Hi,
Some notes....
Some BIOSs (typically in old Compaq machines) don't use the "bootable marker" (the 0xAA55 at offset 0x1FE) and instead check to make sure the first instruction is a JMP to determine if the sector is bootable or not.
For floppy disks you should have a
BPB to describe the format the floppy is in. Without this it will work fine, until someone attempts to use a crappy OS (like Windows) to re-format the disk later (and gets an error from Windows about a corrupt disk it can't format). The first instruction would need to be a JMP to jump over the BPB.
You forgot to do a STI after setting up the temporary stack (the "mov sp, 0x7000" near the start). The BIOS probably enables interrupts during "int 0x13" (how else can the BIOS expect to get the "sectors loaded" IRQ from a hard disk controller; or determine if there's been a time-out when the PIT IRQ is disabled?).
DO NOT ask the BIOS to load data above 0x00100000. With A20 still disabled the BIOS will happily trash the IVT and trash its own data (in the BDA), then maybe even trash your GDT then trash your boot code. Even if you enabled A20 before this, it'd still be highly dodgy. Read the data into a buffer below 0x00100000, then copy it above 0x00100000 if you need to. For example, I use a buffer that's large enough for one track, and (in a loop) read a track, switch to protected mode, copy that track above 0x00100000, switch back to real mode, etc (until all data is loaded). This also works when the data being loaded (kernel?) is larger than 64 KiB.
You don't have a way to determine how large the data being loaded (kernel?) is. This is bad design - better to have a header or something that the boot code uses to determine exactly how many sectors it needs to read (so you can increase the size of the kernel without also needing to modify the boot code to suit).
I'd be "more thorough" when attempting to enable A20. First, check if it's already enabled. Then attempt to use
the BIOS function. Only do it manually if you must (because doing it manually is much less reliable).
I don't know why you need to copy the GDT (and can't just use it where it is). I also don't know what the GDT contains or what "GDT_DESC" actually is either.
You forgot to disable interrupts before switching to protected mode. If the BIOS did the right thing and enabled interrupts earlier, then you can expect it to crash as soon as the first IRQ occurs.
As far as I can tell, there's very few error messages. If you fail to read the sectors then it'd be nice if you could tell the user why (e.g. use the BIOS error code to find an error message, saying if there's was a time-out or a read error or whatever). I'd also check to see if the CPU is an 80386 or later before attempting to use 32-bit instructions (e.g. "rep movsd"), and display a "This CPU is too old" error message if it's not. I also put a CRC in the header of all my files and check that the CRC is correct before relying on the file too (e.g. "Kernel CRC check failed. Boot aborted.").
It's very likely that after you fix the problems (and maybe after you decide to setup a video mode while you're still in real mode) that it won't all fit in 512 bytes. The first 512 bytes of the boot loader should probably load the remaining sectors of the boot loader, and those remaining sectors should contain the code to setup video, load the kernel, check the kernel, enable protected mode, etc.
Cheers,
Brendan