loading kernels @ 1MB

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Alex Buell

loading kernels @ 1MB

Post 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.
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:loading kernels @ 1MB

Post 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..
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
Rob

Re:loading kernels @ 1MB

Post 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
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:loading kernels @ 1MB

Post 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
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.
Rob

Re:loading kernels @ 1MB

Post 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 ;)
Post Reply