Deleted Added
full compact
boot0.S (185562) boot0.S (185579)
1/*
2 * Copyright (c) 2008 Luigi Rizzo (mostly documentation)
3 * Copyright (c) 2002 Bruce M. Simpson
4 * Copyright (c) 1998 Robert Nordier
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms are freely
8 * permitted provided that the above copyright notice and this
9 * paragraph and the following disclaimer are duplicated in all
10 * such forms.
11 *
12 * This software is provided "AS IS" and without any express or
13 * implied warranties, including, without limitation, the implied
14 * warranties of merchantability and fitness for a particular
15 * purpose.
16 *
1/*
2 * Copyright (c) 2008 Luigi Rizzo (mostly documentation)
3 * Copyright (c) 2002 Bruce M. Simpson
4 * Copyright (c) 1998 Robert Nordier
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms are freely
8 * permitted provided that the above copyright notice and this
9 * paragraph and the following disclaimer are duplicated in all
10 * such forms.
11 *
12 * This software is provided "AS IS" and without any express or
13 * implied warranties, including, without limitation, the implied
14 * warranties of merchantability and fitness for a particular
15 * purpose.
16 *
17 * $FreeBSD: head/sys/boot/i386/boot0/boot0.S 185562 2008-12-02 14:57:48Z luigi $
17 * $FreeBSD: head/sys/boot/i386/boot0/boot0.S 185579 2008-12-03 14:53:59Z luigi $
18 */
19
20/* build options: */
21#ifdef SIO /* use serial console on COM1. */
22#endif
23
24#ifdef PXE /* enable PXE/INT18 booting with F6 */
25#endif
26
27#ifdef CHECK_DRIVE /* make sure we boot from a HD. */
28#endif
29
30#ifdef ONLY_F_KEYS /* Only F1..F6, no digits on console */
31#endif
32
18 */
19
20/* build options: */
21#ifdef SIO /* use serial console on COM1. */
22#endif
23
24#ifdef PXE /* enable PXE/INT18 booting with F6 */
25#endif
26
27#ifdef CHECK_DRIVE /* make sure we boot from a HD. */
28#endif
29
30#ifdef ONLY_F_KEYS /* Only F1..F6, no digits on console */
31#endif
32
33#ifdef VOLUME_SERIAL /* support Volume serial number */
34#define B0_BASE 0x1ae /* move the internal data area */
35#define SAVE_MEMORY
36#else
37#define B0_BASE 0x1b2
38#endif
39
33#ifdef TEST /* enable some test code */
40#ifdef TEST /* enable some test code */
34#ifndef ONLY_F_KEYS
35#define ONLY_F_KEYS /* make room for the test code */
41#define SAVE_MEMORY
42#define SAVE_MORE_MEMORY
36#endif
43#endif
37#endif
38
39/*
40 * Note - this code uses many tricks to save space and fit in one sector.
41 * This includes using side effects of certain instructions, reusing
42 * register values from previous operations, etc.
43 * Be extremely careful when changing the code, even for simple things.
44 */
45

--- 67 unchanged lines hidden (view full) ---

113 *
114 * NHRDRV is the address in segment 0 where the BIOS writes the
115 * total number of hard disks in the system.
116 * LOAD is the original load address and cannot be changed.
117 * ORIGIN is the relocation address. If you change it, you also need
118 * to change the value passed to the linker in the Makefile
119 * PRT_OFF is the location of the partition table (from the MBR standard).
120 * B0_OFF is the location of the data area, known to boot0cfg so
44
45/*
46 * Note - this code uses many tricks to save space and fit in one sector.
47 * This includes using side effects of certain instructions, reusing
48 * register values from previous operations, etc.
49 * Be extremely careful when changing the code, even for simple things.
50 */
51

--- 67 unchanged lines hidden (view full) ---

