I am currently trying to plan out my operating system, and was wondering if someone could clarify something for me:
I am going to write my own bootloader. I know that the bootloader is going to sit on the floppy (no hd support yet) within the first 512 bytes.
Tell me if im right here:
My bootloader will operate at 16-bit real mode.
Now, to get to the second stage (yeah, its a two-stage bootloader), I'm going to make a couple BIOS interrupt calls to read from the floppy disk. With these interrupt calls, im going to read "sectors" from the floppy disk (specificly the sectors that contain the 2nd stage bootloader) and then throw them into memory.
Now heres my question:
The first stage bootloader has to be done entirely in assembly for obvious reasons. In order to read from the floppy disk, do I need to implement a FAT12 driver within that 512 limit? I see no other way of grabbing the second stage bootloader while keeping a legit filesystem.
Also,
I'm a little confused what to do after i've loaded the flat binary contents of the second bootloader into memory. Whats the best way of telling the processor to "jump" over to my newly memory allocated bootloader, and start processing its instructions?
Remember, I'm still in 16-bit real mode... My second stage bootloaders going to work the magic and switch me over to 32-bit protected, A20 Line, etc. What do you guys think?
Bootstrapping - Abstract view
i'm pretty sure, or you could know the exact sectors where the second boot loader and load those into memoryThe first stage bootloader has to be done entirely in assembly for obvious reasons. In order to read from the floppy disk, do I need to implement a FAT12 driver within that 512 limit
i would thinkWhats the best way of telling the processor to "jump" over to my newly memory allocated bootloader, and start processing its instructions?
Code: Select all
jmp memory_addr
Hey,
This might help you with developing a bootloader.
You dont need to implement your own FAT12 driver at all. Just parse the FAT12 filesystem to find your second stage loader, and load it to some location in physical memory.
The link I posted above contains several tutorials on developing a FAT12 bootloader from scratch using NASM. The series itself uses MSVC++ as its primary build tool, however it is better to use a cross compiler for better portability support.
Good luck
This might help you with developing a bootloader.
You dont need to implement your own FAT12 driver at all. Just parse the FAT12 filesystem to find your second stage loader, and load it to some location in physical memory.
The link I posted above contains several tutorials on developing a FAT12 bootloader from scratch using NASM. The series itself uses MSVC++ as its primary build tool, however it is better to use a cross compiler for better portability support.
Good luck
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Re: Bootstrapping - Abstract view
Hi,
If you set the "reserved sectors" field to something like 36 then you'd have 35 more contiguous sectors between the boot sector and the File Allocation Table that you could use for your second stage.
Note: If you're tricky you could have a single binary, where the BIOS loads the first 512 bytes at 0x00007C00 and code in the first 512 bytes loads the rest of the binary starting at 0x00007E00. That way you can end up with something like an 18 KB first stage that's in memory from 0x00007C00 to 0x0000C400, and won't need a second stage. This also saves a little space, as things like strings (e.g. error messages) and other data in the first 512 bytes can be re-used by the rest of the code, and you can put routines that are needed later into the first 512 bytes.
Cheers,
Brendan
The FAT filesystem has a "reserved sectors" field in the BPB (BIOS Parameter Block). This determines then number of sectors that are reserved between the start of the partition/disk and the start of the File Allocation Table, including the boot sector.someprogr wrote:The first stage bootloader has to be done entirely in assembly for obvious reasons. In order to read from the floppy disk, do I need to implement a FAT12 driver within that 512 limit? I see no other way of grabbing the second stage bootloader while keeping a legit filesystem.
If you set the "reserved sectors" field to something like 36 then you'd have 35 more contiguous sectors between the boot sector and the File Allocation Table that you could use for your second stage.
Note: If you're tricky you could have a single binary, where the BIOS loads the first 512 bytes at 0x00007C00 and code in the first 512 bytes loads the rest of the binary starting at 0x00007E00. That way you can end up with something like an 18 KB first stage that's in memory from 0x00007C00 to 0x0000C400, and won't need a second stage. This also saves a little space, as things like strings (e.g. error messages) and other data in the first 512 bytes can be re-used by the rest of the code, and you can put routines that are needed later into the first 512 bytes.
If you need to "jump" to your second stage, then using a "JMP" instruction might work...someprogr wrote:I'm a little confused what to do after i've loaded the flat binary contents of the second bootloader into memory. Whats the best way of telling the processor to "jump" over to my newly memory allocated bootloader, and start processing its instructions?
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.
If you dont want to use JMP, you can always use RET or RETF
But yes, JMP is a more standard method
But yes, JMP is a more standard method
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}