Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Assuming your code is a boot loader (and therefore is not an MBR):</p> <ul> <li>Never disable IRQs unless you have to. The BIOS needs them to function correctly, and will enable them inside some BIOS functions anyway (e.g. waiting for a "sectors transferred" IRQ inside disk functions). Because your code is only loading and passing control to more real mode code (e.g. and no switch to protected mode or anything is involved) you have no reason to disable IRQs anywhere in your entire boot loader.</li> <li>For real mode addressing, it's typically cleaner/easier to use 0x0000:0x7C00 rather than 0x07C0:0x0000. You seem to be attempting to mix both (e.g. set segment registers for the former but define BOOTSEG and HDRSEG for the latter).</li> <li>The partition table contains "extended partitions" and not "primary partitions" and your partition table is therefore wrong (and should probably be blank/empty).</li> <li>The boot loader should not assume any specific/hard-coded "starting LBA" (the "starting LBA" for the partition depends on how the end user felt like partitioning their disk when the OS is installed). You need to determine the partition's "starting LBA" from the MBR's primary partition table, which is typically done by hoping that the MBR left DS:SI pointing to your partition's partition table entry.</li> <li>You should not assume that your are booting from "BIOS device 0x80". The MBR should leave DL set to the correct device number, and there should be no reason why your code shouldn't work if (e.g.) the OS is installed on the second hard drive or something else.</li> <li>Your hard-coded "starting LBA to read" (in the DAP) is wrong. For historical reasons there's probably 63 sectors per track and your partition starts on the 64th sector. This means that LBA sector 0x3F is the first sector in the partition (which is your boot loader) and is not the first sector of the kernel. I'm assuming the first sector of the kernel might be LBA sector 0x40 (the second sector of the partition).</li> <li>The "number of sectors" shouldn't be hard-coded either. You'd want to load the beginning of the kernel and examine it, and determine how many sectors to load where from that.</li> <li>Typically 512 bytes (actually more like 446 bytes) is far too little for a decent boot loader. The first 512 bytes of a boot loader should load the rest of the boot loader (with every spare byte left over used to improve error handling - e.g. <code>puts("Read error while trying to load boot loader")</code> rather than just <code>putc('B')</code>). Everything else (loading the pieces of the kernel, setting up a video mode, setting correct values in the "real mode kernel header" fields, etc) should be in the additional sectors and not be in the first sector.</li> </ul> <p>Note that the way the computer boots has been carefully designed such that any MBR can chainload any OS on any partition of any disk; and the MBR may be part of something larger (e.g. a boot manager) that allows multiple OSs to be installed (e.g. where the user can use a pretty menu or something to choose which partition the MBR's code should chain-load). This design allows the user to replace the MBR (or boot manager) with anything else at any time without effecting any installed OS (or causing all of their installed OSs to need fixing). For a simple example, a user should be able to have 12 different partitions that all contain your boot loader and a separate/independent version of Linux, and then install any boot manager (e.g. GRUB, Plop, GAG, MasterBooter, etc) that they want at any time.</p> <p>For why your code hangs, it's not very important given that all of the code needs to be rewritten anyway . If you're curious, I'd strongly recommend running it inside an emulator with a debugger (e.g. Bochs) so that you can examine exactly what has happened (e.g. dump memory at 0x00007E00 to see what it contains, single-step the JMP to see what is being executed, etc).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload