Page 1 of 1

loading kernels @ 1MB

Posted: Mon Mar 27, 2006 2:08 pm
by Alex Buell
Consider that a kernel might be more than 1MB in size and have to be loaded above 1MB. What's the best way to load a kernel from disk into that location? I know from reading the docs, that one has to enable A20 and enter unreal mode before doing that. At that point, can I still use BIOS services to load the kernel from disk and copy the buffer into memory above 1MB?

Thanks.

Re:loading kernels @ 1MB

Posted: Mon Mar 27, 2006 2:16 pm
by bubach
IIRC: You load it (or parts of it at a time) to some buffer below 0xffff:0xffff and then copy the data to somewhere above that address..
Becasue you can access all 4gb, but i don't think that the BIOS can..

Re:loading kernels @ 1MB

Posted: Wed Mar 29, 2006 5:57 am
by Rob
Since "unreal" mode is not protected mode you can still call BIOS functions etc. You cannot however point the BIOS to some buffer above 1 MB.

So basically what you do is this:

1. switch to unreal mode

2. have the BIOS fill up a buffer with data (probably 4 - 64 KB in size)

3. copy that buffer to memory above 1 MB, keep in mind that you cannot use MOVSB/W/D or LOD/STOS for this, you need to do something like mov eax, [esi] mov [edi], eax etc.

4. repeat from 2 as long as there is data read / in the buffer

Re:loading kernels @ 1MB

Posted: Wed Mar 29, 2006 6:57 am
by Brendan
Hi,
Rob wrote:3. copy that buffer to memory above 1 MB, keep in mind that you cannot use MOVSB/W/D or LOD/STOS for this, you need to do something like mov eax, [esi] mov [edi], eax etc.
You can use string instructions like "rep movsb/w/d", you just need to use an address size prefix (and make sure the correct segments are setup (remember that ES can't be overriden with a segment overide prefix for STOS and MOVS).

This means you can do something like (NASM):

Code: Select all

    mov esi,0x12345678
    mov edi,0x9ABCDEF0
    mov ecx,0x00020000
    cld
    a32 es rep movsd
Without the "a32" address size overide, the CPU will use CX, SI and DI instead of ECX, ESI and EDI. The ES segment override makes it use "ES:ESI" and "ES:EDI", so that only one segment needs to have a modified limit.

Without modifying the segment register/s limit, the same thing would cause a general protection fault in real mode (unless ESI and EDI remain below the default 64 KB segment limit).


Cheers,

Brendan

Re:loading kernels @ 1MB

Posted: Wed Mar 29, 2006 7:07 am
by Rob
Interesting, I did not know that. Thanks! I'll have to see if and how MASM supports that. Perhaps I can simply use dword ptr or something. Otherwise there's always db 67h I guess ;)