1 /* ----------------------------------------------------------------------- 2 * 3 * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 8 * Boston MA 02110-1301, USA; either version 2 of the License, or 9 * (at your option) any later version; incorporated herein by reference. 10 * 11 * ----------------------------------------------------------------------- 12 */ 13 #include <sys/cpu.h> 14 #include <sys/io.h> 15 #include <string.h> 16 #include <core.h> 17 #include <fs.h> 18 #include <bios.h> 19 #include <syslinux/video.h> 20 21 /* 22 * localboot.c 23 * 24 * Boot from a local disk, or invoke INT 18h. 25 */ 26 27 #define LOCALBOOT_MSG "Booting from local disk..." 28 29 #define retry_count 16 30 31 extern void local_boot16(void); 32 33 /* 34 * Boot a specified local disk. AX specifies the BIOS disk number; or 35 * -1 in case we should execute INT 18h ("next device.") 36 */ 37 __export void local_boot(int16_t ax) 38 { 39 com32sys_t ireg, oreg; 40 int i; 41 42 memset(&ireg, 0, sizeof(ireg)); 43 syslinux_force_text_mode(); 44 45 writestr(LOCALBOOT_MSG); 46 crlf(); 47 cleanup_hardware(); 48 49 if (ax == -1) { 50 /* Hope this does the right thing */ 51 __intcall(0x18, &zero_regs, NULL); 52 53 /* If we returned, oh boy... */ 54 kaboom(); 55 } 56 57 /* 58 * Load boot sector from the specified BIOS device and jump to 59 * it. 60 */ 61 memset(&ireg, 0, sizeof ireg); 62 ireg.edx.b[0] = ax & 0xff; 63 ireg.eax.w[0] = 0; /* Reset drive */ 64 __intcall(0x13, &ireg, NULL); 65 66 memset(&ireg, 0, sizeof(ireg)); 67 ireg.eax.w[0] = 0x0201; /* Read one sector */ 68 ireg.ecx.w[0] = 0x0001; /* C/H/S = 0/0/1 (first sector) */ 69 ireg.ebx.w[0] = OFFS(trackbuf); 70 ireg.es = SEG(trackbuf); 71 72 for (i = 0; i < retry_count; i++) { 73 __intcall(0x13, &ireg, &oreg); 74 75 if (!(oreg.eflags.l & EFLAGS_CF)) 76 break; 77 } 78 79 if (i == retry_count) 80 kaboom(); 81 82 cli(); /* Abandon hope, ye who enter here */ 83 memcpy((void *)0x07C00, trackbuf, 512); 84 85 ireg.esi.w[0] = OFFS(trackbuf); 86 ireg.edi.w[0] = 0x07C00; 87 ireg.edx.w[0] = ax; 88 call16(local_boot16, &ireg, NULL); 89 } 90 91 void pm_local_boot(com32sys_t *regs) 92 { 93 local_boot(regs->eax.w[0]); 94 } 95