119 *
120 * NHRDRV is the address in segment 0 where the BIOS writes the
121 * total number of hard disks in the system.
122 * LOAD is the original load address and cannot be changed.
123 * ORIGIN is the relocation address. If you change it, you also need
124 * to change the value passed to the linker in the Makefile
125 * PRT_OFF is the location of the partition table (from the MBR standard).
126 * B0_OFF is the location of the data area, known to boot0cfg so
121 * it cannot be changed.
127 * it cannot be changed. Computed as a negative offset from 0x200
122 * MAGIC is the signature of a boot block.
123 */
124
125 .set NHRDRV,0x475 # Number of hard drives
126 .set ORIGIN,0x600 # Execution address
127 .set LOAD,0x7c00 # Load address
128
129 .set PRT_OFF,0x1be # Partition table
128 * MAGIC is the signature of a boot block.
129 */
130
131 .set NHRDRV,0x475 # Number of hard drives
132 .set ORIGIN,0x600 # Execution address
133 .set LOAD,0x7c00 # Load address
134
135 .set PRT_OFF,0x1be # Partition table
130 .set B0_OFF,0x1b2 # Offset of boot0 data
136 .set B0_OFF,(B0_BASE-0x200) # Offset of boot0 data
131
132 .set MAGIC,0xaa55 # Magic: bootable
133
134 .set KEY_ENTER,0x1c # Enter key scan code
135 .set KEY_F1,0x3b # F1 key scan code
136 .set KEY_1,0x02 # #1 key scan code
137
138 .set ASCII_BEL,'#' # ASCII code for <BEL>
139 .set ASCII_CR,0x0D # ASCII code for <CR>
140
141/*
142 * Offsets of variables in the block at B0_OFF, and in the volatile
143 * data area, computed as displacement from %bp.
144 * We need to define them as constant as the assembler cannot
145 * compute them in its single pass.
146 */
137
138 .set MAGIC,0xaa55 # Magic: bootable
139
140 .set KEY_ENTER,0x1c # Enter key scan code
141 .set KEY_F1,0x3b # F1 key scan code
142 .set KEY_1,0x02 # #1 key scan code
143
144 .set ASCII_BEL,'#' # ASCII code for <BEL>
145 .set ASCII_CR,0x0D # ASCII code for <CR>
146
147/*
148 * Offsets of variables in the block at B0_OFF, and in the volatile
149 * data area, computed as displacement from %bp.
150 * We need to define them as constant as the assembler cannot
151 * compute them in its single pass.
152 */
147 .set _NXTDRV, -0x48 # Next drive
148 .set _OPT, -0x47 # Default option
149 .set _SETDRV, -0x46 # Drive to force
150 .set _FLAGS, -0x45 # Flags
153 .set _NXTDRV, B0_OFF+6 # Next drive
154 .set _OPT, B0_OFF+7 # Default option
155 .set _SETDRV, B0_OFF+8 # Drive to force
156 .set _FLAGS, B0_OFF+9 # Flags
151 .set SETDRV, 0x20 # the 'setdrv' flag
152 .set NOUPDATE, 0x40 # the 'noupdate' flag
153 .set USEPACKET, 0x80 # the 'packet' flag
157 .set SETDRV, 0x20 # the 'setdrv' flag
158 .set NOUPDATE, 0x40 # the 'noupdate' flag
159 .set USEPACKET, 0x80 # the 'packet' flag
154 .set _TICKS, -0x44 # Timeout ticks
155 .set _FAKE,0x0 # Fake partition table
160
161 /* ticks is at a fixed position */
162 .set _TICKS, (PRT_OFF - 0x200 - 2) # Timeout ticks
156 .set _MNUOPT, 0x10 # Saved menu entries
157
158 .set TLEN, (desc_ofs - bootable_ids) # size of bootable ids
159 .globl start # Entry point
160 .code16 # This runs in real mode
161
162/*
163 * MAIN ENTRY POINT

--- 91 unchanged lines hidden (view full) ---

255
256 /*
257 * Loop around on the partition table, printing values until we
258 * pass a 256 byte boundary.
259 */
260read_entry: movb %ch,-0x4(%bx) # Zero active flag (ch == 0)
261 btw %dx,_FLAGS(%bp) # Entry enabled?
262 jnc next_entry # No
163 .set _MNUOPT, 0x10 # Saved menu entries
164
165 .set TLEN, (desc_ofs - bootable_ids) # size of bootable ids
166 .globl start # Entry point
167 .code16 # This runs in real mode
168
169/*
170 * MAIN ENTRY POINT

--- 91 unchanged lines hidden (view full) ---

262
263 /*
264 * Loop around on the partition table, printing values until we
265 * pass a 256 byte boundary.
266 */
267read_entry: movb %ch,-0x4(%bx) # Zero active flag (ch == 0)
268 btw %dx,_FLAGS(%bp) # Entry enabled?
269 jnc next_entry # No
263 /*
264 * Lookup type in the 'non_bootable_ids' table, skip matching entries.
265 * This is implemented is by setting %di to the start of the
266 * exclude table, and %cl to the length of the table itself. After the
267 * 'repne scasb' the zero flag is set if we found a match.
268 * If not, %di points to the beginning of the 'valid' types,
269 * which is what we need for the next check.
270 */
271 movb (%bx),%al # Load type
270 movb (%bx),%al # Load type
272 movw $non_bootable_ids,%di # Lookup tables
273 movb $(bootable_ids-non_bootable_ids),%cl # length
274 repne # Exclude
275 scasb # partition?
276 je next_entry # Yes, ignore it
271 test %al, %al # skip empty partition
272 jz next_entry
277 /*
273 /*
278 * Now scan the table of bootable ids, which starts at %di and has
274 * Scan the table of bootable ids, which starts at %di and has
279 * length TLEN. On a match, %di points to the element following the
280 * match; the corresponding offset to the description is $(TLEN-1)
281 * bytes ahead. If we don't find a match, we hit the 'unknown' entry.
282 */
275 * length TLEN. On a match, %di points to the element following the
276 * match; the corresponding offset to the description is $(TLEN-1)
277 * bytes ahead. If we don't find a match, we hit the 'unknown' entry.
278 */
279 movw $bootable_ids,%di # Lookup tables
283 movb $(TLEN),%cl # Number of entries
284 repne # Locate
285 scasb # type
286 /*
287 * Get the matching element in the next array.
288 * The byte at $(TLEN-1)(%di) contains the offset of the description
289 * string from %di, so we add the number and print the string.
290 */

