From 4b1d510b9bfb088c142ee129d31764a73ceb1fd0 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sun, 8 Jun 2003 11:05:06 +0000 Subject: initial import --- Boot.asm | 296 +++++++++++++++++++++++++++++++++++++++++++ Boot.bin | Bin 0 -> 512 bytes Boot.lst | 414 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Bootinst.c | 256 +++++++++++++++++++++++++++++++++++++ Compile.bat | 8 ++ Readme | 57 +++++++++ 6 files changed, 1031 insertions(+) create mode 100644 Boot.asm create mode 100644 Boot.bin create mode 100644 Boot.lst create mode 100644 Bootinst.c create mode 100644 Compile.bat create mode 100644 Readme diff --git a/Boot.asm b/Boot.asm new file mode 100644 index 0000000..1f3465e --- /dev/null +++ b/Boot.asm @@ -0,0 +1,296 @@ +; BOOTEASY, version 1.7. +; Developed from BOOTANY, with many improvements. +; The main idea was to simplify the installation +; procedure and to remove unnecessary partition type switching. +; Second hard disk switching added. +; Author: Serge Vakulenko, + +F1_scancode equ 59 ; scancode of 'F1' key +Enter_scancode equ 28 ; scancode of 'Enter' key +Timeout equ 5 ; wait up to 5 seconds for reply + +StdBase equ 7c00h ; address where DOS loads us +Base equ 600h ; address where we rewrite itself +Partab equ 1beh ; partition table offset +NumDisks equ 475h ; number of disk drives (BIOS data area) + +BootIndicator equ 0 ; partition record: boot indicator +BeginHead equ 1 ; first partition sector: head number +BeginSector equ 2 ; sector and cylinder +SystemId equ 4 ; system type + +; ------------------------------- + +dummy segment at 0 + assume cs:dummy + org Base ; address where we rewrite itself +BaseEntry: + org StdBase ; address where DOS loads us +StdBaseEntry: +dummy ends + +; ------------------------------- + +code segment + assume cs:code, ds:code, es:code, ss:code + org 0 +Boot: +; +; Setup the stack and segment registers +; + xor AX,AX ; Zero register + mov ES,AX ; ES := 0 + mov DS,AX ; DS := 0 + mov SS,AX ; disables intrs up to the next command + mov SP,StdBase ; SP at 7c00 +; +; DOS loads this pgm at 0000:7C00. Any boot routine +; we call also expects to execute there so the first +; exercise is to move this code somewhere else. +; + cld ; Clear direction + mov SI,SP ; Copy from 7c00h... + mov DI,Base ; ...to 600h... + mov CX,256 ; ...512 bytes, or 256 words + repne movsw ; Move itself to new location + + jmp FAR PTR BaseEntry+(Entry-Boot) + +; ------------------------------- +; +; A valid function key was depressed (or defaulted) +; Attempt to boot the corresponding partition. +; +Load: + mov DX,BP ; restore drive number + pop AX ; key '1'..'5' + mov Base+default,AL ; save function key number + cmp AL,'5' + je SwitchDrive + mov AH,16 + mul AH ; AX = key * 16 + add AX,Base+Partab-'1'*16 ; subtract '1' + mov SI,AX +; +; Check if the partition is empty. +; + cmp BYTE PTR SystemId[SI],0 + je Menu ; Empty - display menu again + cmp BYTE PTR SystemId[SI],05h + je Menu ; DOS extended type - never load + + mov BYTE PTR BootIndicator[SI],80h ; Mark partition as bootable + call SaveBoot +; +; Read in and validate the partition's boot sector. +; + mov DH,BeginHead[SI] ; head from partition table + mov CX,BeginSector[SI] + jmp loadboot +; +; Read in the boot sector from second disk. +; +SwitchDrive: + call SaveBoot + mov CX,0001h ; cylinder 0, sector 1 + xor DL,CL ; (DL ^= 1) switch drive +loadboot: + mov BX,StdBase ; ES already == 0 + mov AX,0201h ; function, # of sectors + int 13h ; read system boot record + jc Menu ; exit if error + cmp WORD PTR 510[BX],0aa55h ; test signature + jne Menu ; reprompt if invalid +; +; Jump to secondary boot. +; DL now contains boot disk number (80h or 81h); +; ES:SI contains the address of partition table +; entry to boot. +; + jmp FAR PTR StdBaseEntry + +; ------------------------------- +; +; The main entry to the boot +; +Entry: + cmp DL,81h ; DL contains current drive number + je driveok ; is it valid? + mov DL,80h ; no - use the default value +driveok: mov BP,DX ; save the drive number + inc DX ; 80h -> 81h, 81h -> 82h + xor DL,80h+'3' ; 80h -> '2', 81h -> '1' + mov Base+diskNum,DL +; +; Display the menu +; +Menu: + mov DI,Base+Partab ; set index + mov CX,4 ; set loop count + mov Base+key,'1' ; set key number in message + xor DH,DH ; count of partitions +menuloop: + mov BYTE PTR BootIndicator[DI],CH ; Clear active flag + mov AL,SystemId[DI] + cmp AL,0 ; unused partition? + je next + cmp AL,5 ; extended DOS partition? + je next + inc DH ; increment partition count + + lea SI,Base+FkeyMsg ; get msg addr + call Output + + lea SI,Base+nameTable-2 +nameloop: + inc SI + inc SI + mov BX,[SI] + or BH,BH + je endnameloop + xor BH,SystemId[DI] + jne nameloop +endnameloop: + lea SI,Base+namtab[BX] + call Output +next: + add DI,16 ; next entry address + inc Base+key + loop menuloop + + cmp BYTE PTR DS:NumDisks,2 ; is the second disk present? + je have2disks ; have disk 2 + + lea SI,Base+defaultMsg ; prepare 'Default' message + or DH,DH ; no disk 2; do we have valid partitions? + jne prompt ; several partitions, wait for reply + + int 18h ; no partitions, load ROM basic + jmp Menu ; repeat, if no ROM basic +have2disks: + lea SI,Base+FkeyMsg ; print 'F5' + call Output ; now SI points to "disk 2\nDefault..." +prompt: + call Output ; print 'Default' message +reprompt: + xor AH,AH ; GetTickCount + int 1ah ; BiosTimerService + mov BX,DX ; lo-order tick count + add BX,192*Timeout/10 ; timeout value in ticks +; +; Get the reply +; +waitkey: + mov AH,1 ; keyboard status + int 16h ; keybd bios service + mov AH,0 ; GetTickCount + jnz reply ; jump if reply + int 1ah ; BiosTimerService + cmp DX,BX ; check for timeout + jb waitkey ; wait for scancode +loaddefault: + mov AL,Base+default ; prior system id + jmp testkey ; boot default system +reply: + int 16h ; AH=0, keybd bios service + mov AL,AH ; Copy to AL + cmp AL,Enter_scancode + je loaddefault + add AL,'1'-F1_scancode ; Turn into index +testkey: + cmp AL,'1' ; max Function key + jb reprompt ; Invalid code check + cmp AL,'5' ; max Function key + jnbe reprompt ; if not F1..F5, branch + push AX + + lea SI,Base+newLine ; new line + lea BX,Base+Load + push BX ; call Output; jmp Load + +; ------------------------------- +; +; Output line [SI] to screen, end of line marked with 80h +; +Output: + cld ; reset direction flag + lodsb ; load argument from string + push AX ; save byte + and AL,7fh ; insure valid character + mov AH,14 ; write tty + int 10h ; bios video service + pop AX ; restore byte + test AL,80h ; test for end of string + jz Output ; do until end of string + ret ; return to caller + +; ------------------------------- +; +; Save boot block default partition settings +; +SaveBoot: + push SI + mov AX,0301h ; write sector + mov BX,Base ; ES already == 0 + mov CX,0001h ; cylinder 0, sector 1 + xor DH,DH ; drive #, head 0 + int 13h ; replace boot record + pop SI + mov Base+default,'?' ; reset default + ret + +; ------------------------------- + +newLine db 13,10+80h +FkeyMsg db 13,10,'F' +key db '0 . . .',' '+80h,'disk ' +diskNum db '1' +defaultMsg db 13,10,10,'Default: F' +default db '?',' '+80h + +nameTable db dos -namtab, 1 + db dos -namtab, 4 + db dos -namtab, 6 + db hpfs -namtab, 7 + db os2 -namtab, 0Ah + db unix -namtab, 63h + db novell -namtab, 64h + db novell -namtab, 65h + db minix -namtab, 80h + db linux -namtab, 81h + db linux -namtab, 82h + db linux -namtab, 83h + db amoeba -namtab, 93h + db freebsd -namtab, 0A5h + db bsdi -namtab, 9fh + db pcix -namtab, 75h + db cpm -namtab, 52h + db cpm -namtab, 0dbh + db venix -namtab, 40h + db dossec -namtab, 0F2h + db noname -namtab, 0 + +namtab: +dos db 'Do','s'+80h +hpfs db 'Hpf','s'+80h +os2 db 'Os','2'+80h +unix db 'Uni','x'+80h +novell db 'Novel','l'+80h +minix db 'Mini','x'+80h +linux db 'Linu','x'+80h +amoeba db 'Amoeb','a'+80h +freebsd db 'FreeBS','D'+80h +bsdi db 'BSD','i'+80h +pcix db 'Pci','x'+80h +cpm db 'Cp','m'+80h +venix db 'Veni','x'+80h +dossec db 'Dosse','c'+80h +noname db '?','?'+80h + +used equ $ - Boot + db (1beh - used + 1) dup (0) ; error if code too big + db 63 dup (0) ; clear rest of record + dw 0aa55h ; magic + +code ends + end diff --git a/Boot.bin b/Boot.bin new file mode 100644 index 0000000..ec56052 Binary files /dev/null and b/Boot.bin differ diff --git a/Boot.lst b/Boot.lst new file mode 100644 index 0000000..a10c7b3 --- /dev/null +++ b/Boot.lst @@ -0,0 +1,414 @@ +Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 1 +boot.ASM + + + + 1 ; BOOTEASY, version 1.7. + 2 ; Developed from BOOTANY, with many improvements. + 3 ; The main idea was to simplify the installation + 4 ; procedure and to remove unnecessary partition type switching. + 5 ; Second hard disk switching added. + 6 ; Author: Serge Vakulenko, + 7 + 8 =003B F1_scancode equ 59 ; scancode of 'F1' key + 9 =001C Enter_scancode equ 28 ; scancode of 'Enter' key + 10 =0005 Timeout equ 5 ; wait up to 5 seconds for reply + 11 + 12 =7C00 StdBase equ 7c00h ; address where DOS loads us + 13 =0600 Base equ 600h ; address where we rewrite itself + 14 =01BE Partab equ 1beh ; partition table offset + 15 =0475 NumDisks equ 475h ; number of disk drives (BIOS data area) + 16 + 17 =0000 BootIndicator equ 0 ; partition record: boot indicator + 18 =0001 BeginHead equ 1 ; first partition sector: head number + 19 =0002 BeginSector equ 2 ; sector and cylinder + 20 =0004 SystemId equ 4 ; system type + 21 + 22 ; ------------------------------- + 23 + 24 0000 dummy segment at 0 + 25 assume cs:dummy + 26 org Base ; address where we rewrite itself + 27 0600 BaseEntry: + 28 org StdBase ; address where DOS loads us + 29 7C00 StdBaseEntry: + 30 7C00 dummy ends + 31 + 32 ; ------------------------------- + 33 + 34 0000 code segment + 35 assume cs:code, ds:code, es:code, ss:code + 36 org 0 + 37 0000 Boot: + 38 ; + 39 ; Setup the stack and segment registers + 40 ; + 41 0000 33 C0 xor AX,AX ; Zero register + 42 0002 8E C0 mov ES,AX ; ES := 0 + 43 0004 8E D8 mov DS,AX ; DS := 0 + 44 0006 8E D0 mov SS,AX ; disables intrs up to the next command + 45 0008 BC 7C00 mov SP,StdBase ; SP at 7c00 + 46 ; + 47 ; DOS loads this pgm at 0000:7C00. Any boot routine + 48 ; we call also expects to execute there so the first + 49 ; exercise is to move this code somewhere else. + 50 ; + 51 000B FC cld ; Clear direction + 52 000C 8B F4 mov SI,SP ; Copy from 7c00h... + 53 000E BF 0600 mov DI,Base ; ...to 600h... + 54 0011 B9 0100 mov CX,256 ; ...512 bytes, or 256 words + 55 0014 F2> A5 repne movsw ; Move itself to new location + 56 + 57 0016 EA 00000667sr jmp FAR PTR BaseEntry+(Entry-Boot) + Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 2 +boot.ASM + + + + 58 + 59 ; ------------------------------- + 60 ; + 61 ; A valid function key was depressed (or defaulted) + 62 ; Attempt to boot the corresponding partition. + 63 ; + 64 001B Load: + 65 001B 8B D5 mov DX,BP ; restore drive number + 66 001D 58 pop AX ; key '1'..'5' + 67 001E A2 074Fr mov Base+default,AL ; save function key number + 68 0021 3C 35 cmp AL,'5' + 69 0023 74 23 je SwitchDrive + 70 0025 B4 10 mov AH,16 + 71 0027 F6 E4 mul AH ; AX = key * 16 + 72 0029 05 04AE add AX,Base+Partab-'1'*16 ; subtract '1' + 73 002C 8B F0 mov SI,AX + 74 ; + 75 ; Check if the partition is empty. + 76 ; + 77 002E 80 7C 04 00 cmp BYTE PTR SystemId[SI],0 + 78 0032 74 44 je Menu ; Empty - display menu again + 79 0034 80 7C 04 05 cmp BYTE PTR SystemId[SI],05h + 80 0038 74 3E je Menu ; DOS extended type - never load + 81 + 82 003A C6 04 80 mov BYTE PTR BootIndicator[SI],80h ; Mark partition as bootable + 83 003D E8 00DA call SaveBoot + 84 ; + 85 ; Read in and validate the partition's boot sector. + 86 ; + 87 0040 8A 74 01 mov DH,BeginHead[SI] ; head from partition table + 88 0043 8B 4C 02 mov CX,BeginSector[SI] + 89 0046 EB 08 jmp loadboot + 90 ; + 91 ; Read in the boot sector from second disk. + 92 ; + 93 0048 SwitchDrive: + 94 0048 E8 00CF call SaveBoot + 95 004B B9 0001 mov CX,0001h ; cylinder 0, sector 1 + 96 004E 32 D1 xor DL,CL ; (DL ^= 1) switch drive + 97 0050 loadboot: + 98 0050 BB 7C00 mov BX,StdBase ; ES already == 0 + 99 0053 B8 0201 mov AX,0201h ; function, # of sectors + 100 0056 CD 13 int 13h ; read system boot record + 101 0058 72 1E jc Menu ; exit if error + 102 005A 81 BF 01FE AA55 cmp WORD PTR 510[BX],0aa55h ; test signature + 103 0060 75 16 jne Menu ; reprompt if invalid + 104 ; + 105 ; Jump to secondary boot. + 106 ; DL now contains boot disk number (80h or 81h); + 107 ; ES:SI contains the address of partition table + 108 ; entry to boot. + 109 ; + 110 0062 EA 00007C00sr jmp FAR PTR StdBaseEntry + 111 + 112 ; ------------------------------- + 113 ; + 114 ; The main entry to the boot + Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 3 +boot.ASM + + + + 115 ; + 116 0067 Entry: + 117 0067 80 FA 81 cmp DL,81h ; DL contains current drive number + 118 006A 74 02 je driveok ; is it valid? + 119 006C B2 80 mov DL,80h ; no - use the default value + 120 006E 8B EA driveok: mov BP,DX ; save the drive number + 121 0070 42 inc DX ; 80h -> 81h, 81h -> 82h + 122 0071 80 F2 B3 xor DL,80h+'3' ; 80h -> '2', 81h -> '1' + 123 0074 88 16 0741r mov Base+diskNum,DL + 124 ; + 125 ; Display the menu + 126 ; + 127 0078 Menu: + 128 0078 BF 07BE mov DI,Base+Partab ; set index + 129 007B B9 0004 mov CX,4 ; set loop count + 130 007E C6 06 0734r 31 mov Base+key,'1' ; set key number in message + 131 0083 32 F6 xor DH,DH ; count of partitions + 132 0085 menuloop: + 133 0085 88 2D mov BYTE PTR BootIndicator[DI],CH ; Clear active flag + 134 0087 8A 45 04 mov AL,SystemId[DI] + 135 008A 3C 00 cmp AL,0 ; unused partition? + 136 008C 74 23 je next + 137 008E 3C 05 cmp AL,5 ; extended DOS partition? + 138 0090 74 1F je next + 139 0092 FE C6 inc DH ; increment partition count + 140 + 141 0094 BE 0731r lea SI,Base+FkeyMsg ; get msg addr + 142 0097 E8 0071 call Output + 143 + 144 009A BE 074Fr lea SI,Base+nameTable-2 + 145 009D nameloop: + 146 009D 46 inc SI + 147 009E 46 inc SI + 148 009F 8B 1C mov BX,[SI] + 149 00A1 0A FF or BH,BH + 150 00A3 74 05 je endnameloop + 151 00A5 32 7D 04 xor BH,SystemId[DI] + 152 00A8 75 F3 jne nameloop + 153 00AA endnameloop: + 154 00AA 8D B7 077Br lea SI,Base+namtab[BX] + 155 00AE E8 005A call Output + 156 00B1 next: + 157 00B1 83 C7 10 add DI,16 ; next entry address + 158 00B4 FE 06 0734r inc Base+key + 159 00B8 E2 CB loop menuloop + 160 + 161 00BA 80 3E 0475 02 cmp BYTE PTR DS:NumDisks,2 ; is the second disk present? + 162 00BF 74 0B je have2disks ; have disk 2 + 163 + 164 00C1 BE 0742r lea SI,Base+defaultMsg ; prepare 'Default' message + 165 00C4 0A F6 or DH,DH ; no disk 2; do we have valid partitions? + 166 00C6 75 0A jne prompt ; several partitions, wait for reply + 167 + 168 00C8 CD 18 int 18h ; no partitions, load ROM basic + 169 00CA EB AC jmp Menu ; repeat, if no ROM basic + 170 00CC have2disks: + 171 00CC BE 0731r lea SI,Base+FkeyMsg ; print 'F5' + Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 4 +boot.ASM + + + + 172 00CF E8 0039 call Output ; now SI points to "disk 2\nDefault..." + 173 00D2 prompt: + 174 00D2 E8 0036 call Output ; print 'Default' message + 175 00D5 reprompt: + 176 00D5 32 E4 xor AH,AH ; GetTickCount + 177 00D7 CD 1A int 1ah ; BiosTimerService + 178 00D9 8B DA mov BX,DX ; lo-order tick count + 179 00DB 83 C3 60 add BX,192*Timeout/10 ; timeout value in ticks + 180 ; + 181 ; Get the reply + 182 ; + 183 00DE waitkey: + 184 00DE B4 01 mov AH,1 ; keyboard status + 185 00E0 CD 16 int 16h ; keybd bios service + 186 00E2 B4 00 mov AH,0 ; GetTickCount + 187 00E4 75 0B jnz reply ; jump if reply + 188 00E6 CD 1A int 1ah ; BiosTimerService + 189 00E8 3B D3 cmp DX,BX ; check for timeout + 190 00EA 72 F2 jb waitkey ; wait for scancode + 191 00EC loaddefault: + 192 00EC A0 074Fr mov AL,Base+default ; prior system id + 193 00EF EB 0A jmp testkey ; boot default system + 194 00F1 reply: + 195 00F1 CD 16 int 16h ; AH=0, keybd bios service + 196 00F3 8A C4 mov AL,AH ; Copy to AL + 197 00F5 3C 1C cmp AL,Enter_scancode + 198 00F7 74 F3 je loaddefault + 199 00F9 04 F6 add AL,'1'-F1_scancode ; Turn into index + 200 00FB testkey: + 201 00FB 3C 31 cmp AL,'1' ; max Function key + 202 00FD 72 D6 jb reprompt ; Invalid code check + 203 00FF 3C 35 cmp AL,'5' ; max Function key + 204 0101 77 D2 jnbe reprompt ; if not F1..F5, branch + 205 0103 50 push AX + 206 + 207 0104 BE 072Fr lea SI,Base+newLine ; new line + 208 0107 BB 061Br lea BX,Base+Load + 209 010A 53 push BX ; call Output; jmp Load + 210 + 211 ; ------------------------------- + 212 ; + 213 ; Output line [SI] to screen, end of line marked with 80h + 214 ; + 215 010B Output: + 216 010B FC cld ; reset direction flag + 217 010C AC lodsb ; load argument from string + 218 010D 50 push AX ; save byte + 219 010E 24 7F and AL,7fh ; insure valid character + 220 0110 B4 0E mov AH,14 ; write tty + 221 0112 CD 10 int 10h ; bios video service + 222 0114 58 pop AX ; restore byte + 223 0115 A8 80 test AL,80h ; test for end of string + 224 0117 74 F2 jz Output ; do until end of string + 225 0119 C3 ret ; return to caller + 226 + 227 ; ------------------------------- + 228 ; + Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 5 +boot.ASM + + + + 229 ; Save boot block default partition settings + 230 ; + 231 011A SaveBoot: + 232 011A 56 push SI + 233 011B B8 0301 mov AX,0301h ; write sector + 234 011E BB 0600 mov BX,Base ; ES already == 0 + 235 0121 B9 0001 mov CX,0001h ; cylinder 0, sector 1 + 236 0124 32 F6 xor DH,DH ; drive #, head 0 + 237 0126 CD 13 int 13h ; replace boot record + 238 0128 5E pop SI + 239 0129 C6 06 074Fr 3F mov Base+default,'?' ; reset default + 240 012E C3 ret + 241 + 242 ; ------------------------------- + 243 + 244 012F 0D 8A newLine db 13,10+80h + 245 0131 0D 0A 46 FkeyMsg db 13,10,'F' + 246 0134 30 20 2E 20 2E 20 2E+ key db '0 . . .',' '+80h,'disk ' + 247 A0 64 69 73 6B 20 + 248 0141 31 diskNum db '1' + 249 0142 0D 0A 0A 44 65 66 61+ defaultMsg db 13,10,10,'Default: F' + 250 75 6C 74 3A 20 46 + 251 014F 3F A0 default db '?',' '+80h + 252 + 253 0151 00 01 nameTable db dos -namtab, 1 + 254 0153 00 04 db dos -namtab, 4 + 255 0155 00 06 db dos -namtab, 6 + 256 0157 03 07 db hpfs -namtab, 7 + 257 0159 07 0A db os2 -namtab, 0Ah + 258 015B 0A 63 db unix -namtab, 63h + 259 015D 0E 64 db novell -namtab, 64h + 260 015F 0E 65 db novell -namtab, 65h + 261 0161 14 80 db minix -namtab, 80h + 262 0163 19 81 db linux -namtab, 81h + 263 0165 19 82 db linux -namtab, 82h + 264 0167 19 83 db linux -namtab, 83h + 265 0169 1E 93 db amoeba -namtab, 93h + 266 016B 24 A5 db freebsd -namtab, 0A5h + 267 016D 2B 9F db bsdi -namtab, 9fh + 268 016F 2F 75 db pcix -namtab, 75h + 269 0171 33 52 db cpm -namtab, 52h + 270 0173 33 DB db cpm -namtab, 0dbh + 271 0175 36 40 db venix -namtab, 40h + 272 0177 3B F2 db dossec -namtab, 0F2h + 273 0179 41 00 db noname -namtab, 0 + 274 + 275 017B namtab: + 276 017B 44 6F F3 dos db 'Do','s'+80h + 277 017E 48 70 66 F3 hpfs db 'Hpf','s'+80h + 278 0182 4F 73 B2 os2 db 'Os','2'+80h + 279 0185 55 6E 69 F8 unix db 'Uni','x'+80h + 280 0189 4E 6F 76 65 6C EC novell db 'Novel','l'+80h + 281 018F 4D 69 6E 69 F8 minix db 'Mini','x'+80h + 282 0194 4C 69 6E 75 F8 linux db 'Linu','x'+80h + 283 0199 41 6D 6F 65 62 E1 amoeba db 'Amoeb','a'+80h + 284 019F 46 72 65 65 42 53 C4 freebsd db 'FreeBS','D'+80h + 285 01A6 42 53 44 E9 bsdi db 'BSD','i'+80h + Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 6 +boot.ASM + + + + 286 01AA 50 63 69 F8 pcix db 'Pci','x'+80h + 287 01AE 43 70 ED cpm db 'Cp','m'+80h + 288 01B1 56 65 6E 69 F8 venix db 'Veni','x'+80h + 289 01B6 44 6F 73 73 65 E3 dossec db 'Dosse','c'+80h + 290 01BC 3F BF noname db '?','?'+80h + 291 + 292 =01BE used equ $ - Boot + 293 01BE 01*(00) db (1beh - used + 1) dup (0) ; error if code too big + 294 01BF 3F*(00) db 63 dup (0) ; clear rest of record + 295 01FE AA55 dw 0aa55h ; magic + 296 + 297 0200 code ends + 298 end + Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 7 +Symbol Table + + + + +Symbol Name Type Value Cref (defined at #) + +??DATE Text "11/14/95" +??FILENAME Text "boot " +??TIME Text "18:41:35" +??VERSION Number 030A +@CPU Text 0101H +@CURSEG Text CODE #24 #34 +@FILENAME Text BOOT +@WORDSIZE Text 2 #24 #34 +AMOEBA Byte CODE:0199 265 #283 +BASE Number 0600 #13 26 53 67 72 123 128 130 141 144 154 158 164 171 192 + + 207 208 234 239 +BASEENTRY Near DUMMY:0600 #27 57 +BEGINHEAD Number 0001 #18 87 +BEGINSECTOR Number 0002 #19 88 +BOOT Near CODE:0000 #37 57 292 +BOOTINDICATOR Number 0000 #17 82 133 +BSDI Byte CODE:01A6 267 #285 +CPM Byte CODE:01AE 269 270 #287 +DEFAULT Byte CODE:014F 67 192 239 #251 +DEFAULTMSG Byte CODE:0142 164 #249 +DISKNUM Byte CODE:0141 123 #248 +DOS Byte CODE:017B 253 254 255 #276 +DOSSEC Byte CODE:01B6 272 #289 +DRIVEOK Near CODE:006E 118 #120 +ENDNAMELOOP Near CODE:00AA 150 #153 +ENTER_SCANCODE Number 001C #9 197 +ENTRY Near CODE:0067 57 #116 +F1_SCANCODE Number 003B #8 199 +FKEYMSG Byte CODE:0131 141 171 #245 +FREEBSD Byte CODE:019F 266 #284 +HAVE2DISKS Near CODE:00CC 162 #170 +HPFS Byte CODE:017E 256 #277 +KEY Byte CODE:0134 130 158 #246 +LINUX Byte CODE:0194 262 263 264 #282 +LOAD Near CODE:001B #64 208 +LOADBOOT Near CODE:0050 89 #97 +LOADDEFAULT Near CODE:00EC #191 198 +MENU Near CODE:0078 78 80 101 103 #127 169 +MENULOOP Near CODE:0085 #132 159 +MINIX Byte CODE:018F 261 #281 +NAMELOOP Near CODE:009D #145 152 +NAMETABLE Byte CODE:0151 144 #253 +NAMTAB Near CODE:017B 154 253 254 255 256 257 258 259 260 261 262 263 264 265 + + 266 267 268 269 270 271 272 273 #275 +NEWLINE Byte CODE:012F 207 #244 +NEXT Near CODE:00B1 136 138 #156 +NONAME Byte CODE:01BC 273 #290 +NOVELL Byte CODE:0189 259 260 #280 +NUMDISKS Number 0475 #15 161 +OS2 Byte CODE:0182 257 #278 +OUTPUT Near CODE:010B 142 155 172 174 #215 224 +PARTAB Number 01BE #14 72 128 +PCIX Byte CODE:01AA 268 #286 +PROMPT Near CODE:00D2 166 #173 + Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 8 +Symbol Table + + + +REPLY Near CODE:00F1 187 #194 +REPROMPT Near CODE:00D5 #175 202 204 +SAVEBOOT Near CODE:011A 83 94 #231 +STDBASE Number 7C00 #12 28 45 98 +STDBASEENTRY Near DUMMY:7C00 #29 110 +SWITCHDRIVE Near CODE:0048 69 #93 +SYSTEMID Number 0004 #20 77 79 134 151 +TESTKEY Near CODE:00FB 193 #200 +TIMEOUT Number 0005 #10 179 +UNIX Byte CODE:0185 258 #279 +USED Number 01BE #292 293 +VENIX Byte CODE:01B1 271 #288 +WAITKEY Near CODE:00DE #183 190 + +Groups & Segments Bit Size Align Combine Class Cref (defined at #) + +CODE 16 0200 Para none #34 35 35 35 35 +DUMMY 16 7C00 AT 0000 #24 25 + \ No newline at end of file diff --git a/Bootinst.c b/Bootinst.c new file mode 100644 index 0000000..f0e470a --- /dev/null +++ b/Bootinst.c @@ -0,0 +1,256 @@ +/* + * Boot installator. + * Author: Serge Vakulenko, + */ + +#include +#include +#include + +#define BOOTFILE "boot.bin" +#define SAVEFILE "bootsav.bin" +#define SAVE2FILE "boot2sav.bin" + +#define PartAddr 0x1be /* Offset to partition table */ +#define ValidationAddr 0x1fe /* Offset to validation bytes */ +#define MAGIC 0xaa55 /* Validation tag */ + +#define DISK1 0 +#define DISK2 1 +#define READ 0 +#define WRITE 1 + +typedef struct PartitionEntry { + unsigned char bootIndicator; + unsigned char beginHead; + unsigned char beginSector; + unsigned char beginCyl; + unsigned char systemId; + unsigned char endHead; + unsigned char endSector; + unsigned char endCyl; + unsigned short relSectorLow; + unsigned short relSectorHigh; + unsigned short numSectorsLow; + unsigned short numSectorsHigh; +} PartitionEntry; + +unsigned char bootRecord [512]; +unsigned char bootProg [512]; + +char head1 [] = "ÚÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ¿\n"; +char head2 [] = "³ ³Partition³Can ³Boot³ Beginning ³ Ending ³ Relative³Number of³\n"; +char head3 [] = "³N³ Type ³Boot³Part³Head Cyl Sect³Head Cyl Sect³ Sectors ³ Sectors ³\n"; +char head4 [] = "ÃÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÅÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´\n"; +char mid1 [] = "³%d³%-9.9s³%-4.4s³%-4.4s³%3u ³%4u ³%3u ³%3u ³%4u ³%3u ³%8lu ³%8lu ³\n"; +char mid2 [] = "ÃÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´\n"; +char foot [] = "ÀÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÙ\n"; + +void printtable (disk) +{ + PartitionEntry *part = (PartitionEntry *) (bootRecord + PartAddr); + int i, cb; + long relSectors; + long numSectors; + char *typeString, block [512]; + + printf ("\n"); + printf (head1); + printf (head2); + printf (head3); + printf (head4); + + for (i=0; i<4; ++i) { + switch (part->systemId) { + default: typeString = " ?????"; cb = 1; break; + case 0: typeString = " empty"; cb = 0; break; + case 1: typeString = " dos-12"; cb = 1; break; + case 2: typeString = " xenix"; cb = 1; break; + case 3: typeString = "xenix usr"; cb = 0; break; + case 4: typeString = " dos-16"; cb = 1; break; + case 5: typeString = " extend"; cb = 0; break; + case 6: typeString = " bigdos"; cb = 1; break; + case 7: typeString = " hpfs"; cb = 1; break; + case 0x75: typeString = " pcix"; cb = 1; break; + case 0xdb: typeString = " cp/m"; cb = 1; break; + case 0xff: typeString = " bbt"; cb = 0; break; + case 0x08: typeString = " aix"; cb = 0; break; + case 0x09: typeString = " coherent"; cb = 1; break; + case 0x0A: typeString = " os/2"; cb = 1; break; + case 0x10: typeString = " opus"; cb = 1; break; + case 0x40: typeString = "venix 286"; cb = 1; break; + case 0x50: + case 0x51: typeString = " dm"; cb = 1; break; + case 0x52: typeString = "microport"; cb = 1; break; + case 0x56: typeString = " gb"; cb = 1; break; + case 0x61: + case 0xE1: + case 0xE3: + case 0xE4: + case 0xF1: + case 0xF4: typeString = " speed"; cb = 1; break; + case 0x63: typeString = " unix"; cb = 1; break; + case 0x64: typeString = "novell286"; cb = 1; break; + case 0x65: typeString = "novell386"; cb = 1; break; + case 0x80: typeString = "old minix"; cb = 1; break; + case 0x81: typeString = " minix"; cb = 1; break; + case 0x82: typeString = " linux"; cb = 1; break; + case 0x93: typeString = " amoeba"; cb = 1; break; + case 0x94: typeString = "amoebaBBT"; cb = 0; break; + case 0xA5: typeString = " 386bsd"; cb = 1; break; + case 0x9f: + case 0xB7: typeString = " bsdi"; cb = 1; break; + case 0xB8: typeString = "bsdi swap"; cb = 0; break; + case 0xF2: typeString = " dos sec"; cb = 1; break; + } + relSectors = part->relSectorLow | + (unsigned long) part->relSectorHigh<<16; + numSectors = part->numSectorsLow | + (unsigned long) part->numSectorsHigh<<16; + + if (cb && (bootio (disk, READ, part->beginHead, part->beginCyl, + part->beginSector, block) != 0 || + *(short *) &block [ValidationAddr] != (short) MAGIC)) + cb = 0; + + printf (mid1, i+1, typeString, cb ? " yes" : " no", + (part->bootIndicator & 0x80) ? " yes" : " no", + part->beginHead, part->beginCyl | + part->beginSector<<2 & 0x300, + part->beginSector & 077, part->endHead, + part->endCyl | part->endSector<<2 & 0x300, + part->endSector & 077, relSectors, numSectors); + if (i < 3) + printf (mid2); + ++part; + } + printf (foot); +} + +int yes () +{ + char reply [80]; + + printf (" (yes/no) "); + fgets (reply, sizeof (reply), stdin); + return (!stricmp (reply, "y\n") || !stricmp (reply, "yes\n")); +} + +int install (disk, file, savefile) +char *file, *savefile; +{ + int rc, fd; + + rc = bootio (disk, READ, 0, 0, 1, bootRecord); + if (rc) { + fprintf (stderr, "Error %d reading boot record from disk %d\n", + rc, disk); + return (-1); + } + if (*(short *) &bootRecord [ValidationAddr] != (short) MAGIC) { + fprintf (stderr, "Bad master boot record on disk %d!\n", + disk); + return (-1); + } + + printtable (disk); + + fd = open (file, O_RDONLY|O_BINARY); + if (fd < 0) { + fprintf (stderr, "Cannot read file %s\n", file); + return (-1); + } + if (read (fd, bootProg, 512) != 512) { + fprintf (stderr, "Error reading %s\n", file); + return (-1); + } + close (fd); + if (*(short *) &bootProg [ValidationAddr] != (short) MAGIC) { + fprintf (stderr, "Bad boot image in file %s\n", file); + return (-1); + } + + printf ("\nAre you sure you want to install new boot on disk %d?", + disk); + if (! yes ()) + return (0); + + close (creat (savefile, 0664)); + fd = open (savefile, O_WRONLY|O_BINARY); + if (fd < 0) { + fprintf (stderr, "Cannot write to file %s\n", savefile); + return (-1); + } + if (write (fd, bootRecord, 512) != 512) { + fprintf (stderr, "Error writing to %s\n", savefile); + return (-1); + } + close (fd); + + memcpy (bootRecord, bootProg, PartAddr); + + rc = bootio (disk, WRITE, 0, 0, 1, bootRecord); + if (rc) { + fprintf (stderr, "Error %d updating boot record on disk %d\n", + rc, disk); + return (-1); + } + printf ("New boot record successfully installed.\n"); + return (0); +} + +bootio (disk, op, head, cyl, sect, buf) +char *buf; +{ + return (biosdisk (op==WRITE ? 3 : 2, disk==DISK1 ? 0x80 : 0x81, + head, cyl, sect, 1, buf)); +} + +int main (argc, argv) +char **argv; +{ + char *bootfile; + int disk2present; + + printf ("Boot installer, version 1.7, Copyright (C) Serge Vakulenko\n\n"); + + printf ("This utility allows you to install new boot program on your\n"); + printf ("hard disk. The usage is:\n\n"); + printf (" bootinst [bootfile]\n\n"); + printf ("It installs boot block from bootfile (default boot.bin) to the first\n"); + printf ("drive and, if second drive is present, to the second drive.\n"); + printf ("Old boot sectors are saved to bootsav.bin and boot2sav.bin respectively.\n"); + printf ("\nYou can copy and distribute this software free of charge,\n"); + printf ("provided that sources are included. No warranty, of course.\n\n"); + + if (argc > 3) + return (-1); + + bootfile = argc>1 ? argv[1] : BOOTFILE; + if (access (bootfile, 4) < 0) { + perror (bootfile); + return (-1); + } + + /* + * Is second disk present? Try to read boot sector, + * check that it is bootable and has valid partition table. + */ + disk2present = (bootio (DISK2, READ, 0, 0, 1, bootRecord) == 0 && + *(short *) &bootRecord [ValidationAddr] == (short) MAGIC && + (bootRecord [PartAddr] == 0 || bootRecord [PartAddr] == 0x80) && + (bootRecord [PartAddr+16] == 0 || bootRecord [PartAddr+16] == 0x80) && + (bootRecord [PartAddr+32] == 0 || bootRecord [PartAddr+32] == 0x80) && + (bootRecord [PartAddr+48] == 0 || bootRecord [PartAddr+48] == 0x80)); + + printf ("Continue with installation?"); + if (! yes ()) + return (0); + + install (DISK1, bootfile, SAVEFILE); + + if (disk2present) + install (DISK2, bootfile, SAVE2FILE); + + return (0); +} diff --git a/Compile.bat b/Compile.bat new file mode 100644 index 0000000..8b3ca5d --- /dev/null +++ b/Compile.bat @@ -0,0 +1,8 @@ +tasm /l /c /m3 boot +link /noi /noe /farcall boot,,; +@del boot.obj +@del boot.map +exe2bin boot.exe boot.bin +@del boot.exe +tcc -G -O -Z -d -ebootinst bootinst.c +@del bootinst.obj \ No newline at end of file diff --git a/Readme b/Readme new file mode 100644 index 0000000..99a589a --- /dev/null +++ b/Readme @@ -0,0 +1,57 @@ +This is a program, called BOOTEASY, version 1.7. +It serves as a replacement for the ordinary master boot. +It is very simple in installation, and quite intelligent +in handling various types of partitions. + +BOOTEASY makes possible coexistence of several different operating +systems on the same machine. At the boot time the short menu +is displayed, and you can choose and load the required OS. + +You can also boot from second hard disk. + +Some useful features: + +1) Very simple installation. Just call BOOTINST and answer 'yes' +to several questions. + +2) Saves the copy of original boot sector. You can restore it +calling BOOTINST with a parameter - the name of the file with +original boot sector. By default this is 'BOOTSAVE.BIN'. + +3) If no key is pressed during 5-second timeout, the default OS +will boot. + +4) The last booted partition is remembered and used as a default. + +5) BOOTEASY marks the booted partition as active, which is required +by some OS, such as Interactive Unix. + +6) If the second hard disk is present, you can boot from it. + +Changes in version 1.3: +- Fixed error with activating loaded partition. Loaded + partition was not marked active in partition table. + Now it is activated correctly. + +Changes in version 1.4: +- Fixed error with system timer 0 reset. Timer 0 was + cleared to zero after boot. Because MSDOS uses it (not RTC!) + as the real time value, the time was always 12:00. + Now system timer is not cleared. + +Changes in version 1.5: +- Added the possibility to install on the second disk only. + +Changes in version 1.6: +- Added the check of the drive number, got from the BIOS + in the DL register. Some BIOSes pass incorect value. + +Changes in version 1.7: +- Partition type names changed from lower case to mixed upper/lower case. +- Some program size optimizations added. + +BOOTEASY have been tested on Interactive Unix SVR3 and SVR4, +386bsd, FreeBSD, BSD/386 (BSDI), MSDOS 3, 4 and 5, MINIX, Xenix, +Windows NT, OS/2. + +Author: Serge Vakulenko, -- cgit v1.2.3