The easiest way of doing things in that respect maybe would be to replicate the most important things into the second stage bootloader.
The sample bootsector tries to set up the A20 line through the keyboard controller, sets up Unreal Mode so now you are able to load the kernel above the 1MB mark (you can now reach 0x100000 and above).
I have attached a bootsector that I think is like the previous ones, and have also attached a second stage bootloader.
This bootloader tries again to enable the A20 line through several methods (keyboard controller, BIOS and Fast A20), but not without first testing if it's already enabled.
It also duplicates the small FAT12 code so now you can add other things to this bootloader before jumping to the kernel.
You must name this second stage bootloader, "LOADER.BIN" and the kernel "KERNEL.BIN" (you can change it in the source code).
Your second stage bootloader is loaded always at 8000h:0000h, so it has about 120KB of memory that you can use to gather things like the memory map, maybe some peripheral detection, some option you could implement to boot from a device other than the floppy (it is an advanced feature which is not implemented at all in this sample) and/or set up a graphics mode -- among many other things.
Your bootloader can use RAM from 80000h to 9FBFFh. If you use memory outside that region, with the current setup of loading it at 8000h:0000h, you will make a mistake.
The KERNEL.BIN file is loaded at 0x100000, and is a 32-bit protected mode image (you can reload your own GDT and other structures from your kernel to replace the ones used by the bootloader).
As you can see, both these bootsector and bootloader can now read from a FAT12 floppy since they duplicate the same FAT12 reading code and the second stage bootloader accesses the FAT12 fields located at 7C00h.
The code still needs a lot of cleanup, mainly to make the FAT12 code more ordered (it is optimized to be extremely compact, sacrificing simplicity) but it's a good start for being able to have a first and second stage bootloaders, both capable of reading the files from a standard FAT12 floppy that can be read and used under Windows.
If you wonder what's good about that, it is that as you know, 512 bytes of boot code aren't enough, so the second stage bootloader allows you to take advantage of BIOS calls, which will allow you to get many important pieces of information about your PC. If you made a 512-byte bootsector that jumped directly to a 32-bit kernel, you couldn't use the BIOS (not without heavy emulation on your own) and that would get your kernel rather lost in an unknown hardware environment.
So the configuration of memory for these programs is like this:
Code: Select all
7C00h -- FAT12 bootsector
8000h -- FAT tables read from disk
40000h -- temporary sector-at-once buffer
80000h -- second stage bootloader
100000h -- kernel image
The DL register will be set by the bootsector to the original drive number we were booted from just before jumping to the second stage.
You need to install the bootsector to the floppy, and copy to it (preferably empty) the files LOADER.BIN and KERNEL.BIN.
The KERNEL.BIN file included is the previous one, unchanged.
This bootsector program in general is very fragile because each instruction depends greatly on the results of the previous one(s) to reduce as much as possible the waste of space and try to do an "extreme" optimization, so it isn't easy to modify it arbitrarily without a lot of care.
Maybe I should suggest that you should first fully understand FAT filesystems and all of the code presented until now, which should now be able to pass control to 2nd stage and from there to a 32-bit kernel. Otherwise, there could be a chance of like 90% that you will make many failed kernel attempts which will span a lot of time.
Using an attempt of a kernel is a inconvenient choice if you still need to find out how the hardware works, it's a very deserted environment when you have entered Protected Mode and don't have yet available any way to use the 16-bit Real Mode code of the BIOS or useable drivers. When something about your low level design considerations don't fit with the hardware setup, it will cause bugs that will require you to start from scratch (or almost).