On Thu, 8 Jul 1999, Brian Hurt wrote:
Unless I'm missing something, the linux boot sequence uses IBM-PC BIOS functions. I found a number of int 0x13 (diskette services) and int 0x10 (video services) calls in arch/i386/boot/setup.S. Even Grub makes heavy use of BIOS services- a quick grep revealed 23 different BIOS calls, using services 0x13 (disk), 0x10 (video), 0x1a (RTC), and 0x16 (keyboard).
That's not a problem -- these are not mandatory and even now there are some people that run Linux on ia32-based embedded systems. They have no BIOS and the kernel is started from flash memory.
This is actually my leading favorite canidate. The idea is that once the lmsw instruction is executed, the OS takes over. From my 386SX Microprocessor Programmer's Reference Manual (outdated, I know- but I haven't gotten the more advanced documentation yet), the sensitive instructions are: lidt, lgdt, lmsw, mov to/from special control registers, clts, and hlt. The moves to DRx and the hlt instruction should simply be run in priveledged mode. Movs to TRx should be ignored (for now)- I don't think any OS actually uses these. The rest would need to be emulated.
Note that some DOS-based programs execute smsw (that's unprivileged), check for the PE bit and bail out if set.
Not quite. The difference is _when_ do we switch to real mode- 1) just before jumping into the boot loader, 2) the first time the boot loader does something we don't want to deal with emulating, or 3) never (and we just carefully hand over control to the OS when it loads).
There is no need to get out of the protected mode -- that should be the job of a legacy boot loader. BIOS has only to provide a generic call to enter the legacy mode.
So basically you're putting the boot loader into the bios. I'm not 100% comfortable with this idea- it locks you into a boot loader.
Well all workstation or server systems I know of have a boot loader embedded into their firmware. They can choose the device to boot from -- usually the choice is to start from a SCSI or a network device.
Booting from SCSI devices involves reading the first block, looking for a magic number and, if set, reading two values treated as an offset and a number of blocks. Then the device is seeked to the offset and the indicated number of blocks is read into a predefined location of memory. Control is then passed to the program read. The program can actually be an OS kernel or a second-stage boot loader with the latter case being more frequent (unless you are booting from tape).
Booting from network devices involves the usual BOOTP (or sometimes DHCP) and TFTP stuff, which results in a program image being loaded into memory, then execution continues as described above. The image is an OS kernel in this case, usually.
This approach simplifies things as there is no need for a second-stage boot loader sitting in the boot block and loading the third-stage boot loader or the kernel and basically duplicating the actions described above. Besides, there needs to be a network loader put into BIOS in this case, anyway...