1128741Sru/* 2128741Sru * Copyright (c) 1998 Robert Nordier 3128741Sru * All rights reserved. 4128741Sru * 5128741Sru * Redistribution and use in source and binary forms are freely 6128741Sru * permitted provided that the above copyright notice and this 7128741Sru * paragraph and the following disclaimer are duplicated in all 8128741Sru * such forms. 9128741Sru * 10128741Sru * This software is provided "AS IS" and without any express or 11128741Sru * implied warranties, including, without limitation, the implied 12128741Sru * warranties of merchantability and fitness for a particular 13128741Sru * purpose. 14128741Sru * 15128741Sru * $FreeBSD$ 16128741Sru */ 17127458Sobrien 18128741Sru/* A 1024-byte boot manager. */ 19127458Sobrien 20127458Sobrien .set NHRDRV,0x475 # Number of hard drives 21127458Sobrien .set ORIGIN,0x600 # Execution address 22127458Sobrien .set SECTOR_SIZE,0x200 # Length of a sector 23127458Sobrien .set NUM_SECTORS,2 # Total length in sectors 24127458Sobrien 25127458Sobrien .set FAKE,ORIGIN+(SECTOR_SIZE*NUM_SECTORS) # Partition entry 26127458Sobrien .set LOAD,0x7c00 # Load address 27127458Sobrien 28127458Sobrien .set PRT_OFF,0x1be # Partition table 29127458Sobrien 30127458Sobrien .set TBL0SZ,table0_end-table0 # Table 0 size 31127458Sobrien .set TBL1SZ,table1_end-table1 # Table 1 size 32127458Sobrien 33127458Sobrien .set MAGIC,0xaa55 # Magic: bootable 34127458Sobrien 35127458Sobrien .set KEY_ENTER,0x1c # Enter key scan code 36127458Sobrien .set KEY_F1,0x3b # F1 key scan code 37128441Sobrien .set KEY_1,0x02 # #1 key scan code 38127458Sobrien 39128741Sru/* 40128741Sru * Flag bits 41128741Sru */ 42127458Sobrien .set FL_PACKET,0x80 # Packet mode 43127458Sobrien .set FL_NOUPDATE,0x40 # Don't save selection 44127458Sobrien .set FL_SETDRV,0x20 # Override drive number 45128741Sru/* 46128741Sru * Addresses in the sector of embedded data values. 47128741Sru * Accessed with negative offsets from the end of the relocated sectors (%bp). 48128741Sru */ 49128441Sobrien .set _PRT_END,(FAKE-(ORIGIN+SECTOR_SIZE*(NUM_SECTORS-1))) 50127458Sobrien .set _NXTDRV,-(_PRT_END+0x48) # Next drive 51127458Sobrien .set _OPT,-(_PRT_END+0x47) # Default option 52127458Sobrien .set _SETDRV,-(_PRT_END+0x46) # Drive to force 53127458Sobrien .set _FLAGS,-(_PRT_END+0x45) # Flags 54127458Sobrien .set _TICKS,-(_PRT_END+0x44) # Timeout ticks 55127458Sobrien .set _FAKE,0x0 # Fake partition entry 56127458Sobrien .set _MNUOPT,0xc # Menu options 57127458Sobrien 58127458Sobrien .globl start # Entry point 59127458Sobrien .code16 # This runs in real mode 60127458Sobrien 61128741Sru/* 62128741Sru * Initialise segments and registers to known values. 63128741Sru * segments start at 0. 64128741Sru * The stack is immediately below the address we were loaded to. 65128741Sru * 66128741Sru * Note that this section of code is used as the first signature check in 67128741Sru * boot0cfg(8). 68128741Sru */ 69127458Sobrienstart: cld # String ops inc 70127458Sobrien xorw %ax,%ax # Zero 71127458Sobrien movw %ax,%es # Address 72127458Sobrien movw %ax,%ds # data 73127458Sobrien movw %ax,%ss # Set up 74127458Sobrien movw $LOAD,%sp # stack 75128741Sru/* 76128741Sru * End signature code 77128741Sru */ 78128741Sru 79128741Sru/* 80128741Sru * Set address for variable space beyond code, and clear it. 81128741Sru * Notice that this is also used to point to the values embedded in the block, 82128741Sru * by using negative offsets. 83128741Sru */ 84127458Sobrien movw $fake,%bp # Address variables 85127458Sobrien movw %bp,%di # %di used in stosw 86127458Sobrien movw $0x8,%cx # Words to clear 87127458Sobrien rep # Zero 88127458Sobrien stosw # them 89127458Sobrien incb -0xe(%di) # Sector number 1 90128741Sru/* 91128741Sru * Check what flags were loaded with us; specifically, use a predefined Drive. 92128741Sru * If what the bios gives us is bad, use the '0' in the block instead, as well. 93128741Sru */ 94128441Sobrien testb $FL_SETDRV,LOAD+flags-start # Set number drive? 95128441Sobrien jnz boot.1 # Yes 96128441Sobrien testb %dl,%dl # Drive number valid? 97128441Sobrien js boot.2 # Possibly (0x80 set) 98128441Sobrienboot.1: movb LOAD+setdrv-start,%dl # Drive number to use 99128441Sobrienboot.2: 100128741Sru/* 101128741Sru * Reload all of boot0 (including the extra sectors) into memory at the 102128741Sru * relocation address. 103128741Sru */ 104127458Sobrien push %dx # Save drive number 105127458Sobrien movw $start,%bx # Origin we were linked for 106127458Sobrien movw %bp,%si # Fake PTE 107127458Sobrien movw $0x200+NUM_SECTORS,%ax # Read in all 108127458Sobrien callw intx13 # of boot0 109127458Sobrien pop %dx # Restore 110128741Sru/* 111128741Sru * Relocate to the new copy of the code. 112128741Sru */ 113127458Sobrien jmp main+ORIGIN-LOAD # To relocated code 114128741Sru/* 115128741Sru * Whatever we decided to use, now store it into the fake 116128741Sru * partition entry that lives in the data space above us. 117128741Sru */ 118128441Sobrienmain: movb %dl,_FAKE(%bp) # Save drive number 119127458Sobrien callw putn # To new line 120127458Sobrien pushw %dx # Save drive number 121128741Sru/* 122128741Sru * Start out with a pointer to the 4th byte of the first table entry 123128741Sru * so that after 4 iterations it's beyond the end of the sector. 124128741Sru * and beyond a 256 byte boundary and has overflowed 8 bits (see next comment). 125128741Sru * (remember that the table starts 2 bytes earlier than you would expect 126128741Sru * as the bootable flag is after it in the block) 127128741Sru */ 128127458Sobrien movw $(partbl+0x4),%bx # Partition table (+4) 129127458Sobrien xorw %dx,%dx # Item number 130128741Sru/* 131128741Sru * Loop around on the partition table, printing values until we 132128741Sru * pass a 256 byte boundary. The end of loop test is at main.5. 133128741Sru */ 134128451Sobrienmain.3: movb %ch,-0x4(%bx) # Zero active flag (ch == 0) 135127458Sobrien btw %dx,_FLAGS(%bp) # Entry enabled? 136127458Sobrien jnc main.5 # No 137128741Sru/* 138128741Sru * If any of the entries in the table are 139128741Sru * the same as the 'type' in the slice table entry, 140128741Sru * then this is an empty or non bootable partition. Skip it. 141128741Sru */ 142127458Sobrien movb (%bx),%al # Load type 143127458Sobrien movw $tables,%di # Lookup tables 144127458Sobrien movb $TBL0SZ,%cl # Number of entries 145127458Sobrien repne # Exclude 146127458Sobrien scasb # partition? 147127458Sobrien je main.5 # Yes 148128741Sru/* 149128741Sru * Now scan the table of known types 150128741Sru */ 151127458Sobrien movb $TBL1SZ,%cl # Number of entries 152127458Sobrien repne # Known 153127458Sobrien scasb # type? 154127458Sobrien jne main.4 # No 155128741Sru/* 156128741Sru * If it matches get the matching element in the 157128741Sru * next array. If it doesn't, we are already 158128741Sru * pointing at its first element which points to a "?". 159128741Sru */ 160127458Sobrien addw $TBL1SZ,%di # Adjust 161128471Sobrienmain.4: movb (%di),%cl # Partition 162127458Sobrien addw %cx,%di # description 163127458Sobrien callw putx # Display it 164128471Sobrienmain.5: incw %dx # Next item 165127458Sobrien addb $0x10,%bl # Next entry 166127458Sobrien jnc main.3 # Till done 167128741Sru/* 168128741Sru * Passed a 256 byte boundary.. 169128741Sru * table is finished. 170128741Sru * Add one to the drive number and check it is valid, 171128741Sru */ 172127458Sobrien popw %ax # Drive number 173127458Sobrien subb $0x80-0x1,%al # Does next 174127458Sobrien cmpb NHRDRV,%al # drive exist? (from BIOS?) 175127458Sobrien jb main.6 # Yes 176128741Sru/* 177128741Sru * If not then if there is only one drive, 178128741Sru * Don't display drive as an option. 179128741Sru */ 180127458Sobrien decw %ax # Already drive 0? 181127458Sobrien jz main.7 # Yes 182128741Sru/* 183128741Sru * If it was illegal or we cycled through them, 184128741Sru * then go back to drive 0. 185128741Sru */ 186127458Sobrien xorb %al,%al # Drive 0 187128741Sru/* 188128741Sru * Whatever drive we selected, make it an ascii digit and save it back 189128741Sru * to the "next drive" location in the loaded block in case we 190128741Sru * want to save it for next time. 191128741Sru * This also is part of the printed drive string so add 0x80 to indicate 192128741Sru * end of string. 193128741Sru */ 194128451Sobrienmain.6: addb $'0'|0x80,%al # Save next 195127458Sobrien movb %al,_NXTDRV(%bp) # drive number 196127458Sobrien movw $drive,%di # Display 197127458Sobrien callw putx # item 198128741Sru/* 199128741Sru * Now that we've printed the drive (if we needed to), display a prompt. 200128741Sru * Get ready for the input by noting the time. 201128741Sru */ 202128451Sobrienmain.7: movw $prompt,%si # Display 203127458Sobrien callw putstr # prompt 204127458Sobrien movb _OPT(%bp),%dl # Display 205127458Sobrien decw %si # default 206127458Sobrien callw putkey # key 207127458Sobrien xorb %ah,%ah # BIOS: Get 208127458Sobrien int $0x1a # system time 209127458Sobrien movw %dx,%di # Ticks when 210127458Sobrien addw _TICKS(%bp),%di # timeout 211128741Sru/* 212128741Sru * Busy loop, looking for keystrokes but 213128741Sru * keeping one eye on the time. 214128741Sru */ 215128451Sobrienmain.8: movb $0x1,%ah # BIOS: Check 216127458Sobrien int $0x16 # for keypress 217127458Sobrien jnz main.11 # Have one 218127458Sobrien xorb %ah,%ah # BIOS: Get 219127458Sobrien int $0x1a # system time 220127458Sobrien cmpw %di,%dx # Timeout? 221127458Sobrien jb main.8 # No 222128741Sru/* 223128741Sru * If timed out or defaulting, come here. 224128741Sru */ 225128451Sobrienmain.9: movb _OPT(%bp),%al # Load default 226127458Sobrien jmp main.12 # Join common code 227128741Sru/* 228128741Sru * User's last try was bad, beep in displeasure. 229128741Sru * Since nothing was printed, just continue on as if the user 230128741Sru * hadn't done anything. This gives the effect of the user getting a beep 231128741Sru * for all bad keystrokes but no action until either the timeout 232128741Sru * occurs or the user hits a good key. 233128741Sru */ 234127458Sobrienmain.10: movb $0x7,%al # Signal 235127458Sobrien callw putchr # error 236128741Sru/* 237128741Sru * Get the keystroke. 238128741Sru */ 239127458Sobrienmain.11: xorb %ah,%ah # BIOS: Get 240127458Sobrien int $0x16 # keypress 241127458Sobrien movb %ah,%al # Scan code 242128741Sru/* 243128741Sru * If it's CR act as if timed out. 244128741Sru */ 245127458Sobrien cmpb $KEY_ENTER,%al # Enter pressed? 246127458Sobrien je main.9 # Yes 247128741Sru/* 248128741Sru * Otherwise check if legal 249128741Sru * If not ask again. 250128741Sru */ 251127458Sobrien subb $KEY_F1,%al # Less F1 scan code 252127458Sobrien cmpb $0x4,%al # F1..F5? 253128441Sobrien jna main.12 # Yes 254128441Sobrien subb $(KEY_1 - KEY_F1),%al # Less #1 scan code 255128441Sobrien cmpb $0x4,%al # #1..#5? 256127458Sobrien ja main.10 # No 257128741Sru/* 258128741Sru * We have a selection. 259128741Sru * but if it's a bad selection go back to complain. 260128741Sru * The bits in MNUOPT were set when the options were printed. 261128741Sru * Anything not printed is not an option. 262128741Sru */ 263127458Sobrienmain.12: cbtw # Option 264127458Sobrien btw %ax,_MNUOPT(%bp) # enabled? 265127458Sobrien jnc main.10 # No 266128741Sru/* 267128741Sru * Save the info in the original tables 268128741Sru * for rewriting to the disk. 269128741Sru */ 270127458Sobrien movb %al,_OPT(%bp) # Save option 271127458Sobrien movw $fake,%si # Partition for write 272127458Sobrien movb (%si),%dl # Drive number 273127458Sobrien movw %si,%bx # Partition for read 274128441Sobrien cmpb $0x4,%al # F5/#5 pressed? 275127458Sobrien pushf # Save 276127458Sobrien je main.13 # Yes 277127458Sobrien shlb $0x4,%al # Point to 278127458Sobrien addw $partbl,%ax # selected 279127458Sobrien xchgw %bx,%ax # partition 280127458Sobrien movb $0x80,(%bx) # Flag active 281128741Sru/* 282128741Sru * If not asked to do a write-back (flags 0x40) don't do one. 283128741Sru */ 284127458Sobrienmain.13: pushw %bx # Save 285127458Sobrien testb $FL_NOUPDATE,_FLAGS(%bp) # Skip update? 286127458Sobrien jnz main.14 # Yes 287127458Sobrien movw $start,%bx # Data to write 288127458Sobrien movw $0x301,%ax # Write 1 sector 289127458Sobrien callw intx13 # to disk 290127458Sobrienmain.14: popw %si # Restore 291127458Sobrien popf # Restore 292128741Sru/* 293128741Sru * If going to next drive, replace drive with selected one. 294128741Sru * Remember to un-ascii it. Hey 0x80 is already set, cool! 295128741Sru */ 296128441Sobrien jne main.15 # If not F5/#5 297127458Sobrien movb _NXTDRV(%bp),%dl # Next drive 298127458Sobrien subb $'0',%dl # number 299128741Sru/* 300128741Sru * load selected bootsector to the LOAD location in RAM. 301128741Sru * If it fails to read or isn't marked bootable, treat it 302128741Sru * as a bad selection. 303128741Sru */ 304127458Sobrienmain.15: movw $LOAD,%bx # Address for read 305127458Sobrien movw $0x201,%ax # Read 1 sector 306127458Sobrien callw intx13 # from disk 307127458Sobrien jc main.10 # If error 308127458Sobrien cmpw $MAGIC,0x1fe(%bx) # Bootable? 309127458Sobrien jne main.10 # No 310127458Sobrien callw putn # Leave some space 311127458Sobrien jmp *%bx # Invoke bootstrap 312127458Sobrien 313128741Sru/* 314128741Sru * Display routines 315128741Sru */ 316127458Sobrien 317128451Sobrienputkey: movb $'F',%al # Display 318127458Sobrien callw putchr # 'F' 319127458Sobrien movb $'1',%al # Prepare 320127458Sobrien addb %dl,%al # digit 321127458Sobrien jmp putstr.1 # Display the rest 322127458Sobrien 323128741Sru/* 324128741Sru * Display the option and note that it is a valid option. 325128741Sru * That last point is a bit tricky.. 326128741Sru */ 327127458Sobrienputx: btsw %dx,_MNUOPT(%bp) # Enable menu option 328127458Sobrien movw $item,%si # Display 329127458Sobrien callw putkey # key 330127458Sobrien movw %di,%si # Display the rest 331127458Sobrien 332127458Sobrienputs: callw putstr # Display string 333127458Sobrien 334127458Sobrienputn: movw $crlf,%si # To next line 335127458Sobrien 336128451Sobrienputstr: lodsb # Get byte 337127458Sobrien testb $0x80,%al # End of string? 338127458Sobrien jnz putstr.2 # Yes 339127458Sobrienputstr.1: callw putchr # Display char 340127458Sobrien jmp putstr # Continue 341127458Sobrienputstr.2: andb $~0x80,%al # Clear MSB 342127458Sobrien 343128451Sobrienputchr: pushw %bx # Save 344127458Sobrien movw $0x7,%bx # Page:attribute 345127458Sobrien movb $0xe,%ah # BIOS: Display 346127458Sobrien int $0x10 # character 347127458Sobrien popw %bx # Restore 348127458Sobrien retw # To caller 349127458Sobrien 350128741Sru/* 351128741Sru * One-sector disk I/O routine 352128741Sru * 353128741Sru * Calling conventions: (assumes %si -> partition table entry) 354128741Sru * 355128741Sru * 0x1(%si) - byte - head 356128741Sru * 0x2(%si) - word - cylinder/sector 357128741Sru * 0x8(%si) - long - LBA to use if needed 358128741Sru * %ah - byte - operation, 2 = read, 3 = write 359128741Sru * %al - byte - sector count 360128741Sru * %dl - byte - drive number 361128741Sru * %es:(%bx) - void - buffer to use for transfer 362128741Sru * 363128741Sru * If the head == 0xff, and cylinder/sector == 0xffff, then try 364128741Sru * to use the EDD stuff with the LBA offset instead of CHS. However, 365128741Sru * use CHS if at all possible. 366128741Sru */ 367127458Sobrien 368128451Sobrienintx13: movb 0x1(%si),%dh # Load head 369127458Sobrien movw 0x2(%si),%cx # Load cylinder:sector 370127458Sobrien pushw %si # Save 371127458Sobrien movw %sp,%di # Save 372127458Sobrien cmpb $0xff,%dh # Might we need LBA? 373127458Sobrien jne intx13.2 # No, just use CHS 374127458Sobrien cmpw $0xffff,%cx # Do we need LBA? 375127458Sobrien jne intx13.2 # No 376127458Sobrien testb $FL_PACKET,_FLAGS(%bp) # Try the packet interface? 377127458Sobrien jz intx13.2 # No 378127458Sobrien pushw %cx # Save 379127458Sobrien pushw %bx # Save 380127458Sobrien movw $0x55aa,%bx # Magic 381127458Sobrien pushw %ax # Save 382127458Sobrien movb $0x41,%ah # BIOS: EDD extensions 383127458Sobrien int $0x13 # present? 384127458Sobrien popw %ax # Restore 385127458Sobrien jc intx13.1 # Not present, use CHS 386127458Sobrien cmpw $0xaa55,%bx # Magic? 387127458Sobrien jne intx13.1 # Not present, use CHS 388127458Sobrien testb $0x1,%cl # Packet mode available? 389127458Sobrien jz intx13.1 # No, use CHS 390127458Sobrien orb $0x40,%ah # Use disk packet 391127458Sobrienintx13.1: popw %bx # Restore 392127458Sobrien popw %cx # Restore 393127458Sobrien testb $0x40,%ah # Using packet mode? 394127458Sobrien jz intx13.2 # No, so skip the rest 395127458Sobrien pushl $0x0 # Set the 396127458Sobrien pushl 0x8(%si) # LBA address 397127458Sobrien pushw %es # Set the transfer 398127458Sobrien pushw %bx # buffer address 399127458Sobrien push $0x0 # Punch a hole in the stack 400127458Sobrien push $0x10 # Packet size 401127458Sobrien movw %sp,%si # Packet pointer 402127458Sobrien xchgb %al,0x2(%si) # Set the block count in the 403127458Sobrien # packet and zero %al, 404127458Sobrien # turning verify off for writes 405127458Sobrienintx13.2: int $0x13 # BIOS: Disk I/O 406127458Sobrien movw %di,%sp # Restore 407127458Sobrien popw %si # Restore 408127458Sobrien retw # To caller 409127458Sobrien 410127458Sobrien .org PRT_OFF-0xe,0x90 411128741Sru/* 412128741Sru * These values are sometimes changed before writing back to the drive 413128741Sru * Be especially careful that nxtdrv: must come after drive:, as it 414128741Sru * is part of the same string. 415128741Sru * 416128741Sru * Note that the 'drive' string variable is used as the second signature 417128741Sru * check in boot0cfg(8). 418128741Sru */ 419127458Sobrienversion_minor: .byte 0x1 # minor version 420128451Sobrienversion_major: .byte 0x1 # major version 421127458Sobriendrive: .ascii "Drive " 422128451Sobriennxtdrv: .byte 0x0 # Next drive number 423127458Sobrienopt: .byte 0x0 # Option 424128451Sobriensetdrv: .byte 0x80 # Drive to force 425127458Sobrienflags: .byte FLAGS # Flags 426127458Sobrienticks: .word TICKS # Delay 427127458Sobrien 428128741Sru/* 429128741Sru * here is the 64 byte partition table that fdisk would fiddle with. 430128741Sru */ 431128451Sobrienpartbl: .fill 0x40,0x1,0x0 # Partition table 432127458Sobrien .word MAGIC # Magic number 433127458Sobrien 434128741Sru/* 435128741Sru * start of sector two.. ugh 436128741Sru */ 437127458Sobrien .org SECTOR_SIZE,0x90 438127458Sobrien 439128741Sru/* Menu strings */ 440128741Sru 441127458Sobrienitem: .ascii " "; .byte ' '|0x80 442128451Sobrienprompt: .ascii "\nDefault:"; .byte ' '|0x80 443127458Sobriencrlf: .ascii "\r"; .byte '\n'|0x80 444127458Sobrien 445128741Sru/* Partition type tables */ 446127458Sobrien 447127458Sobrientables: 448128741Sru/* 449128741Sru * These entries identify invalid or NON BOOT types and partitions. 450128741Sru */ 451127458Sobrientable0: .byte 0x0, 0x5, 0xf 452127458Sobrientable0_end: 453128741Sru/* 454128741Sru * These values indicate bootable types we know the names of 455128741Sru */ 456128441Sobrientable1: .byte 0x1, 0x4, 0x6, 0x7, 0xb, 0xc, 0xe, 0x42, 0x63, 0x83 457127458Sobrien .byte 0x9f, 0xa5, 0xa6, 0xa9 458127458Sobrientable1_end: 459128741Sru/* 460128741Sru * These are offsets that match the known names above and point to the strings 461128741Sru * that will be printed. 462128741Sru */ 463127458Sobrien .byte os_misc-. # Unknown 464127458Sobrien .byte os_dos-. # DOS 465127458Sobrien .byte os_dos-. # DOS 466127458Sobrien .byte os_dos-. # DOS 467128441Sobrien .byte os_nt-. # NT/XP or OS/2 468128441Sobrien .byte os_windows-. # Windows 32-bit FAT 469128441Sobrien .byte os_windows-. # Windows 32-bit FAT ext int 13 470127458Sobrien .byte os_windows-. # Windows 471128441Sobrien .byte os_windows-. # Windows 2000 dyn ext 472127458Sobrien .byte os_unix-. # UNIX 473127458Sobrien .byte os_linux-. # Linux 474127458Sobrien .byte os_bsdos-. # BSD/OS 475127458Sobrien .byte os_freebsd-. # FreeBSD 476127458Sobrien .byte os_openbsd-. # OpenBSD 477127458Sobrien .byte os_netbsd-. # NetBSD 478128741Sru/* 479128741Sru * And here are the strings themselves. 0x80 or'd into a byte indicates 480128741Sru * the end of the string. (not so great for Russians but...) 481128741Sru */ 482127458Sobrienos_misc: .ascii "Unknow"; .byte 'n'|0x80 483128451Sobrienos_dos: .ascii "DO"; .byte 'S'|0x80 484128441Sobrienos_nt: .ascii "Windows NT/X"; .byte 'P'|0x80 485128451Sobrienos_windows: .ascii "Window"; .byte 's'|0x80 486127458Sobrienos_unix: .ascii "UNI"; .byte 'X'|0x80 487127458Sobrienos_linux: .ascii "Linu"; .byte 'x'|0x80 488127458Sobrienos_freebsd: .ascii "FreeBS"; .byte 'D'|0x80 489127458Sobrienos_openbsd: .ascii "OpenBS"; .byte 'D'|0x80 490127458Sobrienos_netbsd: .ascii "NetBS"; .byte 'D'|0x80 491127458Sobrienos_bsdos: .ascii "BSD/O"; .byte 'S'|0x80 492127458Sobrien 493128741Sru/* 494128741Sru * Fake partition entry created at the end of the table used when loading 495128741Sru * boot0 at the very beginning and when loading an MBR from another disk when 496128741Sru * F5 is pressed. 497128741Sru */ 498127458Sobrien .org SECTOR_SIZE*NUM_SECTORS, 0x0 499127458Sobrienfake: 500