.gear/rules | 2 + .../tags/efd88eb4c9a72d6398a0f0013f96f6c54f77e907 | 6 + .gear/tags/list | 1 + .gitignore | 2 + Makefile | 33 + boot0.spec | 56 ++ boot0/.svn/all-wcprops | 23 - boot0/.svn/entries | 130 ---- boot0/.svn/prop-base/Makefile.svn-base | 5 - boot0/.svn/prop-base/boot0.S.svn-base | 5 - boot0/.svn/prop-base/boot0ext.S.svn-base | 5 - boot0/.svn/text-base/Makefile.svn-base | 84 --- boot0/.svn/text-base/boot0.S.svn-base | 682 -------------------- boot0/.svn/text-base/boot0ext.S.svn-base | 499 -------------- boot0/GNUMakefile | 46 ++ boot0/boot0.S | 25 + boot0cfg/.svn/all-wcprops | 23 - boot0cfg/.svn/entries | 130 ---- boot0cfg/.svn/prop-base/Makefile.svn-base | 5 - boot0cfg/.svn/prop-base/boot0cfg.8.svn-base | 5 - boot0cfg/.svn/prop-base/boot0cfg.c.svn-base | 5 - boot0cfg/.svn/text-base/Makefile.svn-base | 11 - boot0cfg/.svn/text-base/boot0cfg.8.svn-base | 205 ------ boot0cfg/.svn/text-base/boot0cfg.c.svn-base | 605 ----------------- boot0cfg/GNUMakefile | 6 + boot0cfg/boot0cfg.8 | 26 +- boot0cfg/boot0cfg.c | 44 +- 27 files changed, 235 insertions(+), 2434 deletions(-) diff --git a/.gear/rules b/.gear/rules index e69de29..bf6725c 100644 --- a/.gear/rules +++ b/.gear/rules @@ -0,0 +1,2 @@ +diff: rev@version@:. . +tar: rev@version@:. base=@name@-@version@ name=@name@-@version@ diff --git a/.gear/tags/efd88eb4c9a72d6398a0f0013f96f6c54f77e907 b/.gear/tags/efd88eb4c9a72d6398a0f0013f96f6c54f77e907 new file mode 100644 index 0000000..db09026 --- /dev/null +++ b/.gear/tags/efd88eb4c9a72d6398a0f0013f96f6c54f77e907 @@ -0,0 +1,6 @@ +object efe3820cf0cabfc16cd24df076559d5eb7f5f892 +type commit +tag rev236712 +tagger George V. Kouryachy (Fr. Br. George) 1339065114 +0400 + +Update to 236712 diff --git a/.gear/tags/list b/.gear/tags/list new file mode 100644 index 0000000..eeecdd9 --- /dev/null +++ b/.gear/tags/list @@ -0,0 +1 @@ +efd88eb4c9a72d6398a0f0013f96f6c54f77e907 rev236712 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34ea40f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*/.svn +*/.svn/* diff --git a/Makefile b/Makefile index 4c19fd5..8039af6 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,36 @@ +prefix=/usr +exec_prefix=/usr +bindir=/usr/bin +sbindir=/usr/sbin +sysconfdir=/etc +datadir=/usr/share +includedir=/usr/include +libdir=/usr/lib +libexecdir=/usr/lib +localstatedir=/var/lib +sharedstatedir=/usr/com +mandir=/usr/share/man +infodir=/usr/share/info + +all: + $(MAKE) -C boot0 -f GNUMakefile CFLAGS=-DPXE clean boot0 + mv boot0/boot0 boot0/boot0pxe + $(MAKE) -C boot0 -f GNUMakefile CFLAGS=-DSIO clean boot0 + mv boot0/boot0 boot0/boot0sio + $(MAKE) -C boot0 -f GNUMakefile CFLAGS=-DLINUX_VERSION clean boot0 + mv boot0/boot0 boot0/boot0lin + $(MAKE) -C boot0 -f GNUMakefile clean all + $(MAKE) -C boot0cfg -f GNUMakefile all + +install: + for t in "" lin pxe sio ext; do $(INSTALL) -D boot0/boot0$$t $(datadir)/boot0/boot0$$t; done + $(INSTALL) -sD boot0cfg/boot0cfg $(sbindir)/boot0cfg + $(INSTALL) -D boot0cfg/boot0cfg.8 $(mandir)/man8/boot0cfg.8 + +clean: + $(MAKE) -C boot0 -f GNUMakefile distclean + $(MAKE) -C boot0cfg -f GNUMakefile clean + update: svn update boot0 svn update boot0cfg diff --git a/boot0.spec b/boot0.spec new file mode 100644 index 0000000..3da45f5 --- /dev/null +++ b/boot0.spec @@ -0,0 +1,56 @@ +Name: boot0 +Version: 236712 +Release: alt1 +Group: System/Kernel and hardware +Summary: 1st-level bootloader used in FreeBSD distribution +License: BSD +# see Makefile for real SVN source +Source: %name-%version.tar +Url: http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/boot/i386/boot0/ +Patch: %name-%version-%release.patch + + +%description +The boot manager scans the partition table and prints the menu on the +screen so the user can select what disk and what slice to boot. By +pressing an appropriate key, boot0 performs the following actions: + * modifies the bootable flag for the selected partition to make it + bootable, and clears the previous + * saves itself to disk to remember what partition (slice) has been + selected so to use it as the default on the next boot + * loads the first sector of the selected partition (slice) into + memory and jumps there + +%prep +%setup +%patch -p1 + +%build +%make + +%install +%makeinstall + +%files +%_sbindir/* +%_man8dir/* +%dir %_datadir/%name +%_datadir/%name/* + +%changelog +* Thu Jun 07 2012 Fr. Br. George 236712-alt1 +- Version update + +* Thu Jun 07 2012 Fr. Br. George 196074-alt4 +- Fix new binutils build + +* Sat Aug 08 2009 Fr. Br. George 196074-alt3 +- Accidential clean(*argv) removed +- Linux version (LBA ext, LVM, SWAP and RAID suport) + +* Thu Aug 06 2009 Fr. Br. George 196074-alt2 +- Add boot0ext, 1024-byte boot manager + +* Thu Aug 06 2009 Fr. Br. George 196074-alt1 +- Initial build from scratch + diff --git a/boot0/.svn/all-wcprops b/boot0/.svn/all-wcprops deleted file mode 100644 index 4c60933..0000000 --- a/boot0/.svn/all-wcprops +++ /dev/null @@ -1,23 +0,0 @@ -K 25 -svn:wc:ra_dav:version-url -V 46 -/base/!svn/ver/232263/head/sys/boot/i386/boot0 -END -boot0.S -K 25 -svn:wc:ra_dav:version-url -V 54 -/base/!svn/ver/228738/head/sys/boot/i386/boot0/boot0.S -END -boot0ext.S -K 25 -svn:wc:ra_dav:version-url -V 57 -/base/!svn/ver/128741/head/sys/boot/i386/boot0/boot0ext.S -END -Makefile -K 25 -svn:wc:ra_dav:version-url -V 55 -/base/!svn/ver/232263/head/sys/boot/i386/boot0/Makefile -END diff --git a/boot0/.svn/entries b/boot0/.svn/entries deleted file mode 100644 index babb517..0000000 --- a/boot0/.svn/entries +++ /dev/null @@ -1,130 +0,0 @@ -10 - -dir -236712 -http://svn.freebsd.org/base/head/sys/boot/i386/boot0 -http://svn.freebsd.org/base - - - -2012-02-28T18:30:18.243147Z -232263 -dim - - - - - - - - - - - - - - -ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f - -boot0.S -file - - - - -2012-06-07T10:31:51.000000Z -0a1e57bab2dff7ff922f2bffab3a6ad7 -2011-12-20T15:19:29.116458Z -228738 -jhb -has-props - - - - - - - - - - - - - - - - - - - - -21375 - -boot0ext.S -file - - - - -2009-08-05T19:50:07.000000Z -952078ca8d849e8584fe2cf4e5d29ffd -2004-04-29T18:58:38.000000Z -128741 -ru -has-props - - - - - - - - - - - - - - - - - - - - -14755 - -Makefile -file - - - - -2012-06-07T10:31:51.000000Z -056209f0c7ecfb4225db0d32118aa150 -2012-02-28T18:30:18.243147Z -232263 -dim -has-props - - - - - - - - - - - - - - - - - - - - -2784 - diff --git a/boot0/.svn/prop-base/Makefile.svn-base b/boot0/.svn/prop-base/Makefile.svn-base deleted file mode 100644 index 205b913..0000000 --- a/boot0/.svn/prop-base/Makefile.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 12 -svn:keywords -V 10 -FreeBSD=%H -END diff --git a/boot0/.svn/prop-base/boot0.S.svn-base b/boot0/.svn/prop-base/boot0.S.svn-base deleted file mode 100644 index 205b913..0000000 --- a/boot0/.svn/prop-base/boot0.S.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 12 -svn:keywords -V 10 -FreeBSD=%H -END diff --git a/boot0/.svn/prop-base/boot0ext.S.svn-base b/boot0/.svn/prop-base/boot0ext.S.svn-base deleted file mode 100644 index 205b913..0000000 --- a/boot0/.svn/prop-base/boot0ext.S.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 12 -svn:keywords -V 10 -FreeBSD=%H -END diff --git a/boot0/.svn/text-base/Makefile.svn-base b/boot0/.svn/text-base/Makefile.svn-base deleted file mode 100644 index 38281a1..0000000 --- a/boot0/.svn/text-base/Makefile.svn-base +++ /dev/null @@ -1,84 +0,0 @@ -# $FreeBSD$ - -PROG?= boot0 -STRIP= -BINMODE=${NOBINMODE} -NO_MAN= -SRCS= ${PROG}.S - -# Additional options that you can specify with make OPTS="..." -# (these only apply to boot0.S) -# -# -DVOLUME_SERIAL support volume serial number (NT, XP, Vista) -# -DSIO do I/O using COM1: -# -DPXE fallback to INT18/PXE with F6 -# -DCHECK_DRIVE enable checking drive number -# -DONLY_F_KEYS accept only Fx keys in console -# -DTEST print drive number on entry -# -OPTS ?= -DVOLUME_SERIAL -DPXE -CFLAGS += ${OPTS} - -# Flags used in the boot0.S code: -# 0x0f all valid partitions enabled. -# 0x80 'packet', use BIOS EDD (LBA) extensions instead of CHS -# to read from disk. boot0.S does not check that the extensions -# are supported, but all modern BIOSes should have them. -# 0x40 'noupdate', disable writing boot0 back to disk so that -# the current selection is not preserved across reboots. -# 0x20 'setdrv', override the drive number supplied by the bios -# with the one in the boot sector. - -# Default boot flags: -BOOT_BOOT0_FLAGS?= 0x8f - -# The number of timer ticks to wait for a keypress before assuming the default -# selection. Since there are 18.2 ticks per second, the default value of -# 0xb6 (182d) corresponds to 10 seconds. -BOOT_BOOT0_TICKS?= 0xb6 - -# The base address that we the boot0 code to to run it. Don't change this -# unless you are glutton for punishment. -BOOT_BOOT0_ORG?= 0x600 - -# Comm settings for boot0sio. -# Bit(s) Description -# 7-5 data rate (110,150,300,600,1200,2400,4800,9600 bps) -# 4-3 parity (00 or 10 = none, 01 = odd, 11 = even) -# 2 stop bits (set = 2, clear = 1) -# 1-0 data bits (00 = 5, 01 = 6, 10 = 7, 11 = 8) -.if !defined(BOOT_BOOT0_COMCONSOLE_SPEED) -BOOT_COMCONSOLE_SPEED?= 9600 -.if ${BOOT_COMCONSOLE_SPEED} == 9600 -BOOT_BOOT0_COMCONSOLE_SPEED= "7 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 4800 -BOOT_BOOT0_COMCONSOLE_SPEED= "6 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 2400 -BOOT_BOOT0_COMCONSOLE_SPEED= "5 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 1200 -BOOT_BOOT0_COMCONSOLE_SPEED= "4 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 600 -BOOT_BOOT0_COMCONSOLE_SPEED= "3 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 300 -BOOT_BOOT0_COMCONSOLE_SPEED= "2 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 150 -BOOT_BOOT0_COMCONSOLE_SPEED= "1 << 5 + 3" -.elif ${BOOT_COMCONSOLE_SPEED} == 110 -BOOT_BOOT0_COMCONSOLE_SPEED= "0 << 5 + 3" -.else -BOOT_BOOT0_COMCONSOLE_SPEED= "7 << 5 + 3" -.endif -.endif - -CFLAGS+=-DFLAGS=${BOOT_BOOT0_FLAGS} \ - -DTICKS=${BOOT_BOOT0_TICKS} \ - -DCOMSPEED=${BOOT_BOOT0_COMCONSOLE_SPEED} - -LDFLAGS=-e start -Ttext ${BOOT_BOOT0_ORG} -Wl,-N,-S,--oformat,binary - -.include - -# XXX: clang integrated-as doesn't grok .codeNN directives yet -CFLAGS.boot0.S= ${CLANG_NO_IAS} -CFLAGS.boot0ext.S= ${CLANG_NO_IAS} -CFLAGS+= ${CFLAGS.${.IMPSRC:T}} diff --git a/boot0/.svn/text-base/boot0.S.svn-base b/boot0/.svn/text-base/boot0.S.svn-base deleted file mode 100644 index 798ee97..0000000 --- a/boot0/.svn/text-base/boot0.S.svn-base +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Copyright (c) 2008 Luigi Rizzo (mostly documentation) - * Copyright (c) 2002 Bruce M. Simpson - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - * - * $FreeBSD$ - */ - -/* build options: */ -#ifdef SIO /* use serial console on COM1. */ -#endif - -#ifdef PXE /* enable PXE/INT18 booting with F6 */ -#define SAVE_MORE_MEMORY -#endif - -#ifdef CHECK_DRIVE /* make sure we boot from a HD. */ -#endif - -#ifdef ONLY_F_KEYS /* Only F1..F6, no digits on console */ -#endif - -#ifdef VOLUME_SERIAL /* support Volume serial number */ -#define B0_BASE 0x1ae /* move the internal data area */ -#define SAVE_MEMORY -#else -#define B0_BASE 0x1b2 -#endif - -#ifdef TEST /* enable some test code */ -#define SAVE_MEMORY -#define SAVE_MORE_MEMORY -#endif - -/* - * Note - this code uses many tricks to save space and fit in one sector. - * This includes using side effects of certain instructions, reusing - * register values from previous operations, etc. - * Be extremely careful when changing the code, even for simple things. - */ - -/* - * BOOT BLOCK STRUCTURE - * - * This code implements a Master Boot Record (MBR) for an Intel/PC disk. - * It is 512 bytes long and it is normally loaded by the BIOS (or another - * bootloader) at 0:0x7c00. This code depends on %cs:%ip being 0:0x7c00 - * - * The initial chunk of instructions is used as a signature by external - * tools (e.g. boot0cfg) which can manipulate the block itself. - * - * The area at offset 0x1b2 contains a magic string ('Drive '), also - * used as a signature to detect the block, and some variables that can - * be updated by boot0cfg (and optionally written back to the disk). - * These variables control the operation of the bootloader itself, - * e.g. which partitions to enable, the timeout, the use of LBA - * (called 'packet') or CHS mode, whether to force a drive number, - * and whether to write back the user's selection back to disk. - * - * As in every Master Boot Record, the partition table is at 0x1be, - * made of four 16-byte entries each containing: - * - * OFF SIZE DESCRIPTION - * 0 1 status (0x80: bootable, 0: non bootable) - * 1 3 start sector CHS - * 8:head, 6:sector, 2:cyl bit 9..8, 8:cyl bit 7..0 - * 4 1 partition type - * 5 3 end sector CHS - * 8 4 LBA of first sector - * 12 4 partition size in sectors - * - * and followed by the two bytes 0x55, 0xAA (MBR signature). - */ - - -/* - * BOOT BLOCK OPERATION - * - * On entry, the registers contain the following values: - * - * %cs:%ip 0:0x7c00 - * %dl drive number (0x80, 0x81, ... ) - * %si pointer to the partition table from which we were loaded. - * Some boot code (e.g. syslinux) use this info to relocate - * themselves, so we want to pass a valid one to the next stage. - * NOTE: the use of %si is not a standard. - * - * This boot block first relocates itself at a different address (0:0x600), - * to free the space at 0:0x7c00 for the next stage boot block. - * - * It then initializes some memory at 0:0x800 and above (pointed by %bp) - * to store the original drive number (%dl) passed to us, and to construct a - * fake partition entry. The latter is used by the disk I/O routine and, - * in some cases, passed in %si to the next stage boot code. - * - * The variables at 0x1b2 are accessed as negative offsets from %bp. - * - * After the relocation, the code scans the partition table printing - * out enabled partition or disks, and waits for user input. - * - * When a partition is selected, or a timeout expires, the currently - * selected partition is used to load the next stage boot code, - * %dl and %si are set appropriately as when we were called, and - * control is transferred to the newly loaded code at 0:0x7c00. - */ - -/* - * CONSTANTS - * - * NHRDRV is the address in segment 0 where the BIOS writes the - * total number of hard disks in the system. - * LOAD is the original load address and cannot be changed. - * ORIGIN is the relocation address. If you change it, you also need - * to change the value passed to the linker in the Makefile - * PRT_OFF is the location of the partition table (from the MBR standard). - * B0_OFF is the location of the data area, known to boot0cfg so - * it cannot be changed. Computed as a negative offset from 0x200 - * MAGIC is the signature of a boot block. - */ - - .set NHRDRV,0x475 # Number of hard drives - .set ORIGIN,0x600 # Execution address - .set LOAD,0x7c00 # Load address - - .set PRT_OFF,0x1be # Partition table - .set B0_OFF,(B0_BASE-0x200) # Offset of boot0 data - - .set MAGIC,0xaa55 # Magic: bootable - - .set KEY_ENTER,0x1c # Enter key scan code - .set KEY_F1,0x3b # F1 key scan code - .set KEY_1,0x02 # #1 key scan code - - .set ASCII_BEL,'#' # ASCII code for - .set ASCII_CR,0x0D # ASCII code for - -/* - * Offsets of variables in the block at B0_OFF, and in the volatile - * data area, computed as displacement from %bp. - * We need to define them as constant as the assembler cannot - * compute them in its single pass. - */ - .set _NXTDRV, B0_OFF+6 # Next drive - .set _OPT, B0_OFF+7 # Default option - .set _SETDRV, B0_OFF+8 # Drive to force - .set _FLAGS, B0_OFF+9 # Flags - .set SETDRV, 0x20 # the 'setdrv' flag - .set NOUPDATE, 0x40 # the 'noupdate' flag - .set USEPACKET, 0x80 # the 'packet' flag - - /* ticks is at a fixed position */ - .set _TICKS, (PRT_OFF - 0x200 - 2) # Timeout ticks - .set _MNUOPT, 0x10 # Saved menu entries - - .set TLEN, (desc_ofs - bootable_ids) # size of bootable ids - .globl start # Entry point - .code16 # This runs in real mode - -/* - * MAIN ENTRY POINT - * Initialise segments and registers to known values. - * segments start at 0. - * The stack is immediately below the address we were loaded to. - * NOTE: the initial section of the code (up to movw $LOAD,%sp) - * is used by boot0cfg, together with the 'Drive ' string and - * the 0x55, 0xaa at the end, as an identifier for version 1.0 - * of the boot code. Do not change it. - * In version 1.0 the parameter table (_NEXTDRV etc) is at 0x1b9 - */ -start: cld # String ops inc - xorw %ax,%ax # Zero - movw %ax,%es # Address - movw %ax,%ds # data - movw %ax,%ss # Set up - movw $LOAD,%sp # stack - - /* - * Copy this code to the address it was linked for, 0x600 by default. - */ - movw %sp,%si # Source - movw $start,%di # Destination - movw $0x100,%cx # Word count - rep # Relocate - movsw # code - /* - * After the code, (i.e. at %di+0, 0x800) create a partition entry, - * initialized to LBA 0 / CHS 0:0:1. - * Set %bp to point to the partition and also, with negative offsets, - * to the variables embedded in the bootblock (nextdrv and so on). - */ - movw %di,%bp # Address variables - movb $0x8,%cl # Words to clear - rep # Zero - stosw # them - incb -0xe(%di) # Set the S field to 1 - - jmp main-LOAD+ORIGIN # Jump to relocated code - -main: -#if defined(SIO) && COMSPEED != 0 - /* - * Init the serial port. bioscom preserves the driver number in DX. - */ - movw $COMSPEED,%ax # defined by Makefile - callw bioscom -#endif - - /* - * If the 'setdrv' flag is set in the boot sector, use the drive - * number from the boot sector at 'setdrv_num'. - * Optionally, do the same if the BIOS gives us an invalid number - * (note though that the override prevents booting from a floppy - * or a ZIP/flash drive in floppy emulation). - * The test costs 4 bytes of code so it is disabled by default. - */ - testb $SETDRV,_FLAGS(%bp) # Set drive number? -#ifndef CHECK_DRIVE /* disable drive checks */ - jz save_curdrive # no, use the default -#else - jnz disable_update # Yes - testb %dl,%dl # Drive number valid? - js save_curdrive # Possibly (0x80 set) -#endif - /* - * Disable updates if the drive number is forced. - */ -disable_update: orb $NOUPDATE,_FLAGS(%bp) # Disable updates - movb _SETDRV(%bp),%dl # Use stored drive number - - /* - * Whatever drive we decided to use, store it at (%bp). The byte - * is normally used for the state of the partition (0x80 or 0x00), - * but we abuse it as it is very convenient to access at offset 0. - * The value is read back after 'check_selection' - */ -save_curdrive: movb %dl, (%bp) # Save drive number - pushw %dx # Also in the stack -#ifdef TEST /* test code, print internal bios drive */ - rolb $1, %dl - movw $drive, %si - call putkey -#endif - callw putn # Print a newline - /* - * Start out with a pointer to the 4th byte of the first table entry - * so that after 4 iterations it's beyond the end of the sector - * and beyond a 256 byte boundary. We use the latter trick to check for - * end of the loop without using an extra register (see start.5). - */ - movw $(partbl+0x4),%bx # Partition table (+4) - xorw %dx,%dx # Item number - - /* - * Loop around on the partition table, printing values until we - * pass a 256 byte boundary. - */ -read_entry: movb %ch,-0x4(%bx) # Zero active flag (ch == 0) - btw %dx,_FLAGS(%bp) # Entry enabled? - jnc next_entry # No - movb (%bx),%al # Load type - test %al, %al # skip empty partition - jz next_entry - /* - * Scan the table of bootable ids, which starts at %di and has - * length TLEN. On a match, %di points to the element following the - * match; the corresponding offset to the description is $(TLEN-1) - * bytes ahead. We use a count of TLEN+1 so if we don't find a match - * within the first TLEN entries, we hit the 'unknown' entry. - */ - movw $bootable_ids,%di # Lookup tables - movb $(TLEN+1),%cl # Number of entries - repne # Locate - scasb # type - /* - * Get the matching element in the next array. - * The byte at $(TLEN-1)(%di) contains the offset of the description - * string from %di, so we add the number and print the string. - */ - addw $(TLEN-1), %di # Adjust - movb (%di),%cl # Partition - addw %cx,%di # description - callw putx # Display it - -next_entry: incw %dx # Next item - addb $0x10,%bl # Next entry - jnc read_entry # Till done - /* - * We are past a 256 byte boundary: the partition table is finished. - * Add one to the drive number and check it is valid. - * Note that if we started from a floppy, %dl was 0 so we still - * get an entry for the next drive, which is the first Hard Disk. - */ - popw %ax # Drive number - subb $0x80-0x1,%al # Does next - cmpb NHRDRV,%al # drive exist? (from BIOS?) - jb print_drive # Yes - /* - * If this is the only drive, don't display it as an option. - */ - decw %ax # Already drive 0? - jz print_prompt # Yes - /* - * If it was illegal or we cycled through them, go back to drive 0. - */ - xorb %al,%al # Drive 0 - /* - * Whatever drive we selected, make it an ascii digit and save it - * back to the "nxtdrv" location in case we want to save it to disk. - * This digit is also part of the printed drive string, so add 0x80 - * to indicate end of string. - */ -print_drive: addb $'0'|0x80,%al # Save next - movb %al,_NXTDRV(%bp) # drive number - movw $drive,%di # Display - callw putx # item - /* - * Menu is complete, display a prompt followed by current selection. - * 'decw %si' makes the register point to the space after 'Boot: ' - * so we do not see an extra CRLF on the screen. - */ -print_prompt: movw $prompt,%si # Display - callw putstr # prompt - movb _OPT(%bp),%dl # Display - decw %si # default - callw putkey # key - jmp start_input # Skip beep - -/* - * Here we have the code waiting for user input or a timeout. - */ -beep: movb $ASCII_BEL,%al # Input error, print or beep - callw putchr - -start_input: - /* - * Actual Start of input loop. Take note of time - */ - xorb %ah,%ah # BIOS: Get - int $0x1a # system time - movw %dx,%di # Ticks when - addw _TICKS(%bp),%di # timeout -read_key: - /* - * Busy loop, looking for keystrokes but keeping one eye on the time. - */ -#ifndef SIO - movb $0x1,%ah # BIOS: Check - int $0x16 # for keypress -#else /* SIO */ - movb $0x03,%ah # BIOS: Read COM - call bioscom - testb $0x01,%ah # Check line status - # (bit 1 indicates input) -#endif /* SIO */ - jnz got_key # Have input - xorb %ah,%ah # BIOS: int 0x1a, 00 - int $0x1a # get system time - cmpw %di,%dx # Timeout? - jb read_key # No - - /* - * Timed out or default selection - */ -use_default: movb _OPT(%bp),%al # Load default - orb $NOUPDATE,_FLAGS(%bp) # Disable updates - jmp check_selection # Join common code - - /* - * Get the keystroke. - * ENTER or CR confirm the current selection (same as a timeout). - * Otherwise convert F1..F6 (or '1'..'6') to 0..5 and check if the - * selection is valid. - * The SIO code uses ascii chars, the console code uses scancodes. - */ -got_key: -#ifndef SIO - xorb %ah,%ah # BIOS: int 0x16, 00 - int $0x16 # get keypress - movb %ah,%al # move scan code to %al - cmpb $KEY_ENTER,%al -#else - movb $0x02,%ah # BIOS: Receive - call bioscom - cmpb $ASCII_CR,%al -#endif - je use_default # enter -> default - /* - * Check if the key is acceptable, and loop back if not. - * The console (non-SIO) code looks at scancodes and accepts - * both F1..F6 and 1..6 (the latter costs 6 bytes of code), - * relying on the fact that F1..F6 have higher scancodes than 1..6 - * The SIO code only takes 1..6 - */ -#ifdef SIO /* SIO mode, use ascii values */ - subb $'1',%al # Subtract '1' ascii code -#else /* console mode -- use scancodes */ - subb $KEY_F1,%al /* Subtract F1 scan code */ -#if !defined(ONLY_F_KEYS) - cmpb $0x5,%al # F1..F6 - jna 3f # Yes - subb $(KEY_1 - KEY_F1),%al # Less #1 scan code - 3: -#endif /* ONLY_F_KEYS */ -#endif /* SIO */ -check_selection: - cmpb $0x5,%al # F1..F6 or 1..6 ? -#ifdef PXE /* enable PXE/INT18 using F6 */ - jne 1f; - int $0x18 # found F6, try INT18 - 1: -#endif /* PXE */ - jae beep # Not in F1..F5, beep - - /* - * We have a selection. If it's a bad selection go back to complain. - * The bits in MNUOPT were set when the options were printed. - * Anything not printed is not an option. - */ - cbtw # Extend (%ah=0 used later) - btw %ax,_MNUOPT(%bp) # Option enabled? - jnc beep # No - /* - * Save the info in the original tables - * for rewriting to the disk. - */ - movb %al,_OPT(%bp) # Save option - - /* - * Make %si and %bx point to the fake partition at LBA 0 (CHS 0:0:1). - * Because the correct address is already in %bp, just use it. - * Set %dl with the drive number saved in byte 0. - * If we have pressed F5 or 5, then this is a good, fake value - * to present to the next stage boot code. - */ - movw %bp,%si # Partition for write - movb (%si),%dl # Drive number, saved above - movw %si,%bx # Partition for read - cmpb $0x4,%al # F5/#5 pressed? - pushf # Save results for later - je 1f # Yes, F5 - - /* - * F1..F4 was pressed, so make %bx point to the currently - * selected partition, and leave the drive number unchanged. - */ - shlb $0x4,%al # Point to - addw $partbl,%ax # selected - xchgw %bx,%ax # partition - movb $0x80,(%bx) # Flag active - /* - * If not asked to do a write-back (flags 0x40) don't do one. - * Around the call, save the partition pointer to %bx and - * restore to %si which is where the next stage expects it. - */ - 1: pushw %bx # Save - testb $NOUPDATE,_FLAGS(%bp) # No updates? - jnz 2f # skip update - movw $start,%bx # Data to write - movb $0x3,%ah # Write sector - callw intx13 # to disk - 2: popw %si # Restore - - /* - * If going to next drive, replace drive with selected one. - * Remember to un-ascii it. Hey 0x80 is already set, cool! - */ - popf # Restore %al test results - jne 3f # If not F5/#5 - movb _NXTDRV(%bp),%dl # Next drive - subb $'0',%dl # number - /* - * Load selected bootsector to the LOAD location in RAM. If read - * fails or there is no 0x55aa marker, treat it as a bad selection. - */ - 3: movw $LOAD,%bx # Address for read - movb $0x2,%ah # Read sector - callw intx13 # from disk - jc beep # If error - cmpw $MAGIC,0x1fe(%bx) # Bootable? - jne beep # No - pushw %si # Save ptr to selected part. - callw putn # Leave some space - popw %si # Restore, next stage uses it - jmp *%bx # Invoke bootstrap - -/* - * Display routines - * putkey prints the option selected in %dl (F1..F5 or 1..5) followed by - * the string at %si - * putx: print the option in %dl followed by the string at %di - * also record the drive as valid. - * putn: print a crlf - * putstr: print the string at %si - * putchr: print the char in al - */ - -/* - * Display the option and record the drive as valid in the options. - * That last point is done using the btsw instruction which does - * a test and set. We don't care for the test part. - */ -putx: btsw %dx,_MNUOPT(%bp) # Enable menu option - movw $item,%si # Display - callw putkey # key - movw %di,%si # Display the rest - callw putstr # Display string - -putn: movw $crlf,%si # To next line - jmp putstr - -putkey: -#ifndef SIO - movb $'F',%al # Display - callw putchr # 'F' -#endif - movb $'1',%al # Prepare - addb %dl,%al # digit - -putstr.1: callw putchr # Display char -putstr: lodsb # Get byte - testb $0x80,%al # End of string? - jz putstr.1 # No - andb $~0x80,%al # Clear MSB then print last - -putchr: -#ifndef SIO - pushw %bx # Save - movw $0x7,%bx # Page:attribute - movb $0xe,%ah # BIOS: Display - int $0x10 # character - popw %bx # Restore -#else /* SIO */ - movb $0x01,%ah # BIOS: Send -bioscom: - pushw %dx # Save - xorw %dx,%dx # Use COM1 - int $0x14 # Character - popw %dx # Restore -#endif /* SIO */ - retw # To caller - -/* One-sector disk I/O routine */ - -/* - * %dl: drive, %si partition entry, %es:%bx transfer buffer. - * Load the CHS values and possibly the LBA address from the block - * at %si, and use the appropriate method to load the sector. - * Don't use packet mode for a floppy. - */ -intx13: # Prepare CHS parameters - movb 0x1(%si),%dh # Load head - movw 0x2(%si),%cx # Load cylinder:sector - movb $0x1,%al # Sector count - pushw %si # Save - movw %sp,%di # Save -#ifndef CHECK_DRIVE /* floppy support */ - testb %dl, %dl # is this a floppy ? - jz 1f # Yes, use CHS mode -#endif - testb $USEPACKET,_FLAGS(%bp) # Use packet interface? - jz 1f # No - pushl $0x0 # Set the - pushl 0x8(%si) # LBA address - pushw %es # Set the transfer - pushw %bx # buffer address - push $0x1 # Block count - push $0x10 # Packet size - movw %sp,%si # Packet pointer - decw %ax # Verify off - orb $0x40,%ah # Use disk packet - 1: int $0x13 # BIOS: Disk I/O - movw %di,%sp # Restore - popw %si # Restore - retw # To caller - -/* - * Various menu strings. 'item' goes after 'prompt' to save space. - * Also use shorter versions to make room for the PXE/INT18 code. - */ -prompt: -#ifdef PXE - .ascii "\nF6 PXE\r" -#endif - .ascii "\nBoot:" -item: .ascii " "; .byte ' '|0x80 -crlf: .ascii "\r"; .byte '\n'|0x80 - -/* Partition type tables */ - -bootable_ids: - /* - * These values indicate bootable types we know about. - * Corresponding descriptions are at desc_ofs: - * Entries don't need to be sorted. - */ - .byte 0x83, 0xa5, 0xa6, 0xa9, 0x06, 0x07, 0x0b -#ifndef SAVE_MORE_MEMORY - .byte 0x05 # extended partition -#endif -#ifndef SAVE_MEMORY /* other DOS partitions */ - .byte 0x01 # FAT12 - .byte 0x04 # FAT16 < 32M -#endif - -desc_ofs: - /* - * Offsets that match the known types above, used to point to the - * actual partition name. The last entry must point to os_misc, - * which is used for non-matching names. - */ - .byte os_linux-. # 131, Linux - .byte os_freebsd-. # 165, FreeBSD - .byte os_bsd-. # 166, OpenBSD - .byte os_bsd-. # 169, NetBSD - .byte os_dos-. # 6, FAT16 >= 32M - .byte os_win-. # 7, NTFS - .byte os_win-. # 11, FAT32 - -#ifndef SAVE_MORE_MEMORY - .byte os_ext-. # 5, DOS Ext -#endif -#ifndef SAVE_MEMORY - .byte os_dos-. # 1, FAT12 DOS - .byte os_dos-. # 4, FAT16 <32M -#endif - .byte os_misc-. # Unknown - - /* - * And here are the strings themselves. The last byte of - * the string has bit 7 set. - */ -os_misc: .byte '?'|0x80 -os_dos: -#ifndef SAVE_MORE_MEMORY /* 'DOS' remapped to 'WIN' if no room */ - .ascii "DO"; .byte 'S'|0x80 -#endif -os_win: .ascii "Wi"; .byte 'n'|0x80 -os_linux: .ascii "Linu"; .byte 'x'|0x80 -os_freebsd: .ascii "Free" -os_bsd: .ascii "BS"; .byte 'D'|0x80 -#ifndef SAVE_MORE_MEMORY -os_ext: .ascii "EX"; .byte 'T'|0x80 -#endif - - .org (0x200 + B0_OFF),0x90 -/* - * The boot0 version 1.0 parameter table. - * Do not move it nor change the "Drive " string, boot0cfg - * uses its offset and content to identify the boot sector. - * The other fields are sometimes changed before writing back to the drive - * Be especially careful that nxtdrv: must come after drive:, as it - * is part of the same string. - */ -drive: .ascii "Drive " -nxtdrv: .byte 0x0 # Next drive number -opt: .byte 0x0 # Option -setdrv_num: .byte 0x80 # Drive to force -flags: .byte FLAGS # Flags -#ifdef VOLUME_SERIAL - .byte 0xa8,0xa8,0xa8,0xa8 # Volume Serial Number -#endif -ticks: .word TICKS # Delay - - .org PRT_OFF -/* - * Here is the 64 byte partition table that fdisk would fiddle with. - */ -partbl: .fill 0x40,0x1,0x0 # Partition table - .word MAGIC # Magic number - .org 0x200 # again, safety check -endblock: diff --git a/boot0/.svn/text-base/boot0ext.S.svn-base b/boot0/.svn/text-base/boot0ext.S.svn-base deleted file mode 100644 index a63de25..0000000 --- a/boot0/.svn/text-base/boot0ext.S.svn-base +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - * - * $FreeBSD$ - */ - -/* A 1024-byte boot manager. */ - - .set NHRDRV,0x475 # Number of hard drives - .set ORIGIN,0x600 # Execution address - .set SECTOR_SIZE,0x200 # Length of a sector - .set NUM_SECTORS,2 # Total length in sectors - - .set FAKE,ORIGIN+(SECTOR_SIZE*NUM_SECTORS) # Partition entry - .set LOAD,0x7c00 # Load address - - .set PRT_OFF,0x1be # Partition table - - .set TBL0SZ,table0_end-table0 # Table 0 size - .set TBL1SZ,table1_end-table1 # Table 1 size - - .set MAGIC,0xaa55 # Magic: bootable - - .set KEY_ENTER,0x1c # Enter key scan code - .set KEY_F1,0x3b # F1 key scan code - .set KEY_1,0x02 # #1 key scan code - -/* - * Flag bits - */ - .set FL_PACKET,0x80 # Packet mode - .set FL_NOUPDATE,0x40 # Don't save selection - .set FL_SETDRV,0x20 # Override drive number -/* - * Addresses in the sector of embedded data values. - * Accessed with negative offsets from the end of the relocated sectors (%bp). - */ - .set _PRT_END,(FAKE-(ORIGIN+SECTOR_SIZE*(NUM_SECTORS-1))) - .set _NXTDRV,-(_PRT_END+0x48) # Next drive - .set _OPT,-(_PRT_END+0x47) # Default option - .set _SETDRV,-(_PRT_END+0x46) # Drive to force - .set _FLAGS,-(_PRT_END+0x45) # Flags - .set _TICKS,-(_PRT_END+0x44) # Timeout ticks - .set _FAKE,0x0 # Fake partition entry - .set _MNUOPT,0xc # Menu options - - .globl start # Entry point - .code16 # This runs in real mode - -/* - * Initialise segments and registers to known values. - * segments start at 0. - * The stack is immediately below the address we were loaded to. - * - * Note that this section of code is used as the first signature check in - * boot0cfg(8). - */ -start: cld # String ops inc - xorw %ax,%ax # Zero - movw %ax,%es # Address - movw %ax,%ds # data - movw %ax,%ss # Set up - movw $LOAD,%sp # stack -/* - * End signature code - */ - -/* - * Set address for variable space beyond code, and clear it. - * Notice that this is also used to point to the values embedded in the block, - * by using negative offsets. - */ - movw $fake,%bp # Address variables - movw %bp,%di # %di used in stosw - movw $0x8,%cx # Words to clear - rep # Zero - stosw # them - incb -0xe(%di) # Sector number 1 -/* - * Check what flags were loaded with us; specifically, use a predefined Drive. - * If what the bios gives us is bad, use the '0' in the block instead, as well. - */ - testb $FL_SETDRV,LOAD+flags-start # Set number drive? - jnz boot.1 # Yes - testb %dl,%dl # Drive number valid? - js boot.2 # Possibly (0x80 set) -boot.1: movb LOAD+setdrv-start,%dl # Drive number to use -boot.2: -/* - * Reload all of boot0 (including the extra sectors) into memory at the - * relocation address. - */ - push %dx # Save drive number - movw $start,%bx # Origin we were linked for - movw %bp,%si # Fake PTE - movw $0x200+NUM_SECTORS,%ax # Read in all - callw intx13 # of boot0 - pop %dx # Restore -/* - * Relocate to the new copy of the code. - */ - jmp main+ORIGIN-LOAD # To relocated code -/* - * Whatever we decided to use, now store it into the fake - * partition entry that lives in the data space above us. - */ -main: movb %dl,_FAKE(%bp) # Save drive number - callw putn # To new line - pushw %dx # Save drive number -/* - * Start out with a pointer to the 4th byte of the first table entry - * so that after 4 iterations it's beyond the end of the sector. - * and beyond a 256 byte boundary and has overflowed 8 bits (see next comment). - * (remember that the table starts 2 bytes earlier than you would expect - * as the bootable flag is after it in the block) - */ - movw $(partbl+0x4),%bx # Partition table (+4) - xorw %dx,%dx # Item number -/* - * Loop around on the partition table, printing values until we - * pass a 256 byte boundary. The end of loop test is at main.5. - */ -main.3: movb %ch,-0x4(%bx) # Zero active flag (ch == 0) - btw %dx,_FLAGS(%bp) # Entry enabled? - jnc main.5 # No -/* - * If any of the entries in the table are - * the same as the 'type' in the slice table entry, - * then this is an empty or non bootable partition. Skip it. - */ - movb (%bx),%al # Load type - movw $tables,%di # Lookup tables - movb $TBL0SZ,%cl # Number of entries - repne # Exclude - scasb # partition? - je main.5 # Yes -/* - * Now scan the table of known types - */ - movb $TBL1SZ,%cl # Number of entries - repne # Known - scasb # type? - jne main.4 # No -/* - * If it matches get the matching element in the - * next array. If it doesn't, we are already - * pointing at its first element which points to a "?". - */ - addw $TBL1SZ,%di # Adjust -main.4: movb (%di),%cl # Partition - addw %cx,%di # description - callw putx # Display it -main.5: incw %dx # Next item - addb $0x10,%bl # Next entry - jnc main.3 # Till done -/* - * Passed a 256 byte boundary.. - * table is finished. - * Add one to the drive number and check it is valid, - */ - popw %ax # Drive number - subb $0x80-0x1,%al # Does next - cmpb NHRDRV,%al # drive exist? (from BIOS?) - jb main.6 # Yes -/* - * If not then if there is only one drive, - * Don't display drive as an option. - */ - decw %ax # Already drive 0? - jz main.7 # Yes -/* - * If it was illegal or we cycled through them, - * then go back to drive 0. - */ - xorb %al,%al # Drive 0 -/* - * Whatever drive we selected, make it an ascii digit and save it back - * to the "next drive" location in the loaded block in case we - * want to save it for next time. - * This also is part of the printed drive string so add 0x80 to indicate - * end of string. - */ -main.6: addb $'0'|0x80,%al # Save next - movb %al,_NXTDRV(%bp) # drive number - movw $drive,%di # Display - callw putx # item -/* - * Now that we've printed the drive (if we needed to), display a prompt. - * Get ready for the input by noting the time. - */ -main.7: movw $prompt,%si # Display - callw putstr # prompt - movb _OPT(%bp),%dl # Display - decw %si # default - callw putkey # key - xorb %ah,%ah # BIOS: Get - int $0x1a # system time - movw %dx,%di # Ticks when - addw _TICKS(%bp),%di # timeout -/* - * Busy loop, looking for keystrokes but - * keeping one eye on the time. - */ -main.8: movb $0x1,%ah # BIOS: Check - int $0x16 # for keypress - jnz main.11 # Have one - xorb %ah,%ah # BIOS: Get - int $0x1a # system time - cmpw %di,%dx # Timeout? - jb main.8 # No -/* - * If timed out or defaulting, come here. - */ -main.9: movb _OPT(%bp),%al # Load default - jmp main.12 # Join common code -/* - * User's last try was bad, beep in displeasure. - * Since nothing was printed, just continue on as if the user - * hadn't done anything. This gives the effect of the user getting a beep - * for all bad keystrokes but no action until either the timeout - * occurs or the user hits a good key. - */ -main.10: movb $0x7,%al # Signal - callw putchr # error -/* - * Get the keystroke. - */ -main.11: xorb %ah,%ah # BIOS: Get - int $0x16 # keypress - movb %ah,%al # Scan code -/* - * If it's CR act as if timed out. - */ - cmpb $KEY_ENTER,%al # Enter pressed? - je main.9 # Yes -/* - * Otherwise check if legal - * If not ask again. - */ - subb $KEY_F1,%al # Less F1 scan code - cmpb $0x4,%al # F1..F5? - jna main.12 # Yes - subb $(KEY_1 - KEY_F1),%al # Less #1 scan code - cmpb $0x4,%al # #1..#5? - ja main.10 # No -/* - * We have a selection. - * but if it's a bad selection go back to complain. - * The bits in MNUOPT were set when the options were printed. - * Anything not printed is not an option. - */ -main.12: cbtw # Option - btw %ax,_MNUOPT(%bp) # enabled? - jnc main.10 # No -/* - * Save the info in the original tables - * for rewriting to the disk. - */ - movb %al,_OPT(%bp) # Save option - movw $fake,%si # Partition for write - movb (%si),%dl # Drive number - movw %si,%bx # Partition for read - cmpb $0x4,%al # F5/#5 pressed? - pushf # Save - je main.13 # Yes - shlb $0x4,%al # Point to - addw $partbl,%ax # selected - xchgw %bx,%ax # partition - movb $0x80,(%bx) # Flag active -/* - * If not asked to do a write-back (flags 0x40) don't do one. - */ -main.13: pushw %bx # Save - testb $FL_NOUPDATE,_FLAGS(%bp) # Skip update? - jnz main.14 # Yes - movw $start,%bx # Data to write - movw $0x301,%ax # Write 1 sector - callw intx13 # to disk -main.14: popw %si # Restore - popf # Restore -/* - * If going to next drive, replace drive with selected one. - * Remember to un-ascii it. Hey 0x80 is already set, cool! - */ - jne main.15 # If not F5/#5 - movb _NXTDRV(%bp),%dl # Next drive - subb $'0',%dl # number -/* - * load selected bootsector to the LOAD location in RAM. - * If it fails to read or isn't marked bootable, treat it - * as a bad selection. - */ -main.15: movw $LOAD,%bx # Address for read - movw $0x201,%ax # Read 1 sector - callw intx13 # from disk - jc main.10 # If error - cmpw $MAGIC,0x1fe(%bx) # Bootable? - jne main.10 # No - callw putn # Leave some space - jmp *%bx # Invoke bootstrap - -/* - * Display routines - */ - -putkey: movb $'F',%al # Display - callw putchr # 'F' - movb $'1',%al # Prepare - addb %dl,%al # digit - jmp putstr.1 # Display the rest - -/* - * Display the option and note that it is a valid option. - * That last point is a bit tricky.. - */ -putx: btsw %dx,_MNUOPT(%bp) # Enable menu option - movw $item,%si # Display - callw putkey # key - movw %di,%si # Display the rest - -puts: callw putstr # Display string - -putn: movw $crlf,%si # To next line - -putstr: lodsb # Get byte - testb $0x80,%al # End of string? - jnz putstr.2 # Yes -putstr.1: callw putchr # Display char - jmp putstr # Continue -putstr.2: andb $~0x80,%al # Clear MSB - -putchr: pushw %bx # Save - movw $0x7,%bx # Page:attribute - movb $0xe,%ah # BIOS: Display - int $0x10 # character - popw %bx # Restore - retw # To caller - -/* - * One-sector disk I/O routine - * - * Calling conventions: (assumes %si -> partition table entry) - * - * 0x1(%si) - byte - head - * 0x2(%si) - word - cylinder/sector - * 0x8(%si) - long - LBA to use if needed - * %ah - byte - operation, 2 = read, 3 = write - * %al - byte - sector count - * %dl - byte - drive number - * %es:(%bx) - void - buffer to use for transfer - * - * If the head == 0xff, and cylinder/sector == 0xffff, then try - * to use the EDD stuff with the LBA offset instead of CHS. However, - * use CHS if at all possible. - */ - -intx13: movb 0x1(%si),%dh # Load head - movw 0x2(%si),%cx # Load cylinder:sector - pushw %si # Save - movw %sp,%di # Save - cmpb $0xff,%dh # Might we need LBA? - jne intx13.2 # No, just use CHS - cmpw $0xffff,%cx # Do we need LBA? - jne intx13.2 # No - testb $FL_PACKET,_FLAGS(%bp) # Try the packet interface? - jz intx13.2 # No - pushw %cx # Save - pushw %bx # Save - movw $0x55aa,%bx # Magic - pushw %ax # Save - movb $0x41,%ah # BIOS: EDD extensions - int $0x13 # present? - popw %ax # Restore - jc intx13.1 # Not present, use CHS - cmpw $0xaa55,%bx # Magic? - jne intx13.1 # Not present, use CHS - testb $0x1,%cl # Packet mode available? - jz intx13.1 # No, use CHS - orb $0x40,%ah # Use disk packet -intx13.1: popw %bx # Restore - popw %cx # Restore - testb $0x40,%ah # Using packet mode? - jz intx13.2 # No, so skip the rest - pushl $0x0 # Set the - pushl 0x8(%si) # LBA address - pushw %es # Set the transfer - pushw %bx # buffer address - push $0x0 # Punch a hole in the stack - push $0x10 # Packet size - movw %sp,%si # Packet pointer - xchgb %al,0x2(%si) # Set the block count in the - # packet and zero %al, - # turning verify off for writes -intx13.2: int $0x13 # BIOS: Disk I/O - movw %di,%sp # Restore - popw %si # Restore - retw # To caller - - .org PRT_OFF-0xe,0x90 -/* - * These values are sometimes changed before writing back to the drive - * Be especially careful that nxtdrv: must come after drive:, as it - * is part of the same string. - * - * Note that the 'drive' string variable is used as the second signature - * check in boot0cfg(8). - */ -version_minor: .byte 0x1 # minor version -version_major: .byte 0x1 # major version -drive: .ascii "Drive " -nxtdrv: .byte 0x0 # Next drive number -opt: .byte 0x0 # Option -setdrv: .byte 0x80 # Drive to force -flags: .byte FLAGS # Flags -ticks: .word TICKS # Delay - -/* - * here is the 64 byte partition table that fdisk would fiddle with. - */ -partbl: .fill 0x40,0x1,0x0 # Partition table - .word MAGIC # Magic number - -/* - * start of sector two.. ugh - */ - .org SECTOR_SIZE,0x90 - -/* Menu strings */ - -item: .ascii " "; .byte ' '|0x80 -prompt: .ascii "\nDefault:"; .byte ' '|0x80 -crlf: .ascii "\r"; .byte '\n'|0x80 - -/* Partition type tables */ - -tables: -/* - * These entries identify invalid or NON BOOT types and partitions. - */ -table0: .byte 0x0, 0x5, 0xf -table0_end: -/* - * These values indicate bootable types we know the names of - */ -table1: .byte 0x1, 0x4, 0x6, 0x7, 0xb, 0xc, 0xe, 0x42, 0x63, 0x83 - .byte 0x9f, 0xa5, 0xa6, 0xa9 -table1_end: -/* - * These are offsets that match the known names above and point to the strings - * that will be printed. - */ - .byte os_misc-. # Unknown - .byte os_dos-. # DOS - .byte os_dos-. # DOS - .byte os_dos-. # DOS - .byte os_nt-. # NT/XP or OS/2 - .byte os_windows-. # Windows 32-bit FAT - .byte os_windows-. # Windows 32-bit FAT ext int 13 - .byte os_windows-. # Windows - .byte os_windows-. # Windows 2000 dyn ext - .byte os_unix-. # UNIX - .byte os_linux-. # Linux - .byte os_bsdos-. # BSD/OS - .byte os_freebsd-. # FreeBSD - .byte os_openbsd-. # OpenBSD - .byte os_netbsd-. # NetBSD -/* - * And here are the strings themselves. 0x80 or'd into a byte indicates - * the end of the string. (not so great for Russians but...) - */ -os_misc: .ascii "Unknow"; .byte 'n'|0x80 -os_dos: .ascii "DO"; .byte 'S'|0x80 -os_nt: .ascii "Windows NT/X"; .byte 'P'|0x80 -os_windows: .ascii "Window"; .byte 's'|0x80 -os_unix: .ascii "UNI"; .byte 'X'|0x80 -os_linux: .ascii "Linu"; .byte 'x'|0x80 -os_freebsd: .ascii "FreeBS"; .byte 'D'|0x80 -os_openbsd: .ascii "OpenBS"; .byte 'D'|0x80 -os_netbsd: .ascii "NetBS"; .byte 'D'|0x80 -os_bsdos: .ascii "BSD/O"; .byte 'S'|0x80 - -/* - * Fake partition entry created at the end of the table used when loading - * boot0 at the very beginning and when loading an MBR from another disk when - * F5 is pressed. - */ - .org SECTOR_SIZE*NUM_SECTORS, 0x0 -fake: diff --git a/boot0/GNUMakefile b/boot0/GNUMakefile new file mode 100644 index 0000000..2f47978 --- /dev/null +++ b/boot0/GNUMakefile @@ -0,0 +1,46 @@ +CPPFLAGS=${CFLAGS} -O2 -fno-strict-aliasing -pipe -ffreestanding -mpreferred-stack-boundary=2 -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -m32 -march=i386 +PROG?= boot0 +BINMODE=${NOBINMODE} +SRCS= ${PROG}.S + +# The default set of flags compiled into boot0. This enables update (writing +# the modified boot0 back to disk after running so that the selection made is +# saved), packet mode (detect and use the BIOS EDD extensions if we try to +# boot past the 1024 cylinder liimt), and booting from all valid slices. +BOOT_BOOT0_FLAGS?= 0x8f + +# The number of timer ticks to wait for a keypress before assuming the default +# selection. Since there are 18.2 ticks per second, the default value of +# 0xb6 (182d) corresponds to 10 seconds. +BOOT_BOOT0_TICKS?= 0xb6 + +# The base address that we the boot0 code to to run it. Don't change this +# unless you are glutton for punishment. +BOOT_BOOT0_ORG?= 0x600 + +# Comm settings for boot0sio. +# Bit(s) Description +# 7-5 data rate (110,150,300,600,1200,2400,4800,9600 bps) +# 4-3 parity (00 or 10 = none, 01 = odd, 11 = even) +# 2 stop bits (set = 2, clear = 1) +# 1-0 data bits (00 = 5, 01 = 6, 10 = 7, 11 = 8) +BOOT_COMCONSOLE_SPEED= 9600 +BOOT_BOOT0_COMCONSOLE_SPEED= "7 << 5 + 3" + +CPPFLAGS+=-DFLAGS=${BOOT_BOOT0_FLAGS} \ + -DTICKS=${BOOT_BOOT0_TICKS} \ + -DCOMSPEED=${BOOT_BOOT0_COMCONSOLE_SPEED} + +LDFLAGS=-N -e start -Ttext=${BOOT_BOOT0_ORG} -Wl,-S,--oformat,binary -nostdlib -Xlinker -melf_i386 + +all: boot0 boot0ext + +boot0: boot0.o + +boot0ext: boot0ext.o + +clean: + rm -f *.o boot0 + +distclean: clean + rm -f o oo ooo *~ *.bak boot0[^.][^.][^.] diff --git a/boot0/boot0.S b/boot0/boot0.S index 798ee97..c061bf2 100644 --- a/boot0/boot0.S +++ b/boot0/boot0.S @@ -604,14 +604,20 @@ bootable_ids: * Corresponding descriptions are at desc_ofs: * Entries don't need to be sorted. */ +#ifdef LINUX_VERSION + .byte 0x83, 0xa5, 0xa6, 0xa9, 0x82, 0x8e, 0xfd, 0x07, 0x15 +#else .byte 0x83, 0xa5, 0xa6, 0xa9, 0x06, 0x07, 0x0b +#endif #ifndef SAVE_MORE_MEMORY .byte 0x05 # extended partition #endif +#ifndef LINUX_VERSION #ifndef SAVE_MEMORY /* other DOS partitions */ .byte 0x01 # FAT12 .byte 0x04 # FAT16 < 32M #endif +#endif desc_ofs: /* @@ -623,17 +629,27 @@ desc_ofs: .byte os_freebsd-. # 165, FreeBSD .byte os_bsd-. # 166, OpenBSD .byte os_bsd-. # 169, NetBSD +#ifdef LINUX_VERSION + .byte os_swap-. # 130, Linux swap + .byte os_lvm-. # 142, Linux LVM + .byte os_raid-. # 253, Linux RAID auto + .byte os_win-. # 7, NTFS + .byte os_ext-. # 15, LBA Ext +#else .byte os_dos-. # 6, FAT16 >= 32M .byte os_win-. # 7, NTFS .byte os_win-. # 11, FAT32 +#endif #ifndef SAVE_MORE_MEMORY .byte os_ext-. # 5, DOS Ext #endif +#ifndef LINUX_VERSION #ifndef SAVE_MEMORY .byte os_dos-. # 1, FAT12 DOS .byte os_dos-. # 4, FAT16 <32M #endif +#endif .byte os_misc-. # Unknown /* @@ -642,12 +658,21 @@ desc_ofs: */ os_misc: .byte '?'|0x80 os_dos: +#ifndef LINUX_VERSION #ifndef SAVE_MORE_MEMORY /* 'DOS' remapped to 'WIN' if no room */ .ascii "DO"; .byte 'S'|0x80 #endif +#endif os_win: .ascii "Wi"; .byte 'n'|0x80 os_linux: .ascii "Linu"; .byte 'x'|0x80 +#ifdef LINUX_VERSION +os_swap: .ascii "swa"; .byte 'p'|0x80 +os_lvm: .ascii "LV"; .byte 'M'|0x80 +os_raid: .ascii "RAI"; .byte 'D'|0x80 +os_freebsd: +#else os_freebsd: .ascii "Free" +#endif os_bsd: .ascii "BS"; .byte 'D'|0x80 #ifndef SAVE_MORE_MEMORY os_ext: .ascii "EX"; .byte 'T'|0x80 diff --git a/boot0cfg/.svn/all-wcprops b/boot0cfg/.svn/all-wcprops deleted file mode 100644 index f2289b8..0000000 --- a/boot0cfg/.svn/all-wcprops +++ /dev/null @@ -1,23 +0,0 @@ -K 25 -svn:wc:ra_dav:version-url -V 44 -/base/!svn/ver/233455/head/usr.sbin/boot0cfg -END -boot0cfg.c -K 25 -svn:wc:ra_dav:version-url -V 55 -/base/!svn/ver/228738/head/usr.sbin/boot0cfg/boot0cfg.c -END -boot0cfg.8 -K 25 -svn:wc:ra_dav:version-url -V 55 -/base/!svn/ver/233455/head/usr.sbin/boot0cfg/boot0cfg.8 -END -Makefile -K 25 -svn:wc:ra_dav:version-url -V 53 -/base/!svn/ver/228656/head/usr.sbin/boot0cfg/Makefile -END diff --git a/boot0cfg/.svn/entries b/boot0cfg/.svn/entries deleted file mode 100644 index 4a3e2a1..0000000 --- a/boot0cfg/.svn/entries +++ /dev/null @@ -1,130 +0,0 @@ -10 - -dir -236712 -http://svn.freebsd.org/base/head/usr.sbin/boot0cfg -http://svn.freebsd.org/base - - - -2012-03-25T09:18:34.770404Z -233455 -joel - - - - - - - - - - - - - - -ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f - -boot0cfg.c -file - - - - -2012-06-07T10:31:53.000000Z -65783ac4d015b3ac44f69662079c0273 -2011-12-20T15:19:29.116458Z -228738 -jhb -has-props - - - - - - - - - - - - - - - - - - - - -16529 - -boot0cfg.8 -file - - - - -2012-06-07T10:31:53.000000Z -557f64bee97ffc53099eacf4c53ae279 -2012-03-25T09:18:34.770404Z -233455 -joel -has-props - - - - - - - - - - - - - - - - - - - - -6116 - -Makefile -file - - - - -2012-06-07T10:31:53.000000Z -357a0ea513ee17697d37638bd8e95fa7 -2011-12-17T19:33:26.792240Z -228656 -dim -has-props - - - - - - - - - - - - - - - - - - - - -158 - diff --git a/boot0cfg/.svn/prop-base/Makefile.svn-base b/boot0cfg/.svn/prop-base/Makefile.svn-base deleted file mode 100644 index 205b913..0000000 --- a/boot0cfg/.svn/prop-base/Makefile.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 12 -svn:keywords -V 10 -FreeBSD=%H -END diff --git a/boot0cfg/.svn/prop-base/boot0cfg.8.svn-base b/boot0cfg/.svn/prop-base/boot0cfg.8.svn-base deleted file mode 100644 index 205b913..0000000 --- a/boot0cfg/.svn/prop-base/boot0cfg.8.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 12 -svn:keywords -V 10 -FreeBSD=%H -END diff --git a/boot0cfg/.svn/prop-base/boot0cfg.c.svn-base b/boot0cfg/.svn/prop-base/boot0cfg.c.svn-base deleted file mode 100644 index 205b913..0000000 --- a/boot0cfg/.svn/prop-base/boot0cfg.c.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 12 -svn:keywords -V 10 -FreeBSD=%H -END diff --git a/boot0cfg/.svn/text-base/Makefile.svn-base b/boot0cfg/.svn/text-base/Makefile.svn-base deleted file mode 100644 index bb7fe07..0000000 --- a/boot0cfg/.svn/text-base/Makefile.svn-base +++ /dev/null @@ -1,11 +0,0 @@ -# $FreeBSD$ - -PROG= boot0cfg -MAN= boot0cfg.8 - -DPADD= ${LIBGEOM} ${LIBBSDXML} ${LIBSBUF} -LDADD= -lgeom -lbsdxml -lsbuf - -NO_WCAST_ALIGN= - -.include diff --git a/boot0cfg/.svn/text-base/boot0cfg.8.svn-base b/boot0cfg/.svn/text-base/boot0cfg.8.svn-base deleted file mode 100644 index 4d622a2..0000000 --- a/boot0cfg/.svn/text-base/boot0cfg.8.svn-base +++ /dev/null @@ -1,205 +0,0 @@ -.\" Copyright (c) 1999 Robert Nordier -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS -.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -.\" OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -.\" OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd February 4, 2012 -.Dt BOOT0CFG 8 -.Os -.Sh NAME -.Nm boot0cfg -.Nd boot manager installation/configuration utility -.Sh SYNOPSIS -.Nm -.Op Fl Bv -.Op Fl b Ar boot0 -.Op Fl d Ar drive -.Op Fl e Ar bell character -.Op Fl f Ar file -.Op Fl i Ar volume-id -.Op Fl m Ar mask -.Op Fl o Ar options -.Op Fl s Ar slice -.Op Fl t Ar ticks -.Ar disk -.Sh DESCRIPTION -The -.Fx -.Sq boot0 -boot manager permits the operator to select from which disk and -slice an i386 machine (PC) is booted. -.Pp -Note that what are referred to here as -.Dq slices -are typically called -.Dq partitions -in -.No non- Ns Bx -documentation relating to the PC. -Typically, only non-removable disks are sliced. -.Pp -The -.Nm -utility optionally installs the -.Sq boot0 -boot manager on the specified -.Ar disk ; -and allows various operational parameters to be configured. -.Pp -On PCs, a boot manager typically occupies sector 0 of a disk, which is -known as the Master Boot Record (MBR). -The MBR contains both code (to which control is passed by the PC BIOS) -and data (an embedded table of defined slices). -.Pp -The options are: -.Bl -tag -width indent -.It Fl B -Install the -.Sq boot0 -boot manager. -This option causes MBR code to be replaced, without -affecting the embedded slice table. -.It Fl b Ar boot0 -Specify which -.Sq boot0 -image to use. -The default is -.Pa /boot/boot0 -which will use the video card as output, alternatively -.Pa /boot/boot0sio -can be used for output to the COM1 port. -(Be aware that nothing will be output to the COM1 port unless the -modem signals DSR and CTS are active.) -.It Fl d Ar drive -Specify the drive number used by the PC BIOS in referencing the drive -which contains the specified -.Ar disk . -Typically this will be 0x80 for the first hard drive, 0x81 for the -second hard drive, and so on; however any integer between 0 and 0xff -is acceptable here. -.It Fl e Ar bell character -Set the character to be printed in case of input error. -.It Fl f Ar file -Specify that a backup copy of the preexisting MBR should be written to -.Ar file . -This file is created if it does not exist, and replaced if it does. -.It Fl i Ar volume-id -Specifies a volume-id (in the form XXXX-XXXX) to be saved at location -0x1b8 in the MBR. This information is sometimes used by NT, XP and Vista -to identify the disk drive. The option is only compatible with version 2.00 -of the 512-byte boot block. -.It Fl m Ar mask -Specify slices to be enabled/disabled, where -.Ar mask -is an integer between 0 (no slices enabled) and 0xf (all four slices -enabled). -Each mask bit enables corresponding slice if set to 1. -The least significant bit of the mask corresponds to slice 1, -the most significant bit of the mask corresponds to slice 4. -.It Fl o Ar options -A comma-separated string of any of the following options may be -specified (with -.Dq no -prepended as necessary): -.Bl -tag -width indent -.It packet -Use the disk packet (BIOS INT 0x13 extensions) interface, -as opposed to the legacy (CHS) interface, when doing disk I/O. -This allows booting above cylinder 1023, but requires specific -BIOS support. -The default is -.Sq packet . -.It setdrv -Forces the drive containing the disk to be referenced using drive -number definable by means of the -d option. -The default is -.Sq nosetdrv . -.It update -Allow the MBR to be updated by the boot manager. -(The MBR may be updated to flag slices as -.Sq active , -and to save slice selection information.) -This is the default; a -.Sq noupdate -option causes the MBR to be treated as read-only. -.El -.It Fl s Ar slice -Set the default boot selection to -.Ar slice . -Values between 1 and 4 refer to slices; a value of 5 refers to the -option of booting from a second disk. -The special string -.Dq PXE -or a value of 6 can be used to boot via PXE. -.It Fl t Ar ticks -Set the timeout value to -.Ar ticks . -(There are approximately 18.2 ticks per second.) -.It Fl v -Verbose: display information about the slices defined, etc. -.El -.Sh FILES -.Bl -tag -width /boot/boot0sio -compact -.It Pa /boot/boot0 -The default -.Sq boot0 -image -.It Pa /boot/boot0sio -Image for serial consoles (COM1,9600,8,N,1,MODEM) -.El -.Sh EXIT STATUS -.Ex -std -.Sh EXAMPLES -To boot slice 2 on the next boot: -.Pp -.Dl "boot0cfg -s 2 ad0" -.Pp -To enable just slices 1 and 3 in the menu: -.Pp -.Dl "boot0cfg -m 0x5 ad0" -.Pp -To go back to non-interactive booting, use -.Xr fdisk 8 -to install the default MBR: -.Pp -.Dl "fdisk -B ad0" -.Sh SEE ALSO -.Xr geom 4 , -.Xr boot 8 , -.Xr fdisk 8 , -.Xr gpart 8 -.Sh AUTHORS -.An Robert Nordier Aq rnordier@FreeBSD.org . -.Sh BUGS -Use of the -.Sq packet -option may cause -.Sq boot0 -to fail, depending on the nature of BIOS support. -.Pp -Use of the -.Sq setdrv -option with an incorrect -d operand may cause the boot0 code -to write the MBR to the wrong disk, thus trashing its previous -content. Be careful. diff --git a/boot0cfg/.svn/text-base/boot0cfg.c.svn-base b/boot0cfg/.svn/text-base/boot0cfg.c.svn-base deleted file mode 100644 index 2602e50..0000000 --- a/boot0cfg/.svn/text-base/boot0cfg.c.svn-base +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Copyright (c) 2008 Luigi Rizzo - * Copyright (c) 1999 Robert Nordier - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MBRSIZE 512 /* master boot record size */ - -#define OFF_VERSION 0x1b0 /* offset: version number, only boot0version */ -#define OFF_SERIAL 0x1b8 /* offset: volume serial number */ -#define OFF_PTBL 0x1be /* offset: partition table */ -#define OFF_MAGIC 0x1fe /* offset: magic number */ -/* - * Offsets to the parameters of the 512-byte boot block. - * For historical reasons they are set as macros - */ -struct opt_offsets { - int opt; - int drive; - int flags; - int ticks; -}; - -static struct opt_offsets b0_ofs[] = { - { 0x0, 0x0, 0x0, 0x0 }, /* no boot block */ - { 0x1b9, 0x1ba, 0x1bb, 0x1bc }, /* original block */ - { 0x1b5, 0x1b6, 0x1b7, 0x1bc }, /* NT_SERIAL block */ -}; - -static int b0_ver; /* boot block version set by boot0bs */ - -#define OFF_OPT (b0_ofs[b0_ver].opt) /* default boot option */ -#define OFF_DRIVE (b0_ofs[b0_ver].drive) /* setdrv drive */ -#define OFF_FLAGS (b0_ofs[b0_ver].flags) /* option flags */ -#define OFF_TICKS (b0_ofs[b0_ver].ticks) /* clock ticks */ - - -#define cv2(p) ((p)[0] | (p)[1] << 010) - -#define mk2(p, x) \ - (p)[0] = (u_int8_t)(x), \ - (p)[1] = (u_int8_t)((x) >> 010) - -static const struct { - const char *tok; - int def; -} opttbl[] = { - {"packet", 0}, - {"update", 1}, - {"setdrv", 0} -}; -static const int nopt = sizeof(opttbl) / sizeof(opttbl[0]); - -static const char fmt0[] = "# flag start chs type" - " end chs offset size\n"; - -static const char fmt1[] = "%d 0x%02x %4u:%3u:%2u 0x%02x" - " %4u:%3u:%2u %10u %10u\n"; - -static int geom_class_available(const char *); -static int read_mbr(const char *, u_int8_t **, int); -static void write_mbr(const char *, int, u_int8_t *, int); -static void display_mbr(u_int8_t *); -static int boot0version(const u_int8_t *); -static int boot0bs(const u_int8_t *); -static void stropt(const char *, int *, int *); -static int argtoi(const char *, int, int, int); -static int set_bell(u_int8_t *, int, int); -static void usage(void); - -static unsigned vol_id[5]; /* 4 plus 1 for flag */ - -static int v_flag; -/* - * Boot manager installation/configuration utility. - */ -int -main(int argc, char *argv[]) -{ - u_int8_t *mbr, *boot0; - int boot0_size, mbr_size; - const char *bpath, *fpath; - char *disk; - int B_flag, o_flag; - int d_arg, m_arg, s_arg, t_arg; - int o_and, o_or, o_e = -1; - int up, c; - - bpath = "/boot/boot0"; - fpath = NULL; - B_flag = v_flag = o_flag = 0; - d_arg = m_arg = s_arg = t_arg = -1; - o_and = 0xff; - o_or = 0; - while ((c = getopt(argc, argv, "Bvb:d:e:f:i:m:o:s:t:")) != -1) - switch (c) { - case 'B': - B_flag = 1; - break; - case 'v': - v_flag = 1; - break; - case 'b': - bpath = optarg; - break; - case 'd': - d_arg = argtoi(optarg, 0, 0xff, 'd'); - break; - case 'e': - if (optarg[0] == '0' && optarg[1] == 'x') - sscanf(optarg, "0x%02x", &o_e); - else - o_e = optarg[0]; - break; - case 'f': - fpath = optarg; - break; - case 'i': - if (sscanf(optarg, "%02x%02x-%02x%02x", - vol_id, vol_id+1, vol_id+2, vol_id+3) == 4) - vol_id[4] = 1; - else - errx(1, "bad argument %s", optarg); - break; - case 'm': - m_arg = argtoi(optarg, 0, 0xf, 'm'); - break; - case 'o': - stropt(optarg, &o_and, &o_or); - o_flag = 1; - break; - case 's': - if (strcasecmp(optarg, "pxe") == 0) - s_arg = 6; - else - s_arg = argtoi(optarg, 1, 6, 's'); - break; - case 't': - t_arg = argtoi(optarg, 1, 0xffff, 't'); - break; - default: - usage(); - } - argc -= optind; - argv += optind; - if (argc != 1) - usage(); - disk = g_device_path(*argv); - if (disk == NULL) - errx(1, "Unable to get providername for %s\n", *argv); - up = B_flag || d_arg != -1 || m_arg != -1 || o_flag || s_arg != -1 - || t_arg != -1; - - /* open the disk and read in the existing mbr. Either here or - * when reading the block from disk, we do check for the version - * and abort if a suitable block is not found. - */ - mbr_size = read_mbr(disk, &mbr, !B_flag); - - /* save the existing MBR if we are asked to do so */ - if (fpath) - write_mbr(fpath, O_CREAT | O_TRUNC, mbr, mbr_size); - - /* - * If we are installing the boot loader, read it from disk and copy the - * slice table over from the existing MBR. If not, then point boot0 - * back at the MBR we just read in. After this, boot0 is the data to - * write back to disk if we are going to do a write. - */ - if (B_flag) { - boot0_size = read_mbr(bpath, &boot0, 1); - memcpy(boot0 + OFF_PTBL, mbr + OFF_PTBL, - sizeof(struct dos_partition) * NDOSPART); - if (b0_ver == 2) /* volume serial number support */ - memcpy(boot0 + OFF_SERIAL, mbr + OFF_SERIAL, 4); - } else { - boot0 = mbr; - boot0_size = mbr_size; - } - - /* set the drive */ - if (d_arg != -1) - boot0[OFF_DRIVE] = d_arg; - - /* set various flags */ - if (m_arg != -1) { - boot0[OFF_FLAGS] &= 0xf0; - boot0[OFF_FLAGS] |= m_arg; - } - if (o_flag) { - boot0[OFF_FLAGS] &= o_and; - boot0[OFF_FLAGS] |= o_or; - } - - /* set the default boot selection */ - if (s_arg != -1) - boot0[OFF_OPT] = s_arg - 1; - - /* set the timeout */ - if (t_arg != -1) - mk2(boot0 + OFF_TICKS, t_arg); - - /* set the bell char */ - if (o_e != -1 && set_bell(boot0, o_e, 0) != -1) - up = 1; - - if (vol_id[4]) { - if (b0_ver != 2) - errx(1, "incompatible boot block, cannot set volume ID"); - boot0[OFF_SERIAL] = vol_id[0]; - boot0[OFF_SERIAL+1] = vol_id[1]; - boot0[OFF_SERIAL+2] = vol_id[2]; - boot0[OFF_SERIAL+3] = vol_id[3]; - up = 1; /* force update */ - } - /* write the MBR back to disk */ - if (up) - write_mbr(disk, 0, boot0, boot0_size); - - /* display the MBR */ - if (v_flag) - display_mbr(boot0); - - /* clean up */ - if (mbr != boot0) - free(boot0); - free(mbr); - free(disk); - - return 0; -} - -/* get or set the 'bell' character to be used in case of errors. - * Lookup for a certain code sequence, return -1 if not found. - */ -static int -set_bell(u_int8_t *mbr, int new_bell, int report) -{ - /* lookup sequence: 0x100 means skip, 0x200 means done */ - static unsigned seq[] = - { 0xb0, 0x100, 0xe8, 0x100, 0x100, 0x30, 0xe4, 0x200 }; - int ofs, i, c; - for (ofs = 0x60; ofs < 0x180; ofs++) { /* search range */ - if (mbr[ofs] != seq[0]) /* search initial pattern */ - continue; - for (i=0;; i++) { - if (seq[i] == 0x200) { /* found */ - c = mbr[ofs+1]; - if (!report) - mbr[ofs+1] = c = new_bell; - else - printf(" bell=%c (0x%x)", - (c >= ' ' && c < 0x7f) ? c : ' ', c); - return c; - } - if (seq[i] != 0x100 && seq[i] != mbr[ofs+i]) - break; - } - } - warn("bell not found"); - return -1; -} -/* - * Read in the MBR of the disk. If it is boot0, then use the version to - * read in all of it if necessary. Use pointers to return a malloc'd - * buffer containing the MBR and then return its size. - */ -static int -read_mbr(const char *disk, u_int8_t **mbr, int check_version) -{ - u_int8_t buf[MBRSIZE]; - int mbr_size, fd; - int ver; - ssize_t n; - - if ((fd = open(disk, O_RDONLY)) == -1) - err(1, "open %s", disk); - if ((n = read(fd, buf, MBRSIZE)) == -1) - err(1, "read %s", disk); - if (n != MBRSIZE) - errx(1, "%s: short read", disk); - if (cv2(buf + OFF_MAGIC) != 0xaa55) - errx(1, "%s: bad magic", disk); - - if (! (ver = boot0bs(buf))) { - if (check_version) - errx(1, "%s: unknown or incompatible boot code", disk); - } else if (boot0version(buf) == 0x101) { - mbr_size = 1024; - if ((*mbr = malloc(mbr_size)) == NULL) - errx(1, "%s: unable to allocate read buffer", disk); - if (lseek(fd, 0, SEEK_SET) == -1 || - (n = read(fd, *mbr, mbr_size)) == -1) - err(1, "%s", disk); - if (n != mbr_size) - errx(1, "%s: short read", disk); - close(fd); - return (mbr_size); - } - *mbr = malloc(sizeof(buf)); - memcpy(*mbr, buf, sizeof(buf)); - close(fd); - - return sizeof(buf); -} - -static int -geom_class_available(const char *name) -{ - struct gclass *class; - struct gmesh mesh; - int error; - - error = geom_gettree(&mesh); - if (error != 0) - errc(1, error, "Cannot get GEOM tree"); - - LIST_FOREACH(class, &mesh.lg_class, lg_class) { - if (strcmp(class->lg_name, name) == 0) { - geom_deletetree(&mesh); - return (1); - } - } - - geom_deletetree(&mesh); - return (0); -} - -/* - * Write out the mbr to the specified file. - */ -static void -write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size) -{ - struct gctl_req *grq; - const char *errmsg; - char *pname; - ssize_t n; - int fd; - - fd = open(fname, O_WRONLY | flags, 0666); - if (fd != -1) { - n = write(fd, mbr, mbr_size); - close(fd); - if (n != mbr_size) - errx(1, "%s: short write", fname); - return; - } - - /* - * If we're called to write to a backup file, don't try to - * write through GEOM. - */ - if (flags != 0) - err(1, "can't open file %s to write backup", fname); - - /* Try open it read only. */ - fd = open(fname, O_RDONLY); - if (fd == -1) { - warn("error opening %s", fname); - return; - } - - pname = g_providername(fd); - if (pname == NULL) { - warn("error getting providername for %s", fname); - return; - } - - /* First check that GEOM_PART is available */ - if (geom_class_available("PART") != 0) { - grq = gctl_get_handle(); - gctl_ro_param(grq, "class", -1, "PART"); - gctl_ro_param(grq, "arg0", -1, pname); - gctl_ro_param(grq, "verb", -1, "bootcode"); - gctl_ro_param(grq, "bootcode", mbr_size, mbr); - gctl_ro_param(grq, "flags", -1, "C"); - errmsg = gctl_issue(grq); - if (errmsg != NULL && errmsg[0] != '\0') - errx(1, "GEOM_PART: write bootcode to %s failed: %s", - fname, errmsg); - gctl_free(grq); - } else if (geom_class_available("MBR") != 0) { - grq = gctl_get_handle(); - gctl_ro_param(grq, "verb", -1, "write MBR"); - gctl_ro_param(grq, "class", -1, "MBR"); - gctl_ro_param(grq, "geom", -1, pname); - gctl_ro_param(grq, "data", mbr_size, mbr); - errmsg = gctl_issue(grq); - if (errmsg != NULL) - err(1, "GEOM_MBR: write MBR to %s failed", fname); - gctl_free(grq); - } else - errx(1, "can't write MBR to %s", fname); - free(pname); -} - -/* - * Outputs an informative dump of the data in the MBR to stdout. - */ -static void -display_mbr(u_int8_t *mbr) -{ - struct dos_partition *part; - int i, version; - - part = (struct dos_partition *)(mbr + DOSPARTOFF); - printf(fmt0); - for (i = 0; i < NDOSPART; i++) - if (part[i].dp_typ) - printf(fmt1, 1 + i, part[i].dp_flag, - part[i].dp_scyl + ((part[i].dp_ssect & 0xc0) << 2), - part[i].dp_shd, part[i].dp_ssect & 0x3f, part[i].dp_typ, - part[i].dp_ecyl + ((part[i].dp_esect & 0xc0) << 2), - part[i].dp_ehd, part[i].dp_esect & 0x3f, part[i].dp_start, - part[i].dp_size); - printf("\n"); - version = boot0version(mbr); - printf("version=%d.%d drive=0x%x mask=0x%x ticks=%u", - version >> 8, version & 0xff, mbr[OFF_DRIVE], - mbr[OFF_FLAGS] & 0xf, cv2(mbr + OFF_TICKS)); - set_bell(mbr, 0, 1); - printf("\noptions="); - for (i = 0; i < nopt; i++) { - if (i) - printf(","); - if (!(mbr[OFF_FLAGS] & 1 << (7 - i)) ^ opttbl[i].def) - printf("no"); - printf("%s", opttbl[i].tok); - } - printf("\n"); - if (b0_ver == 2) - printf("volume serial ID %02x%02x-%02x%02x\n", - mbr[OFF_SERIAL], mbr[OFF_SERIAL+1], - mbr[OFF_SERIAL+2], mbr[OFF_SERIAL+3]); - printf("default_selection=F%d (", mbr[OFF_OPT] + 1); - if (mbr[OFF_OPT] < 4) - printf("Slice %d", mbr[OFF_OPT] + 1); - else if (mbr[OFF_OPT] == 4) - printf("Drive 1"); - else - printf("PXE"); - printf(")\n"); -} - -/* - * Return the boot0 version with the minor revision in the low byte, and - * the major revision in the next higher byte. - */ -static int -boot0version(const u_int8_t *bs) -{ - /* Check for old version, and return 0x100 if found. */ - int v = boot0bs(bs); - if (v != 0) - return v << 8; - - /* We have a newer boot0, so extract the version number and return it. */ - return *(const int *)(bs + OFF_VERSION) & 0xffff; -} - -/* descriptor of a pattern to match. - * Start from the first entry trying to match the chunk of bytes, - * if you hit an entry with len=0 terminate the search and report - * off as the version. Otherwise skip to the next block after len=0 - * An entry with len=0, off=0 is the end marker. - */ -struct byte_pattern { - unsigned off; - unsigned len; - u_int8_t *key; -}; - -/* - * Decide if we have valid boot0 boot code by looking for - * characteristic byte sequences at fixed offsets. - */ -static int -boot0bs(const u_int8_t *bs) -{ - /* the initial code sequence */ - static u_int8_t id0[] = {0xfc, 0x31, 0xc0, 0x8e, 0xc0, 0x8e, 0xd8, - 0x8e, 0xd0, 0xbc, 0x00, 0x7c }; - /* the drive id */ - static u_int8_t id1[] = {'D', 'r', 'i', 'v', 'e', ' '}; - static struct byte_pattern patterns[] = { - {0x0, sizeof(id0), id0}, - {0x1b2, sizeof(id1), id1}, - {1, 0, NULL}, - {0x0, sizeof(id0), id0}, /* version with NT support */ - {0x1ae, sizeof(id1), id1}, - {2, 0, NULL}, - {0, 0, NULL}, - }; - struct byte_pattern *p = patterns; - - for (; p->off || p->len; p++) { - if (p->len == 0) - break; - if (!memcmp(bs + p->off, p->key, p->len)) /* match */ - continue; - while (p->len) /* skip to next block */ - p++; - } - b0_ver = p->off; /* XXX ugly side effect */ - return p->off; -} - -/* - * Adjust "and" and "or" masks for a -o option argument. - */ -static void -stropt(const char *arg, int *xa, int *xo) -{ - const char *q; - char *s, *s1; - int inv, i, x; - - if (!(s = strdup(arg))) - err(1, NULL); - for (s1 = s; (q = strtok(s1, ",")); s1 = NULL) { - if ((inv = !strncmp(q, "no", 2))) - q += 2; - for (i = 0; i < nopt; i++) - if (!strcmp(q, opttbl[i].tok)) - break; - if (i == nopt) - errx(1, "%s: Unknown -o option", q); - if (opttbl[i].def) - inv ^= 1; - x = 1 << (7 - i); - if (inv) - *xa &= ~x; - else - *xo |= x; - } - free(s); -} - -/* - * Convert and check an option argument. - */ -static int -argtoi(const char *arg, int lo, int hi, int opt) -{ - char *s; - long x; - - errno = 0; - x = strtol(arg, &s, 0); - if (errno || !*arg || *s || x < lo || x > hi) - errx(1, "%s: Bad argument to -%c option", arg, opt); - return x; -} - -/* - * Display usage information. - */ -static void -usage(void) -{ - fprintf(stderr, "%s\n%s\n", - "usage: boot0cfg [-Bv] [-b boot0] [-d drive] [-f file] [-m mask]", - " [-o options] [-s slice] [-t ticks] disk"); - exit(1); -} diff --git a/boot0cfg/GNUMakefile b/boot0cfg/GNUMakefile new file mode 100644 index 0000000..9272dec --- /dev/null +++ b/boot0cfg/GNUMakefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +all: boot0cfg + +clean: + rm -f *.o boot0cfg diff --git a/boot0cfg/boot0cfg.8 b/boot0cfg/boot0cfg.8 index 4d622a2..422f80d 100644 --- a/boot0cfg/boot0cfg.8 +++ b/boot0cfg/boot0cfg.8 @@ -85,9 +85,17 @@ Specify which .Sq boot0 image to use. The default is -.Pa /boot/boot0 -which will use the video card as output, alternatively -.Pa /boot/boot0sio +.Pa /usr/share/boot0/boot0lin +(this version does not support FAT partitions type in the sake of Linux SWAP, LVM, RAID and LBA extended partition type), +.Pa /usr/share/boot0/boot0 +is the original FreeBSD version, +.Pa /usr/share/boot0/boot0pxe +provides experimental PXE loader code. +.Pp +All theese +.Sq boot0 +variations will use the video card as output. Alternatively +.Pa /usr/share/boot0/boot0sio can be used for output to the COM1 port. (Be aware that nothing will be output to the COM1 port unless the modem signals DSR and CTS are active.) @@ -160,12 +168,18 @@ Set the timeout value to Verbose: display information about the slices defined, etc. .El .Sh FILES -.Bl -tag -width /boot/boot0sio -compact -.It Pa /boot/boot0 +.Bl -tag -width /usr/share/boot0/boot0sio -compact +.It Pa /usr/share/boot0/boot0lin The default .Sq boot0 image -.It Pa /boot/boot0sio +.It Pa /usr/share/boot0/boot0 +Unmodified FreeBSD +.Sq boot0 +variant +.It Pa /usr/share/boot0/boot0pxe +Experimental PXE bootloader +.It Pa /usr/share/boot0/boot0sio Image for serial consoles (COM1,9600,8,N,1,MODEM) .El .Sh EXIT STATUS diff --git a/boot0cfg/boot0cfg.c b/boot0cfg/boot0cfg.c index 2602e50..0eac86e 100644 --- a/boot0cfg/boot0cfg.c +++ b/boot0cfg/boot0cfg.c @@ -26,23 +26,47 @@ */ #include -__FBSDID("$FreeBSD$"); #include -#include -#include #include #include #include #include -#include #include #include #include #include #include +#define DOSBBSECTOR 0 /* DOS boot block relative sector number */ +#define DOSPARTOFF 446 +#define DOSPARTSIZE 16 +#define NDOSPART 4 +#define NEXTDOSPART 32 +#define DOSMAGICOFFSET 510 +#define DOSMAGIC 0xAA55 + +#define DOSPTYP_386BSD 0xa5 /* 386BSD partition type */ +#define DOSPTYP_LINSWP 0x82 /* Linux swap partition */ +#define DOSPTYP_LINUX 0x83 /* Linux partition */ +#define DOSPTYP_PMBR 0xee /* GPT Protective MBR */ +#define DOSPTYP_EXT 5 /* DOS extended partition */ +#define DOSPTYP_EXTLBA 15 /* DOS extended partition */ + +struct dos_partition { + unsigned char dp_flag; /* bootstrap flags */ + unsigned char dp_shd; /* starting head */ + unsigned char dp_ssect; /* starting sector */ + unsigned char dp_scyl; /* starting cylinder */ + unsigned char dp_typ; /* partition type */ + unsigned char dp_ehd; /* end head */ + unsigned char dp_esect; /* end sector */ + unsigned char dp_ecyl; /* end cylinder */ + u_int32_t dp_start; /* absolute starting sector number */ + u_int32_t dp_size; /* partition size in sectors */ +}; + #define MBRSIZE 512 /* master boot record size */ #define OFF_VERSION 0x1b0 /* offset: version number, only boot0version */ @@ -96,7 +120,9 @@ static const char fmt0[] = "# flag start chs type" static const char fmt1[] = "%d 0x%02x %4u:%3u:%2u 0x%02x" " %4u:%3u:%2u %10u %10u\n"; +#ifndef __linux__ static int geom_class_available(const char *); +#endif static int read_mbr(const char *, u_int8_t **, int); static void write_mbr(const char *, int, u_int8_t *, int); static void display_mbr(u_int8_t *); @@ -125,7 +151,7 @@ main(int argc, char *argv[]) int o_and, o_or, o_e = -1; int up, c; - bpath = "/boot/boot0"; + bpath = "/usr/share/boot0/boot0lin"; fpath = NULL; B_flag = v_flag = o_flag = 0; d_arg = m_arg = s_arg = t_arg = -1; @@ -184,7 +210,7 @@ main(int argc, char *argv[]) argv += optind; if (argc != 1) usage(); - disk = g_device_path(*argv); + disk = strdup(*argv); if (disk == NULL) errx(1, "Unable to get providername for %s\n", *argv); up = B_flag || d_arg != -1 || m_arg != -1 || o_flag || s_arg != -1 @@ -343,6 +369,7 @@ read_mbr(const char *disk, u_int8_t **mbr, int check_version) return sizeof(buf); } +#ifndef __linux__ static int geom_class_available(const char *name) { @@ -364,6 +391,7 @@ geom_class_available(const char *name) geom_deletetree(&mesh); return (0); } +#endif /* * Write out the mbr to the specified file. @@ -371,7 +399,9 @@ geom_class_available(const char *name) static void write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size) { +#ifndef __linux__ struct gctl_req *grq; +#endif const char *errmsg; char *pname; ssize_t n; @@ -386,6 +416,7 @@ write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size) return; } +#ifndef __linux__ /* * If we're called to write to a backup file, don't try to * write through GEOM. @@ -432,6 +463,7 @@ write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size) } else errx(1, "can't write MBR to %s", fname); free(pname); +#endif } /*