// Starts off in the multiboot context 1 MB high but eventually gets into low memory // and winds up with a bootdevice in eax which is all that boot() wants // This lets the stack pointer remain very high. // If we were to call boot directly from multiboot then the whole multiboot_info // would be on the stack which would possibly be using way too much stack. void multiboot_to_boot(int multiboot_magic, struct multiboot_info *mi_orig) { uint32_t bootdevice = hi_multiboot(multiboot_magic, mi_orig); if(bootdevice != BAD_BOOT_DEVICE) { // boot only returns to do a chain load. for(;;) { // NOTE: boot only uses the last byte (the drive number) common_boot(bootdevice); if(chainbootflag) chainLoad(); else waitThenReload(); } } // Avoid returning to high-memory address which isn't valid in the segment // we are now in. // Calling sleep() ensures the user ought to be able to use Ctrl+Alt+Del // because the BIOS will have interrupts on. for(;;) sleep(10); // NOTE: *IF* we needed to return we'd have to fix up our return address to // be in low memory using the same trick as below. // However, there doesn't seem to be any point in returning to assembly // particularly when the remaining code merely halts the processor. }
// Starts off in the multiboot context 1 MB high but eventually gets into low memory // and winds up with a bootdevice in eax which is all that boot() wants // This lets the stack pointer remain very high. // If we were to call boot directly from multiboot then the whole multiboot_info // would be on the stack which would possibly be using way too much stack. void multiboot_to_boot(int multiboot_magic, struct multiboot_info *mi_orig) { hi_multiboot(multiboot_magic, mi_orig); }