Merge commit 'd76af0754db7ddd4c06215d922d213c93178c0af' into elflink
[syslinux/sherbszt.git] / core / localboot.c
blob03ac866de5ed68a9ba4ef167721ded2a678d18b1
1 /* -----------------------------------------------------------------------
3 * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
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.
11 * -----------------------------------------------------------------------
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 <graphics.h>
22 * localboot.c
24 * Boot from a local disk, or invoke INT 18h.
27 #define LOCALBOOT_MSG "Booting from local disk..."
29 #define retry_count 16
31 extern void local_boot16(void);
34 * Boot a specified local disk. AX specifies the BIOS disk number; or
35 * -1 in case we should execute INT 18h ("next device.")
37 void local_boot(int16_t ax)
39 com32sys_t ireg, oreg;
40 int i;
42 syslinux_force_text_mode();
44 writestr(LOCALBOOT_MSG);
45 crlf();
46 cleanup_hardware();
48 if (ax == -1) {
49 /* Hope this does the right thing */
50 __intcall(0x18, &zero_regs, NULL);
52 /* If we returned, oh boy... */
53 kaboom();
57 * Load boot sector from the specified BIOS device and jump to
58 * it.
60 ireg.edx.b[0] = ax & 0xff;
61 ireg.eax.w[0] = 0; /* Reset drive */
62 __intcall(0x13, &ireg, NULL);
64 ireg.eax.w[0] = 0x0201; /* Read one sector */
65 ireg.ecx.w[0] = 0x0001; /* C/H/S = 0/0/1 (first sector) */
66 ireg.ebx.w[0] = OFFS(trackbuf);
67 ireg.es = SEG(trackbuf);
69 for (i = 0; i < retry_count; i++) {
70 __intcall(0x13, &ireg, &oreg);
72 if (!(oreg.eflags.l & EFLAGS_CF))
73 break;
76 if (i == retry_count)
77 kaboom();
79 cli(); /* Abandon hope, ye who enter here */
80 memcpy((void *)0x07C00, trackbuf, 512);
82 ireg.esi.w[0] = OFFS(trackbuf);
83 ireg.edi.w[0] = 0x07C00;
84 ireg.edx.w[0] = ax;
85 call16(local_boot16, &ireg, NULL);
88 void pm_local_boot(com32sys_t *regs)
90 local_boot(regs->eax.w[0]);