I am writing a loader for my little test OS. My booting sequence is as below:
Bootsector -> Loader -> Kernel...
Bootsector: Only load the loader.
Loader: (a) Load the kernal from a floppy in real mode
(b) Switch to protect mode
Kernel: to-be-continued...
I am wondering:
In what order should I arrange the 2 parts of the Loader's job?
Currently, the loader loads the kernel into memory with the help of real mode BIOS interrupt routine. But real mode limits the size of memory I can use. Though the kernel for now is small enough to fit in, what if it grow quite big in the future?
So I am considering doing step (b) first. But thus I won't be able to use the BIOS interrupt routine, then I have to implement my own floppy driver.
How does Linux handle this problem?
Could someone give me some suggestion to solve this problem elegantly?
Load kernel before or after I enable the Protect Mode?
- smwikipedia
- Member
- Posts: 49
- Joined: Tue Apr 20, 2010 1:11 am
Re: Load kernel before or after I enable the Protect Mode?
If a trainstation is where trains stop, what is a workstation ?
- smwikipedia
- Member
- Posts: 49
- Joined: Tue Apr 20, 2010 1:11 am
Re: Load kernel before or after I enable the Protect Mode?
Thanks gerryg400. How about turning on protect mode first?
Re: Load kernel before or after I enable the Protect Mode?
This would make things much more complicated because you would not have access to the BIOS. Yes, I know that say floppy disk access is "Easy" but the BIOS makes it so you can boot off of anything the BIOS considers bootable(and can be read with int13h) including CD, harddrive, and flash drive.smwikipedia wrote:Thanks gerryg400. How about turning on protect mode first?
Re: Load kernel before or after I enable the Protect Mode?
It's been a long time since I did this. From memory you...
1. enable a20
2. create segment descriptors with a 4G limit
3. switch to protected mode
4. load DS and ES
5. switch back to real mode.
You can now copy data up above the 1MB barrier and at the same time bios interrupts will still work
6. set esi and edi to contain src and dest addresses
7. db 66h
db 67h
movsb
- gerryg400
1. enable a20
2. create segment descriptors with a 4G limit
3. switch to protected mode
4. load DS and ES
5. switch back to real mode.
You can now copy data up above the 1MB barrier and at the same time bios interrupts will still work
6. set esi and edi to contain src and dest addresses
7. db 66h
db 67h
movsb
- gerryg400
If a trainstation is where trains stop, what is a workstation ?
Re: Load kernel before or after I enable the Protect Mode?
earlz,
In fact big real mode is 16bit so the BIOS is accessible
- gerryg400
In fact big real mode is 16bit so the BIOS is accessible
- gerryg400
If a trainstation is where trains stop, what is a workstation ?
-
- Member
- Posts: 127
- Joined: Sat Sep 29, 2007 5:43 pm
- Location: Amsterdam, The Netherlands
Re: Load kernel before or after I enable the Protect Mode?
You generally have two options that are easy. The first option is to, as mentioned before, get into unreal mode, voodoo mode, flat mode, whatever, in which case your data segments will be 32-bit and thus be able to access 4GB, whilst your code segment remains 16-bit, in which case you can simply use the BIOS. The other option is to load a block in real mode, switch to protected mode, move the block and switch back to real mode to load the next block. Doing it purely in protected mode or even long mode is possible, but you'll have to write a x86-16 emulator for the BIOS or use VM86, which is absent in long mode. Another option is not to use the BIOS, but your own drivers to access the drive, this, however, is an advanced method which you will not be able to support everywhere from the start, besides you'll still need the BIOS to load your drivers. So at the end it's probably the best to go with unreal mode, voodoo mode, flat mode, or whatever.smwikipedia wrote:Currently, the loader loads the kernel into memory with the help of real mode BIOS interrupt routine. But real mode limits the size of memory I can use. Though the kernel for now is small enough to fit in, what if it grow quite big in the future?
Linux doesn't really deal with it since Linux is usually loaded by GRUB Legacy or GRUB 2, which aren't part of Linux actually. You could always look at their old boot loader, LILO, though.smwikipedia wrote:How does Linux handle this problem?
gerryg400 wrote:It's been a long time since I did this. From memory you...
1. enable a20
2. create segment descriptors with a 4G limit
3. switch to protected mode
4. load DS and ES
5. switch back to real mode.
You can now copy data up above the 1MB barrier and at the same time bios interrupts will still work
6. set esi and edi to contain src and dest addresses
7. db 66h
db 67h
movsb
- gerryg400
Code: Select all
; enable the A20 here.
; ...
push ds
push es
push fs
push gs
lgdt [GDT32.Pointer]
mov eax, cr0
or eax, 00000000000000000000000000000001b
mov cr0, eax
mov ax, GDT32.Data
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, cr0
and eax, 11111111111111111111111111111110b
mov cr0, eax
pop gs
pop fs
pop es
pop ds
sti
; ...
GDT32:
.Null: equ $ - GDT32
dq 0
.Code: equ $ - GDT32
dw 0xFFFF
dw 0
db 0
db 10011010b
db 11001111b
db 0
.Data: equ $ - GDT32
dw 0xFFFF
dw 0
db 0
db 10010010b
db 11001111b
db 0
.Pointer: dw $ - GDT32 - 1
dd GDT32
Code: Select all
mov esi, 0x00001000
mov edi, 0x00100000
mov ecx, 1024
a32 rep movsd
Regards,
Stephan J.R. van Schaik.