--- 204 unchanged lines hidden (view full) ---

495 jmp *%bx # Invoke bootstrap
496
497/*
498 * Display routines
499 * putkey prints the option selected in %dl (F1..F5 or 1..5) followed by
500 * the string at %si
501 * putx: print the option in %dl followed by the string at %di
502 * also record the drive as valid.
280 movb $(TLEN),%cl # Number of entries
281 repne # Locate
282 scasb # type
283 /*
284 * Get the matching element in the next array.
285 * The byte at $(TLEN-1)(%di) contains the offset of the description
286 * string from %di, so we add the number and print the string.
287 */

--- 204 unchanged lines hidden (view full) ---

492 jmp *%bx # Invoke bootstrap
493
494/*
495 * Display routines
496 * putkey prints the option selected in %dl (F1..F5 or 1..5) followed by
497 * the string at %si
498 * putx: print the option in %dl followed by the string at %di
499 * also record the drive as valid.
503 * puts: print the string at %si followed by a crlf
504 * putn: print a crlf
505 * putstr: print the string at %si
506 * putchr: print the char in al
507 */
500 * putn: print a crlf
501 * putstr: print the string at %si
502 * putchr: print the char in al
503 */
508putkey:
509#ifndef SIO
510 movb $'F',%al # Display
511 callw putchr # 'F'
512#endif
513 movb $'1',%al # Prepare
514 addb %dl,%al # digit
515 jmp putstr.1 # Display the rest
516
517/*
518 * Display the option and record the drive as valid in the options.
519 * That last point is done using the btsw instruction which does
520 * a test and set. We don't care for the test part.
521 */
522putx: btsw %dx,_MNUOPT(%bp) # Enable menu option
523 movw $item,%si # Display
524 callw putkey # key
525 movw %di,%si # Display the rest
504
505/*
506 * Display the option and record the drive as valid in the options.
507 * That last point is done using the btsw instruction which does
508 * a test and set. We don't care for the test part.
509 */
510putx: btsw %dx,_MNUOPT(%bp) # Enable menu option
511 movw $item,%si # Display
512 callw putkey # key
513 movw %di,%si # Display the rest
514 callw putstr # Display string
526
515
527puts: callw putstr # Display string
528
529putn: movw $crlf,%si # To next line
516putn: movw $crlf,%si # To next line
517 jmp putstr
530
518
519putkey:
520#ifndef SIO
521 movb $'F',%al # Display
522 callw putchr # 'F'
523#endif
524 movb $'1',%al # Prepare
525 addb %dl,%al # digit
526
527putstr.1: callw putchr # Display char
531putstr: lodsb # Get byte
532 testb $0x80,%al # End of string?
528putstr: lodsb # Get byte
529 testb $0x80,%al # End of string?
533 jnz putstr.2 # Yes
534putstr.1: callw putchr # Display char
535 jmp putstr # Continue
536putstr.2: andb $~0x80,%al # Clear MSB
530 jz putstr.1 # No
531 andb $~0x80,%al # Clear MSB then print last
537
538putchr:
539#ifndef SIO
540 pushw %bx # Save
541 movw $0x7,%bx # Page:attribute
542 movb $0xe,%ah # BIOS: Display
543 int $0x10 # character
544 popw %bx # Restore

