2 * Mach Operating System
3 * Copyright (c) 1992, 1991 Carnegie Mellon University
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
16 * Carnegie Mellon requests users of this software to return to
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
26 * from: Mach, [92/04/03 16:51:14 rvb]
27 * $FreeBSD: src/sys/i386/boot/cdboot/boot.c,v 1.3 1999/08/28 00:43:17 peter Exp $
32 Copyright 1988, 1989, 1990, 1991, 1992
33 by Intel Corporation, Santa Clara, California.
37 Permission to use, copy, modify, and distribute this software and
38 its documentation for any purpose and without fee is hereby
39 granted, provided that the above copyright notice appears in all
40 copies and that both the copyright notice and this permission notice
41 appear in supporting documentation, and that the name of Intel
42 not be used in advertising or publicity pertaining to distribution
43 of the software without specific, written prior permission.
45 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
46 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
47 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
48 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
49 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
50 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
51 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
55 * Extensions for El Torito CD-ROM booting:
57 * Copyright © 1997 Pluto Technologies International, Inc. Boulder CO
58 * Copyright © 1997 interface business GmbH, Dresden.
59 * All rights reserved.
61 * This code was written by Jörg Wunsch, Dresden.
62 * Direct comments to <joerg_wunsch@interface-business.de>.
64 * Redistribution and use in source and binary forms, with or without
65 * modification, are permitted provided that the following conditions
67 * 1. Redistributions of source code must retain the above copyright
68 * notice, this list of conditions and the following disclaimer.
69 * 2. Redistributions in binary form must reproduce the above copyright
70 * notice, this list of conditions and the following disclaimer in the
71 * documentation and/or other materials provided with the distribution.
73 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
74 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
77 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
79 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
81 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
82 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
83 * POSSIBILITY OF SUCH DAMAGE.
86 #include <sys/param.h>
89 #include <sys/reboot.h>
90 #include <machine/bootinfo.h>
91 #ifdef PROBE_KEYBOARD_LOCK
92 #include <machine/cpufunc.h>
95 #define ouraddr (BOOTSEG << 4) /* XXX */
101 * By now, only "cd". How do we learn from the BIOS we've been booted off
102 * an ATAPI CD-ROM? Do the non-{cd,wcd} drivers implement El Torito booting
106 static struct specpacket spkt = { 0x13 };
108 static char namebuf[128];
109 static struct bootinfo bootinfo;
111 static void getbootdev(char *ptr, int *howto);
112 static void loadprog(void);
120 #ifdef PROBE_KEYBOARD
121 if (probe_keyboard()) {
123 loadflags |= RB_SERIAL;
124 printf("\nNo keyboard found.");
128 #ifdef PROBE_KEYBOARD_LOCK
129 if (!(inb(0x64) & 0x10)) {
131 loadflags |= RB_SERIAL;
132 printf("\nKeyboard locked.");
136 #ifdef FORCE_COMCONSOLE
138 loadflags |= RB_SERIAL;
139 printf("\nSerial console forced.");
142 /* Pick up the story from the Bios on geometry of disks */
146 * Do we need to defer this until we can relinguish the
150 for(ret = 0; ret < N_BIOS_GEOM; ret ++)
151 bootinfo.bi_bios_geom[ret] = get_diskinfo(ret + 0x80);
153 bootinfo.bi_basemem = memsize(0);
154 bootinfo.bi_extmem = memsize(1);
155 bootinfo.bi_memsizes_valid = 1;
159 ret = getbootspec(&spkt);
161 printf("Your BIOS int 0x13 extensions seem to be disabled.\n"
162 "It's impossible to boot a CD-ROM without them.\n"
163 "(BIOS int 0x13 fn 0x4b01 yielded error %d)\n",
169 if (devopen(sessionstart) == -1)
170 printf("Warning: cannot open default session.\n"
171 "Maybe your BIOS int 0x13 extensions are disabled?\n"
172 "You need them in order to boot a CD-ROM.\n");
177 * The El Torito specification stinks. Not only this
178 * crappy idea of `emulation booting' (and at least
179 * earlier versions of the AHA-2940 BIOS didn't
180 * implement anything else than floppy emulation
181 * booting), but note also that there's absolutely no
182 * way via the BIOS to obtain the starting LBA of your
183 * session. All you can get ahold of is the LBA of
184 * that funny emulated disk. Since this one just
185 * happens to be a file hidden inside the ISO9660
186 * filesystem, it is located at a varying offset from
187 * the start of the session. We therefore allow to
188 * specify the starting block of the session to use in
189 * the boot string, so the operator can specify the
190 * session to boot from. However, (s)he needs to know
191 * the RBA for the session from the CD-ROM TOC.
193 DPRINTF(("using session at sector %d\n", sessionstart));
196 printf("\n>> FreeBSD CD-ROM BOOT\n"
197 "Usage: [@%d]%s[-abcCdghrsv]\n"
198 "Use ? for file list or press Enter for defaults\n"
202 loadflags &= RB_SERIAL; /* clear all, but leave serial console */
203 loadflags |= RB_CDROM; /* ...and default to CD-ROM root. */
205 getbootdev(namebuf, &loadflags);
207 DPRINTF(("Selected: name=`%s', loadflags=0x%x\n",
212 DPRINTF(("openrd() = %d\n", ret));
216 printf("Can't find %s\n", name);
227 u_int32_t startaddr, addr, bootdev;
232 if (read((void *)&head, sizeof(head)) == -1 ||
234 printf("Invalid format!\n");
239 * We assume that the entry address is the same as the lowest text
240 * address and that the kernel startup code handles relocation by
241 * this address rounded down to a multiple of 16M.
243 startaddr = head.a_entry & 0x00FFFFFF;
245 printf("Booting CD-ROM [@%d]%s @ 0x%x\n", sessionstart, name, addr);
246 if(addr < 0x00100000)
249 * Bail out, instead of risking to damage the BIOS
250 * variables, the loader, or the adapter memory area.
251 * We don't support loading below 1 MB any more.
253 printf("Start address too low\n");
256 printf("text=0x%x ", head.a_text);
258 /* load the text segment */
259 seek(N_TXTOFF(head));
260 if (xread((void *)addr, head.a_text) == -1)
264 /* Pad to a page boundary. */
265 pad = (unsigned)addr & PAGE_MASK;
267 pad = PAGE_SIZE - pad;
268 pbzero((void *)addr, pad);
272 /* load the initialised data after the text */
273 printf("data=0x%x ", head.a_data);
274 if (xread((void *)addr, head.a_data) == -1)
278 /* Skip over the uninitialised data (but clear it) */
279 printf("bss=0x%x ", head.a_bss);
282 * XXX however, we should be checking that we don't load ... into
283 * nonexistent memory. A full symbol table is unlikely to fit on 4MB
286 pbzero((void *)addr, head.a_bss);
289 /* Pad to a page boundary. */
290 pad = (unsigned)addr & PAGE_MASK;
292 pad = PAGE_SIZE - pad;
295 bootinfo.bi_symtab = addr;
297 /* Copy the symbol table size */
298 pcpy(&head.a_syms, (void *)addr, sizeof(head.a_syms));
299 addr += sizeof(head.a_syms);
301 /* Load the symbol table */
302 printf("symbols=[+0x%x+0x%x+0x%x", pad, sizeof(head.a_syms),
304 if (xread((void *)addr, head.a_syms) == -1)
308 /* Load the string table size */
309 if (read((void *)&i, sizeof(int)) == -1)
311 pcpy(&i, (void *)addr, sizeof(int));
315 /* Load the string table */
316 printf("+0x%x+0x%x]\n", sizeof(int), i);
317 if (xread((void *)addr, i) == -1)
321 bootinfo.bi_esymtab = addr;
323 /* XXX what else can we say about a CD-ROM? */
324 bootdev = MAKEBOOTDEV(maj, 0, 0, 0, 0);
326 bootinfo.bi_version = BOOTINFO_VERSION;
327 bootinfo.bi_kernelname = (u_int32_t)(name + ouraddr);
328 bootinfo.bi_nfs_diskless = 0;
329 bootinfo.bi_size = sizeof(bootinfo);
330 printf("total=0x%x entry point=0x%x\n", (int)addr, (int)startaddr);
331 startprog((int)startaddr, loadflags | RB_BOOTINFO, bootdev,
332 (int)&bootinfo + ouraddr);
336 getbootdev(char *ptr, int *howto)
341 * Be paranoid and make doubly sure that the input buffer is empty.
343 if (*howto & RB_SERIAL)
350 while ((c = *ptr) != '\0') {
355 while ((c = *++ptr) != '\0') {
361 *howto |= RB_ASKNAME;
370 if (*howto & RB_SERIAL)
377 *howto |= RB_DFLTROOT;
381 *howto |= RB_VERBOSE;
386 while (*++ptr != '\0') {