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.
loading kernels @ 1MB
Re:loading kernels @ 1MB
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..
Becasue you can access all 4gb, but i don't think that the BIOS can..
Re:loading kernels @ 1MB
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
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
Hi,
This means you can do something like (NASM):
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
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).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.
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 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:loading kernels @ 1MB
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