--- 51 unchanged lines hidden (view full) ---

596#else
597prompt: .ascii "\nDefault:"
598item: .ascii " "; .byte ' '|0x80
599#endif
600crlf: .ascii "\r"; .byte '\n'|0x80
601
602/* Partition type tables */
603
532
533putchr:
534#ifndef SIO
535 pushw %bx # Save
536 movw $0x7,%bx # Page:attribute
537 movb $0xe,%ah # BIOS: Display
538 int $0x10 # character
539 popw %bx # Restore

--- 51 unchanged lines hidden (view full) ---

591#else
592prompt: .ascii "\nDefault:"
593item: .ascii " "; .byte ' '|0x80
594#endif
595crlf: .ascii "\r"; .byte '\n'|0x80
596
597/* Partition type tables */
598
604non_bootable_ids:
605 /*
606 * These entries identify invalid or NON BOOT types and partitions.
607 * 0: empty, 5: DOS3 ext. partition, 0xf: WIN95 ext partition
608 */
609 .byte 0x0, 0x5, 0xf
610bootable_ids:
611 /*
599bootable_ids:
600 /*
612 * These values indicate bootable types we know the names of.
613 * 1: FAT12, 4: FAT16 <32M, 6: FAT16 > 32M, 7: NTFS
614 * 0xb: FAT32, 0xc: FAT32-LBA, 0xe: FAT16-LBA,
615 * 0x83: linux, 0xa5: FreeBSD, 0xa6: netbsd, 0xa9:openbsd
601 * These values indicate bootable types we know about.
602 * Corresponding descriptions are at desc_ofs:
603 * Entries don't need to be sorted.
616 */
604 */
617 .byte 0x1, 0x6, 0x7, 0xb, 0xc, 0xe, 0x83
618 .byte 0xa5, 0xa6, 0xa9, 0x4
605 .byte 0x1, 0x6, 0x7, 0xb, 0xc
606#ifndef SAVE_MEMORY
607 .byte 0xe
608#endif
609 .byte 0x83, 0xa5, 0xa6, 0xa9, 0x4
610#ifndef SAVE_MORE_MEMORY
611 .byte 0x5, 0xf
612#endif
613
619desc_ofs:
620 /*
621 * Offsets that match the known types above, used to point to the
622 * actual partition name. The last entry must point to os_misc,
623 * which is used for non-matching names.
624 */
614desc_ofs:
615 /*
616 * Offsets that match the known types above, used to point to the
617 * actual partition name. The last entry must point to os_misc,
618 * which is used for non-matching names.
619 */
625 .byte os_dos-. # 1, DOS
626 .byte os_dos-. # 6, DOS/WIN
627 .byte os_win-. # 7, Windows
628 .byte os_win-. # 11, Windows
629 .byte os_win-. # 12, Windows
630 .byte os_win-. # 14, Windows
620 .byte os_dos-. # 1, FAT12 DOS
621 .byte os_dos-. # 6, FAT16 <32M, DOS/WIN
622 .byte os_win-. # 7, FAT16 >=32M Windows
623 .byte os_win-. # 11, FAT32
624 .byte os_win-. # 12, FAT32-LBA
625#ifndef SAVE_MEMORY
626 .byte os_win-. # 14, FAT16-LBA
627#endif
631 .byte os_linux-. # 131, Linux
632 .byte os_freebsd-. # 165, FreeBSD
633 .byte os_bsd-. # 166, OpenBSD
634 .byte os_bsd-. # 169, NetBSD
628 .byte os_linux-. # 131, Linux
629 .byte os_freebsd-. # 165, FreeBSD
630 .byte os_bsd-. # 166, OpenBSD
631 .byte os_bsd-. # 169, NetBSD
635 .byte os_dos-. # 4, DOS
632 .byte os_dos-. # 4, FAT16 < 32M
633#ifndef SAVE_MORE_MEMORY
634 .byte os_ext-. # 5, DOS Ext
635 .byte os_ext-. # 15, DOS Ext-LBA
636#endif
637
636 .byte os_misc-. # Unknown
637
638 /*
639 * And here are the strings themselves. The last byte of
640 * the string has bit 7 set.
641 */
642os_misc: .byte '?'|0x80
643os_dos:
638 .byte os_misc-. # Unknown
639
640 /*
641 * And here are the strings themselves. The last byte of
642 * the string has bit 7 set.
643 */
644os_misc: .byte '?'|0x80
645os_dos:
644#if !defined(TEST) /* DOS string only if room */
646#ifndef SAVE_MEMORY /* DOS string only if room */
645 .ascii "DO"; .byte 'S'|0x80
646#endif
647os_win: .ascii "WI"; .byte 'N'|0x80
648os_linux: .ascii "Linu"; .byte 'x'|0x80
649os_freebsd: .ascii "Free"
650os_bsd: .ascii "BS"; .byte 'D'|0x80
647 .ascii "DO"; .byte 'S'|0x80
648#endif
649os_win: .ascii "WI"; .byte 'N'|0x80
650os_linux: .ascii "Linu"; .byte 'x'|0x80
651os_freebsd: .ascii "Free"
652os_bsd: .ascii "BS"; .byte 'D'|0x80
653#ifndef SAVE_MORE_MEMORY
654os_ext: .ascii "EX"; .byte 'T'|0x80
655#endif
651
656
652 .org B0_OFF,0x90
657 .org (0x200 + B0_OFF),0x90
653/*
654 * The boot0 version 1.0 parameter table.
655 * Do not move it nor change the "Drive " string, boot0cfg
656 * uses its offset and content to identify the boot sector.
657 * The other fields are sometimes changed before writing back to the drive
658 * Be especially careful that nxtdrv: must come after drive:, as it
659 * is part of the same string.
660 */
661drive: .ascii "Drive "
662nxtdrv: .byte 0x0 # Next drive number
663opt: .byte 0x0 # Option
664setdrv_num: .byte 0x80 # Drive to force
665flags: .byte FLAGS # Flags
658/*
659 * The boot0 version 1.0 parameter table.
660 * Do not move it nor change the "Drive " string, boot0cfg
661 * uses its offset and content to identify the boot sector.
662 * The other fields are sometimes changed before writing back to the drive
663 * Be especially careful that nxtdrv: must come after drive:, as it
664 * is part of the same string.
665 */
666drive: .ascii "Drive "
667nxtdrv: .byte 0x0 # Next drive number
668opt: .byte 0x0 # Option
669setdrv_num: .byte 0x80 # Drive to force
670flags: .byte FLAGS # Flags
671#ifdef VOLUME_SERIAL
672 .byte 0xa8,0xa8,0xa8,0xa8 # Volume Serial Number
673#endif
666ticks: .word TICKS # Delay
667
668 .org PRT_OFF
669/*
670 * Here is the 64 byte partition table that fdisk would fiddle with.
671 */
672partbl: .fill 0x40,0x1,0x0 # Partition table
673 .word MAGIC # Magic number
674 .org 0x200 # again, safety check
675endblock:
674ticks: .word TICKS # Delay
675
676 .org PRT_OFF
677/*
678 * Here is the 64 byte partition table that fdisk would fiddle with.
679 */
680partbl: .fill 0x40,0x1,0x0 # Partition table
681 .word MAGIC # Magic number
682 .org 0x200 # again, safety check
683endblock: