Page 1 of 2
Best design strategy for loading > 1mb
Posted: Tue Dec 30, 2008 6:02 pm
by Revelation
While testing my bootloader, I stumbled upon an ugly problem. If the disk I use is 10 mb, the loader works, but if I make it 100 mb it fails, because the FAT is more than 1 mb and I am in real mode. Am I forced to go to protected mode before loading the kernel? If I am in protected mode, I can't read the FAT nor the kernel because I can't use my BIOS function calls anymore.
I don't really know what to do now. If I should go for protected mode, I must first detect which drive I must read from (from the DL register, but I don know how to translate that to a drive in pmode) and what kind of device it is (floppy, hdd, USB) (no idea how to do that either).
What should I do?
Re: Best design strategy for loading > 1mb
Posted: Tue Dec 30, 2008 6:16 pm
by Combuster
assuming it is fat32 (or fat16), and you can just pop a few sectors full of fat into memory when you need it, and overwrite it when you need some other part of the disk. If fragmentation is low it'd probably be faster too.
Saves your bootloader from one form of obesity
Re: Best design strategy for loading > 1mb
Posted: Tue Dec 30, 2008 11:19 pm
by JohnnyTheDon
You can use unreal mode, which will let you use BIOS interrupts and access memory above 1 MB.
From the wiki:
http://wiki.osdev.org/Unreal_Mode
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 1:35 am
by Brendan
Hi,
Revelation wrote:While testing my bootloader, I stumbled upon an ugly problem. If the disk I use is 10 mb, the loader works, but if I make it 100 mb it fails, because the FAT is more than 1 mb and I am in real mode. Am I forced to go to protected mode before loading the kernel? If I am in protected mode, I can't read the FAT nor the kernel because I can't use my BIOS function calls anymore.
Combuster is right - the only thing the should matter is the size (or intended/future size) of the kernel itself, and the size of the FAT file system or disk shouldn't matter (unless the disk is larger than the original BIOS functions can handle, in which case you'd only need to start using the Int 13 Extensions). I'm guessing that if everything works with a 10 MiB disk, but it doesn't work with a 100 MiB disk when everything else is exactly the same, then you've got a bug somewhere or an incompatibility somewhere. For example, maybe your code only supports FAT12 and whatever you use to format the disk uses FAT16 or FAT32 for 100 MiB disks.
Note: AFAIK the maximum partition size supported by FAT12 is about 32 MiB.
Revelation wrote:I don't really know what to do now. If I should go for protected mode, I must first detect which drive I must read from (from the DL register, but I don know how to translate that to a drive in pmode) and what kind of device it is (floppy, hdd, USB) (no idea how to do that either).
If you want to load your kernel above 1 MiB, then you can load some sectors in real mode, switch to protected mode, copy the sectors above 1 MiB then switch back to real mode (or maybe just use unreal mode). Virtual 80x86 mode is another (more complex) option. Building device drivers for every possible storage device into your boot loader is the worst option - don't do that (it'd be funny if you needed to load your boot loader above 1 MiB because there wasn't enough space below 1 MiB for all the device drivers it might need to load the kernel
).
Cheers,
Brendan
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 5:15 am
by djmauretto
Ciao,
I don't know if i'm lucky but usually in all pc tested from me
i manage to copy code above 1MB address without
enter in protected mode or use Unreal mode.
I use simply this:
Code: Select all
XOR AX,AX
MOV DS,AX
MOV ES,AX
MOV ECX,Number of bytes to copy
MOV ESI, Base Address Source ; Physical Address
MOV EDI, Base Address Destination ; Physical Address
CLD
DB 67H
REP MOVSB
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 6:30 am
by Love4Boobies
I'm too lazy to see what DB 67H means right now but that won't work. In both real (even when enabling gate A20) and unreal mode, MOVS will only work with 16-bit registers. Also, you've cleared the segment registers so all you're doing is copying some code from segment 0000 to the same segment.
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 6:39 am
by djmauretto
Love4Boobies wrote:I'm too lazy to see what DB 67H means right now but that won't work. In both real (even when enabling gate A20) and unreal mode, MOVS will only work with 16-bit registers. Also, you've cleared the segment registers so all you're doing is copying some code from segment 0000 to the same segment.
Instead it works fine in all pc that i tested ,
try and let me know.
Db 67h is Address-size override prefix.
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 8:48 am
by Brendan
Hi,
djmauretto wrote:Love4Boobies wrote:I'm too lazy to see what DB 67H means right now but that won't work. In both real (even when enabling gate A20) and unreal mode, MOVS will only work with 16-bit registers. Also, you've cleared the segment registers so all you're doing is copying some code from segment 0000 to the same segment.
Instead it works fine in all pc that i tested ,
try and let me know.
Db 67h is Address-size override prefix.
I guarantee that if ESI or EDI is greater than 0xFFFF you'll get a general protection fault in real mode; unless some code that ran before your code changed the segments limits (which would mean you'd be in unreal mode without knowing it), which isn't impossible - it wouldn't be the first time someone wrote buggy code to switch from protected mode to real mode...
Cheers,
Brendan
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 8:57 am
by Combuster
The full opcode is
rep a32 movsw
or
rep movs word [ds:esi], [es:edi]
the prefix tells it to use 32-bit address generation. In 32-bit mode the default address and operand sizes are 32-bit, you can execute 32-bit instructions by adding those prefixes. The data moved is 16 bits, so you don't need to change that. the offsets are 32-bits so that does needs to be changed - hence the prefix
If that works with large EDI and ESI then you *must* be in unreal mode, as it will GPF in any other case.
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 10:09 am
by djmauretto
ok i know very well Unreal mode,
but until it will work fine I'll use,
please try in your pc,i don't have many pc to try,
but in all pc that i test it's work fine.
If you want i can post a simply floppy image where
i use this,then read well my post,i have told you that maybe i'm
lucky and that perhaps the bios initialization code had used
unreal mode before to me:-)
Note that my code work fine also in MS Virtual PC,
Pentium 4 AMI Bios 2003
Pentium 3 Award Bios 2000
Repeat that i know it's not safe but i'll change only
when pc crash because it is so Cool
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 11:34 am
by djmauretto
Ok I have write a boot program for test of Bios unreal mode
and all the bios of my pc use unreal mode before me
with a descriptor of data segment of 4GB
It's funny that until now i don't found ever a bios
where my system crash
Note also that i use DS and ES ,and both register are loaded with
same exact segment descriptor of 4GB ,while bios have also other data segment descriptor
in GDT ,but they aren't 4GB.
I told you that I'm so Lucky
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 3:58 pm
by Combuster
Tested on Bochs - failed as expected. The bios doesn't leave you in unreal mode.
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 4:52 pm
by djmauretto
You aren't lucky as me
The bios doesn't leave you in unreal mode
My code work in all pc that i tried ,your code don't know i'm sorry
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 5:52 pm
by Combuster
I'm lucky because my code will work on more systems than yours
Re: Best design strategy for loading > 1mb
Posted: Wed Dec 31, 2008 6:58 pm
by djmauretto
Yes i know , you are a good coder ,but i believe that you are much curios about my code that not use unreal mode, i have posted only a fragment
maybe tomorrow i discard everything ,but for now it's works fine