Ticket #4028: new_haiku_gpt_mbr.diff
File new_haiku_gpt_mbr.diff, 27.8 KB (added by , 13 years ago) |
---|
-
build/jam/AnybootImage
33 33 } 34 34 35 35 local baseMBR = base_mbr.bin ; 36 local mbrSource = [ FDirName $(HAIKU_TOP) src bin writembr mbr.S ] ;36 local mbrSource = [ FDirName $(HAIKU_TOP) src bin writembr hybrid_mbr.S ] ; 37 37 BuildAnybootMBR $(baseMBR) : $(mbrSource) ; 38 38 MakeLocate $(baseMBR) : $(HAIKU_OUTPUT_DIR) ; 39 39 MakeLocate $(HAIKU_ANYBOOT) : $(HAIKU_ANYBOOT_DIR) ; -
src/add-ons/kernel/partitioning_systems/intel/PartitionMapWriter.cpp
39 39 40 40 // compiled form of hybrid FreeBSD pmbr and mbr loader done by André Braga 41 41 static const uint8 kBootCode[] = { 42 0xf c, 0xe8, 0x05, 0x01, 0xbc, 0x00, 0x0e, 0xbe, 0x15, 0x7c, 0xbf, 0x15,43 0x 06, 0xb9, 0xeb, 0x01, 0xf3, 0xa4, 0xe9, 0x00, 0x8a, 0xe8, 0xfc, 0x00,44 0x bb, 0x00, 0x0e, 0xbe, 0xb0, 0x07, 0xb9, 0x01, 0x00, 0xe8, 0x03, 0x01,45 0x 66, 0x81, 0x3e, 0x00, 0x0e, 0x45, 0x46, 0x49, 0x20, 0x75, 0x5c, 0x66,46 0x 81, 0x3e, 0x04, 0x0e, 0x50, 0x41, 0x52, 0x54, 0x75, 0x51, 0xbe, 0x48,47 0x 0e, 0xbb, 0x00, 0x10, 0xb9, 0x01, 0x00, 0xe8, 0xe1, 0x00, 0x89, 0xde,48 0x bf, 0xa0, 0x07, 0xb1, 0x10, 0xf3, 0xa6, 0x75, 0x1b, 0x89, 0xdf, 0x8d,49 0x75, 0x 20, 0xbb, 0xc0, 0x07, 0x8e, 0xc3, 0x31, 0xdb, 0x56, 0x8a, 0x0e,50 0x 9f, 0x07, 0xe8, 0xc2, 0x00, 0x31, 0xc0, 0x8e, 0xc0, 0xe9, 0x94, 0x75,51 0x 66, 0xff, 0x0e, 0x50, 0x0e, 0x74, 0x18, 0xa1, 0x54, 0x0e, 0x01, 0xc3,52 0x 81, 0xfb, 0x00, 0x12, 0x72, 0xc8, 0x66, 0xff, 0x06, 0x48, 0x0e, 0x66,53 0x 83, 0x16, 0x4c, 0x0e, 0x00, 0xeb, 0xaf, 0xe8, 0x7b, 0x00, 0xbc, 0x00,54 0x 7c, 0x31, 0xf6, 0xbb, 0xbe, 0x07, 0xb1, 0x04, 0x38, 0x2f, 0x74, 0x0c,55 0x 0f, 0x8f, 0xa2, 0x00, 0x85, 0xf6, 0x0f, 0x85, 0x9c, 0x00, 0x89, 0xde,56 0x 80, 0xc3, 0x10, 0xe2, 0xeb, 0x85, 0xf6, 0x75, 0x02, 0xcd, 0x18, 0xe8,57 0x 5e, 0x00, 0x89, 0xe7, 0x8a, 0x74, 0x01, 0x8b, 0x4c, 0x02, 0xbb, 0x00,58 0x 7c, 0xf6, 0x06, 0x9e, 0x07, 0x80, 0x74, 0x2d, 0x51, 0x53, 0xbb, 0xaa,59 0x 55, 0xb4, 0x41, 0xcd, 0x13, 0x72, 0x20, 0x81, 0xfb, 0x55, 0xaa, 0x75,60 0x 1a, 0xf6, 0xc1, 0x01, 0x74, 0x15, 0x5b, 0x66, 0x6a, 0x00, 0x66, 0xff,61 0x7 4, 0x08, 0x06, 0x53, 0x6a, 0x01, 0x6a, 0x10, 0x89, 0xe6, 0xb8, 0x00,62 0x 42, 0xeb, 0x05, 0x5b, 0x59, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x89, 0xfc,63 0x 72, 0x49, 0x81, 0xbf, 0xfe, 0x01, 0x55, 0xaa, 0x75, 0x46, 0xe9, 0x5c,64 0xf f, 0x31, 0xc9, 0x31, 0xc0, 0x8e, 0xc0, 0x8e, 0xd8, 0x8e, 0xd0, 0xc3,65 0x8 0, 0xfa, 0x80, 0x72, 0x0b, 0x8a, 0x36, 0x75, 0x04, 0x80, 0xc6, 0x80,66 0x 38, 0xf2, 0x72, 0x02, 0xb2, 0x80, 0xc3, 0x66, 0xff, 0x74, 0x04, 0x66,67 0x ff, 0x34, 0x06, 0x53, 0x51, 0x6a, 0x10, 0x89, 0xe6, 0xb8, 0x00, 0x42,68 0x cd, 0x13, 0x83, 0xc4, 0x10, 0x0f, 0x82, 0x4a, 0xff, 0xc3, 0xbe, 0x60,69 0x 07, 0xeb, 0x11, 0xbe, 0x74, 0x07, 0xeb, 0x0c, 0xbe, 0x7d, 0x07, 0xeb,70 0x 07, 0xbb, 0x07, 0x00, 0xb4, 0x0e, 0xcd, 0x10, 0xac, 0x84, 0xc0, 0x75,71 0x f4, 0xf4, 0xeb, 0xfd, 0x42, 0x61, 0x64, 0x20, 0x50, 0x61, 0x72, 0x74,72 0x 69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x00,73 0x4 9, 0x4f, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x4d, 0x69, 0x73,74 0x 73, 0x69, 0x6e, 0x67, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20,75 0x 42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x00, 0xff,76 0x ff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x02, 0x31, 0x53, 0x46, 0x42,42 0xfa, 0x31, 0xc0, 0x8e, 0xc0, 0x8e, 0xd8, 0x8e, 0xd0, 0xbc, 0xf8, 0x0d, 43 0xfd, 0xbe, 0x00, 0x7c, 0x8d, 0x7c, 0xff, 0xb9, 0xff, 0x75, 0xf3, 0xaa, 44 0xfc, 0xb9, 0x00, 0x02, 0xf3, 0xa4, 0xea, 0x23, 0x06, 0x00, 0x00, 0xfb, 45 0xb6, 0x00, 0xbb, 0xaa, 0x55, 0xb4, 0x41, 0xcd, 0x13, 0x72, 0x0b, 0x81, 46 0xfb, 0x55, 0xaa, 0x75, 0x05, 0xf6, 0xc1, 0x01, 0x75, 0x05, 0xb6, 0x01, 47 0xe9, 0x92, 0x00, 0xbb, 0x00, 0x0e, 0xbe, 0xf8, 0x0d, 0xc6, 0x04, 0x01, 48 0xe8, 0xe8, 0x00, 0x66, 0x81, 0x3e, 0x00, 0x0e, 0x45, 0x46, 0x49, 0x20, 49 0x75, 0x7b, 0x66, 0x81, 0x3e, 0x04, 0x0e, 0x50, 0x41, 0x52, 0x54, 0x75, 50 0x70, 0xbe, 0x48, 0x0e, 0xbb, 0x00, 0x10, 0xe8, 0xc9, 0x00, 0x89, 0xde, 51 0xbf, 0xa0, 0x07, 0xb1, 0x10, 0xf3, 0xa6, 0x75, 0x3d, 0x89, 0xdf, 0x8d, 52 0x75, 0x20, 0xbb, 0xc0, 0x07, 0x8e, 0xc3, 0x31, 0xdb, 0x56, 0xe8, 0xae, 53 0x00, 0x5e, 0x66, 0x8b, 0x45, 0x28, 0x66, 0x3b, 0x04, 0x75, 0x0d, 0x66, 54 0x8b, 0x45, 0x2c, 0x66, 0x3b, 0x44, 0x04, 0x75, 0x03, 0xe9, 0x8e, 0x00, 55 0x66, 0xff, 0x04, 0x66, 0x83, 0x54, 0x04, 0x00, 0x8c, 0xc0, 0x83, 0xc0, 56 0x20, 0x3d, 0x00, 0x90, 0x73, 0x7c, 0x8e, 0xc0, 0xeb, 0xcf, 0x66, 0xff, 57 0x0e, 0x50, 0x0e, 0x74, 0x18, 0xa1, 0x54, 0x0e, 0x01, 0xc3, 0x81, 0xfb, 58 0x00, 0x12, 0x72, 0xa6, 0x66, 0xff, 0x06, 0x48, 0x0e, 0x66, 0x83, 0x16, 59 0x4c, 0x0e, 0x00, 0xeb, 0x90, 0x31, 0xc0, 0x8e, 0xc0, 0xbc, 0x00, 0x7c, 60 0x31, 0xf6, 0xbb, 0xbe, 0x07, 0xb9, 0x04, 0x00, 0x38, 0x2f, 0x74, 0x08, 61 0x7f, 0x74, 0x85, 0xf6, 0x75, 0x70, 0x89, 0xde, 0x80, 0xc3, 0x10, 0xe2, 62 0xef, 0x85, 0xf6, 0x75, 0x02, 0xcd, 0x18, 0x89, 0xe3, 0x56, 0x80, 0xfe, 63 0x01, 0x74, 0x12, 0x83, 0xc6, 0x08, 0xbf, 0xf8, 0x0d, 0x66, 0xa5, 0x87, 64 0xfe, 0x83, 0xee, 0x04, 0xe8, 0x24, 0x00, 0xeb, 0x0c, 0x8a, 0x74, 0x01, 65 0x8b, 0x4c, 0x02, 0xb0, 0x02, 0xb4, 0x02, 0xcd, 0x13, 0x72, 0x43, 0x5e, 66 0x88, 0x14, 0x81, 0xbf, 0xfe, 0x01, 0x55, 0xaa, 0x75, 0x40, 0x31, 0xc0, 67 0x8e, 0xc0, 0xea, 0x00, 0x7c, 0x00, 0x00, 0x66, 0xff, 0x74, 0x04, 0x66, 68 0xff, 0x34, 0x06, 0x53, 0x6a, 0x01, 0x6a, 0x10, 0x89, 0xe6, 0xb8, 0x00, 69 0x42, 0xcd, 0x13, 0x83, 0xc4, 0x10, 0x72, 0x16, 0xc3, 0xbb, 0x07, 0x00, 70 0xb4, 0x0e, 0xcd, 0x10, 0xac, 0x84, 0xc0, 0x75, 0xf4, 0xc3, 0xbe, 0x74, 71 0x07, 0xe8, 0xf4, 0xff, 0xeb, 0x0e, 0xbe, 0x85, 0x07, 0xe8, 0xec, 0xff, 72 0xeb, 0x06, 0xbe, 0x91, 0x07, 0xe8, 0xe4, 0xff, 0xfa, 0xf4, 0xeb, 0xfc, 73 0x42, 0x61, 0x64, 0x20, 0x50, 0x61, 0x72, 0x74, 0x2e, 0x20, 0x54, 0x61, 74 0x62, 0x6c, 0x65, 0x21, 0x00, 0x52, 0x65, 0x61, 0x64, 0x20, 0x45, 0x72, 75 0x72, 0x6f, 0x72, 0x21, 0x00, 0x4e, 0x6f, 0x20, 0x53, 0x79, 0x73, 0x20, 76 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x21, 0x00, 0x31, 0x53, 0x46, 0x42, 77 77 0xa3, 0x3b, 0xf1, 0x10, 0x80, 0x2a, 0x48, 0x61, 0x69, 0x6b, 0x75, 0x21 78 78 }; 79 79 -
src/bin/writembr/mbr.S
1 /*2 ** Copyright (c) 1999 Robert Nordier3 ** All rights reserved.4 **5 ** Redistribution and use in source and binary forms are freely6 ** permitted provided that the above copyright notice and this7 ** paragraph and the following disclaimer are duplicated in all8 ** such forms.9 **10 ** This software is provided "AS IS" and without any express or11 ** implied warranties, including, without limitation, the implied12 ** warranties of merchantability and fitness for a particular13 ** purpose.14 /*15 16 /* A 512 byte MBR boot manager that simply boots the active partition. */17 18 .set LOAD, 0x7c00 // Load address19 .set EXEC, 0x600 // Execution address20 .set PT_OFF, 0x1be // Partition table21 .set MAGIC, 0xaa55 // Magic: bootable22 23 .set NUM_HARD_DRIVES, 0x475 // Number of hard drives24 25 .globl start // Entry point26 .code1627 28 /*29 * Setup the segment registers for flat addressing and setup the stack.30 */31 start: cld // String ops inc32 xorw %ax, %ax // Zero33 movw %ax, %es // Address34 movw %ax, %ds // data35 movw %ax, %ss // Set up stack36 movw $LOAD, %sp //37 /*38 * Relocate ourself to a lower address so that we are out of the way when39 * we load in the bootstrap from the partition to boot.40 */41 movw $main-EXEC+LOAD, %si // Source42 movw $main, %di // Destination43 movw $0x200-(main-start), %cx // Byte count44 rep // Relocate code45 movsb //46 /*47 * Jump to the relocated code.48 */49 jmp main-LOAD+EXEC // Jump to relocated code50 51 /*52 * Scan the partition table looking for an active entry. Note that %ch is53 * zero from the repeated string instruction above. We save the offset of54 * the active partition in %si and scan the entire table to ensure that only55 * one partition is marked active.56 */57 58 main: xorw %si, %si // No active partition59 movw $partition_table, %bx // Partition table60 movb $0x4, %cl // Number of entries61 main.1: cmpb %ch, (%bx) // Null entry?62 je main.2 // Yes63 jg err_partition_table // If 0x1..0x7f64 testw %si, %si // Active already found?65 jnz err_partition_table // Yes66 movw %bx, %si // Point to active67 main.2: addb $0x10, %bl // Till68 loop main.1 // done69 testw %si, %si // Active found?70 jnz main.3 // Yes71 int $0x18 // BIOS: Diskless boot72 /*73 * Ok, we've found a possible active partition. Check to see that the drive74 * is a valid hard drive number.75 */76 main.3: cmpb $0x80, %dl // Drive valid?77 jb main.4 // No78 movb NUM_HARD_DRIVES, %dh // Calculate the highest79 addb $0x80, %dh // drive number available80 cmpb %dh, %dl // Within range?81 jb main.5 // Yes82 main.4: movb (%si), %dl // Load drive83 /*84 * Ok, now that we have a valid drive and partition entry, load the CHS from85 * the partition entry and read the sector from the disk.86 */87 main.5: movw %sp, %di // Save stack pointer88 movb 0x1(%si), %dh // Load head89 movw 0x2(%si), %cx // Load cylinder:sector90 movw $LOAD, %bx // Transfer buffer91 cmpb $0xff, %dh // Might we need to use LBA?92 jnz main.7 // No.93 cmpw $0xffff, %cx // Do we need to use LBA?94 jnz main.7 // No.95 pushw %cx // Save %cx96 pushw %bx // Save %bx97 movw $0x55aa, %bx // Reversed Magic98 movb $0x41, %ah // BIOS: EDD extensions present?99 int $0x13 //100 jc main.6 // No.101 cmpw $MAGIC, %bx // Magic ok?102 jne main.6 // No.103 testb $0x1, %cl // Packet mode present?104 jz main.6 // No.105 popw %bx // Restore %bx106 pushl $0x0 // Set the LBA107 pushl 0x8(%si) // address108 pushw %es // Set the address of109 pushw %bx // the transfer buffer110 pushw $0x1 // Read 1 sector111 pushw $0x10 // Packet length112 movw %sp, %si // Packet pointer113 movw $0x4200, %ax // BIOS: LBA Read from disk114 jmp main.8 // Skip the CHS setup115 main.6: popw %bx // Restore %bx116 popw %cx // Restore %cx117 main.7: movw $0x201, %ax // BIOS: Read from disk118 main.8: int $0x13 // Call the BIOS119 movw %di,%sp // Restore stack120 jc err_loading_os // If error121 /*122 * Now that we've loaded the bootstrap, check for the magic 0xaa55 signature.123 * If it is present, execute the bootstrap we just loaded.124 */125 cmpw $MAGIC, 0x1fe(%bx) // Bootable?126 jne err_missing_os // No127 jmp *%bx // Invoke bootstrap128 /*129 * Various error message entry points.130 */131 err_partition_table:132 movw $msg_partition_table, %si // "Invalid partition table"133 jmp putString //134 135 err_loading_os:136 movw $msg_loading_os, %si // "Error loading operating system"137 jmp putString //138 139 err_missing_os:140 movw $msg_missing_os, %si // "Missing operating system"141 jmp putString //142 /*143 * Output an ASCIZ string to the console via the BIOS.144 */145 putString.0:146 movw $0x7, %bx // Page:attribute147 movb $0xe, %ah // BIOS: Display character148 int $0x10 //149 putString:150 lodsb // Get character151 testb %al,%al // End of string?152 jnz putString.0 // No153 putString.1:154 jmp putString.1 // Await reset155 156 msg_partition_table: .asciz "Invalid partition table"157 msg_loading_os: .asciz "Error loading operating system"158 msg_missing_os: .asciz "Missing operating system"159 160 .org PT_OFF161 162 partition_table:163 .fill 0x10,0x4,0x0 // Partition table164 .word MAGIC // Magic number -
src/bin/writembr/hybrid_mbr.S
1 # 2 # Partly from: 3 # $FreeBSD: src/sys/boot/i386/pmbr/pmbr.s,v 1.2 2007/11/26 21:29:59 jhb Exp $ 4 # 5 # Copyright (c) 2007 Yahoo!, Inc. 6 # All rights reserved. 7 # Written by: John Baldwin <jhb@FreeBSD.org> 8 # 9 # Redistribution and use in source and binary forms, with or without 10 # modification, are permitted provided that the following conditions 11 # are met: 12 # 1. Redistributions of source code must retain the above copyright 13 # notice, this list of conditions and the following disclaimer. 14 # 2. Redistributions in binary form must reproduce the above copyright 15 # notice, this list of conditions and the following disclaimer in the 16 # documentation and/or other materials provided with the distribution. 17 # 3. Neither the name of the author nor the names of any co-contributors 18 # may be used to endorse or promote products derived from this software 19 # without specific prior written permission. 20 # 21 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 # SUCH DAMAGE. 32 # 33 34 # 35 # Partly from: 36 # $FreeBSD: src/sys/boot/i386/mbr/mbr.s,v 1.7 2004/08/28 08:39:35 yar Exp $ 37 # 38 # Copyright (c) 1999 Robert Nordier 39 # All rights reserved. 40 # 41 # Redistribution and use in source and binary forms are freely 42 # permitted provided that the above copyright notice and this 43 # paragraph and the following disclaimer are duplicated in all 44 # such forms. 45 # 46 # This software is provided "AS IS" and without any express or 47 # implied warranties, including, without limitation, the implied 48 # warranties of merchantability and fitness for a particular 49 # purpose. 50 # 51 52 # 53 # "Hybridisation" and modifications for booting Haiku by Andre' Braga 54 # (me@andrebraga.com), with valuable input from Jean-Loïc Charroud 55 # (jcharroud@free.fr). The modifications contained herein are released into 56 # the Public Domain. 57 # 58 59 # 60 # A 432 bytes MBR IPL (Initial Program Loader) that looks for the UUID of 61 # a Haiku Boot GUID partition and boots it, falling back to MBR partitions if 62 # said UUID isn't found or if the (primary) GPT is corrupted or non-existent. 63 # Its usefulness is in being a versatile, "universal" IPL that supports 64 # both partitioning styles, allowing it to be used transparently and even 65 # facilitating the conversion between partitioning styles, should the need 66 # for more partitions or volumes over 2TiB arise (for instance when cloning 67 # an older disk to a newer, more capacious one). 68 # It also paves the way for Haiku to create and support booting from 69 # multiple volumes larger than 2TiB, which we're in the very privileged 70 # position of enjoying efficiently in the near future due to BFS. Another use 71 # case is taking a disk from a Intel EFI machine, plugging it on a BIOS 72 # machine and boot just fine; and vice-versa. 73 # As mentioned, if there are valid partitions defined in the MBR, and the 74 # primary GPT becomes corrupt, it can fall back to loading the MBR partition 75 # with the active flag set, if one is defined. 76 # Currently there's no provision for falling back to the GPT copy that 77 # lives in the end of the disk, due to the 512 bytes constraint; supporting 78 # this is unlikely given that the code is packed tight. An alternative would be 79 # disabling support for booting from MBR using BIOS calls other than Int13h 80 # function 42h, "Extended Read From Disk" (i.e., LBA mode). It's unlikely that 81 # any machine that Haiku supports won't have this BIOS function, but having an 82 # "universal" IPL should be quite useful to, say, people using Haiku to 83 # rewrite a corrupt MBR on another disk using the excellent DiskProbe. 84 # The number of sectors loaded depends on the boot style. Booting from a 85 # MBR partition assumes that the Partition Boot Record is one sector long, 86 # whereas booting from a GPT partition assumes a partition exclusive for a 87 # system loader and will either copy its entirety into memory starting from 88 # address 0x7c00, or will copy up to circa 545KiB, whichever is smaller. Thus, 89 # it remains compatible with the FreeBSD gptloader and should work for loading 90 # Bootman from an exclusive Haiku boot manager partition as well. 91 # It should be easy to adjust the UUID signature as needed. It lives at 92 # offset 0x1a0 (416), leaving plenty of space before the 32-bit disk signature 93 # at offset 0x1b8 (440), so compatibility with Microsoft Windows and other OSs 94 # is maintained. 95 # 96 97 .ifndef VALIDATE_DRV 98 .set VALIDATE_DRV,0 99 .endif 100 .set LOAD,0x7c00 # Load address 101 .set EXEC,0x600 # Execution address 102 .set MAGIC,0xaa55 # Magic: bootable 103 .set HANDSHAKE,0x55aa # Int13h EDD handshake 104 .set SECSIZE,0x200 # Size of a single disk sector 105 106 .set UUID,0x1a0 # Boot partition UUID offset 107 .set DISKSIG,0x1b8 # Disk signature offset 108 .set PT_OFF,0x1be # Partition table offset 109 110 .set GPTSTACK,EXEC+SECSIZE*4-8 # Stack address 111 .set LBABUF,GPTSTACK # LBA address pointer buffer, 112 # 8 bytes long, after stack 113 114 .set GPT_ADDR,LBABUF+8 # GPT header address 115 .set GPT_SIG,0 # Signature offset from LBA 1 116 .set GPT_SIG_0,0x20494645 # "EFI ", bswapped 117 .set GPT_SIG_1,0x54524150 # "PART", bswapped 118 .set GPT_MYLBA,24 # Offs of curr header copy addr 119 .set GPT_PART_LBA,72 # Offs of partitions start LBA 120 .set GPT_NPART,80 # Offs to number of partitions 121 .set GPT_PART_SIZE,84 # Offs to size of partition 122 .set PART_ADDR,GPT_ADDR+SECSIZE # GPT partition array addr. 123 .set PART_TYPE,0 124 .set PART_START_LBA,32 # Offs to 1st LBA on part entry 125 .set PART_END_LBA,40 # Offs to last LBA 126 127 .set NHRDRV,0x475 # Number of hard drives 128 129 .globl start # Entry point 130 .code16 131 132 # 133 # Setup the segment registers for flat addressing and setup the stack. 134 # 135 start: cli # Clear interrupts before relocation 136 137 xorw %ax,%ax # Zero 138 movw %ax,%es # Address 139 movw %ax,%ds # data 140 141 movw %ax,%ss # Set up 142 movw $GPTSTACK,%sp # stack 143 144 std # String ops set to decrement 145 movw $LOAD,%si # We'll clear working memory starting 146 leaw -1(%si),%di # from $LOAD-1 and stopping at EXEC. 147 movw $(LOAD-EXEC-1),%cx # In the end we have %si pointing 148 rep stosb # at LOAD and %di at EXEC. 149 150 151 # 152 # Relocate ourself to a lower address so that we have more room to load 153 # other sectors. 154 # 155 reloc: cld # String ops set to increment 156 movw $SECSIZE,%cx # Now we walk forward and relocate. 157 rep movsb # Tricky, but works great! 158 159 # 160 # Jump to the relocated code. 161 # 162 jmp $0,$main # Absolute address (far) jump 163 164 # 165 # Will land here; we're now at %cs = 0x0000 and %ip a little above 0x0600 166 # 167 main: sti # Re-enable interrupts 168 169 .if VALIDATE_DRV 170 # 171 # Validate drive number in %dl. Certain BIOSes might not like it. 172 # 173 validate_drv: cmpb $0x80,%dl # Drive valid? (>= 0x80) 174 jb validate_drv.1 # No 175 movb NHRDRV,%dh # Calculate the highest 176 addb $0x80,%dh # drive number available 177 cmpb %dh,%dl # Within range? 178 jb test_extensions # Yes, proceed 179 validate_drv.1: movb $0x80,%dl # Else, assume drive 0x80 180 .endif 181 182 # 183 # Test if BIOS supports Int13h extensions. If so, will try GPT scheme first. 184 # Else, sets flag (%dh = 1) and goes straight to MBR code. 185 # (%dl still contains the drive number from BIOS bootstrap) 186 # 187 test_extensions: 188 movb $0,%dh # We'll test for EDD extensions. 189 # LBA read (Int13,42) uses only 190 # %dl to get drive number and if 191 # we must fall back to CHS read 192 # (Int13,02), %dh receives head 193 # number, so it's clear to use 194 # %dh to hold a "use CHS" flag 195 196 movw $HANDSHAKE,%bx # EDD extensions magic number 197 movb $0x41,%ah # BIOS: EDD extensions 198 int $0x13 # present? 199 jc set_chs # No, fall back to CHS read 200 201 test_magic: cmpw $MAGIC,%bx # Magic ok? 202 jne set_chs # No, fall back to CHS read 203 204 test_packet: testb $0x1,%cl # Packet mode present? 205 jnz load_gpt_hdr # Yes! 206 207 set_chs: movb $1,%dh # read_chs overwrites this, and 208 # Int13,42 only uses %dl, so 209 # it's clear to use %dh as flag 210 jmp try_mbr 211 212 213 # 214 # If we reached here, drive is valid, LBA reads are available, will try GPT. 215 # Load the primary GPT header from LBA 1 and verify signature. 216 # 217 load_gpt_hdr: movw $GPT_ADDR,%bx 218 movw $LBABUF,%si # Will load LBA sector 1 from disk 219 movb $1,(%si) # (64-bit value! Memory was zeroed so 220 # it's OK to write only the LSB) 221 call read 222 cmpl $GPT_SIG_0,GPT_ADDR+GPT_SIG 223 jnz try_mbr # If invalid GPT header 224 cmpl $GPT_SIG_1,GPT_ADDR+GPT_SIG+4 225 jnz try_mbr # Fluke :( Try MBR now 226 227 # 228 # GPT is valid. Load a partition table sector from disk and look for a 229 # partition matching the UUID found in boot_uuid. 230 # 231 load_part: movw $GPT_ADDR+GPT_PART_LBA,%si 232 movw $PART_ADDR,%bx 233 call read 234 scan: movw %bx,%si # Compare partition UUID 235 movw $boot_uuid,%di # with Haiku boot UUID 236 movb $0x10,%cl # (16 bytes) 237 repe cmpsb 238 jnz next_part # Didn't match, next partition 239 240 # 241 # We found a partition. Load it into RAM starting at 0x7c00. 242 # 243 movw %bx,%di # Save partition pointer in %di 244 leaw PART_START_LBA(%di),%si 245 movw $LOAD/16,%bx 246 movw %bx,%es 247 xorw %bx,%bx 248 load_bootcode: push %si # Save %si 249 call read 250 pop %si # Restore 251 movl PART_END_LBA(%di),%eax # See if this was the last LBA 252 cmpl (%si),%eax 253 jnz next_boot_lba 254 movl PART_END_LBA+4(%di),%eax 255 cmpl 4(%si),%eax 256 jnz next_boot_lba 257 jmp start_loader # Jump to boot code 258 259 next_boot_lba: incl (%si) # Next LBA 260 adcl $0,4(%si) 261 mov %es,%ax # Adjust segment for next 262 addw $SECSIZE/16,%ax # sector 263 cmp $0x9000,%ax # Don't load past 0x90000, 264 jae start_loader # 545k should be enough for 265 mov %ax,%es # any boot code. :) 266 jmp load_bootcode 267 268 # 269 # Move to the next partition. If we walk off the end of the sector, load 270 # the next sector. 271 # 272 next_part: decl GPT_ADDR+GPT_NPART # Was this the last partition? 273 jz try_mbr # UUID boot signature not found 274 movw GPT_ADDR+GPT_PART_SIZE,%ax 275 addw %ax,%bx # Next partition 276 cmpw $PART_ADDR+0x200,%bx # Still in sector? 277 jb scan 278 incl GPT_ADDR+GPT_PART_LBA # Next sector 279 adcl $0,GPT_ADDR+GPT_PART_LBA+4 280 jmp load_part 281 282 # 283 # If loading boot sectors from a GPT partition fails, try booting a MBR part. 284 # Reset stack/segment. Could have been tainted by the GPT loading code. 285 # 286 try_mbr: xorw %ax,%ax # Zero 287 movw %ax,%es # extra segment 288 movw $LOAD,%sp # Reset stack 289 290 xorw %si,%si # Will point to active partition 291 movw $partbl,%bx # Point to partition table start 292 movw $0x4,%cx # Tested entries counter (4 total) 293 read_mbr_entry: cmpb %ch,(%bx) # Null entry? (%ch just zeroed) 294 je next_mbr_entry # Yes 295 jg err_part_table # If 0x1..0x7f 296 testw %si,%si # Active already found? 297 jnz err_part_table # Yes 298 movw %bx,%si # Point to active 299 next_mbr_entry: addb $0x10,%bl # Till 300 loop read_mbr_entry # done 301 testw %si,%si # Active found? 302 jnz read_bootsect # Yes, read OS loader 303 try_diskless: int $0x18 # Else, BIOS: Diskless boot 304 305 306 # 307 # Ok, now that we have a valid drive and partition entry, load either CHS 308 # or LBA from the partition entry and read the boot sector from the partition. 309 # 310 read_bootsect: movw %sp,%bx # Write addr. (%sp points to LOAD) 311 pushw %si # Points at active part. entry; 312 # save, else 'read' will trash it 313 314 test_flag: cmpb $1,%dh # Test flag set by set_chs above 315 jz read_chs # CHS read if set 316 317 read_lba: addw $0x8,%si # Start LBA of partition, 32-bit 318 movw $LBABUF,%di # So far either QWORD 1 or 0, so 319 movsl # top significant bytes are all 0 320 xchg %di,%si # Copy to buffer and swap pointers 321 subw $0x4,%si # Adjust back to start of buffer 322 call read 323 jmp finished_read # Skip the CHS setup 324 325 read_chs: movb 0x1(%si),%dh # Load head 326 movw 0x2(%si),%cx # Load cylinder:sector 327 movb $2,%al # Read two sectors 328 movb $2,%ah # BIOS: Read sectors from disk 329 int $0x13 # Call the BIOS 330 331 finished_read: jc err_reading # If error 332 333 334 # 335 # Now that we've loaded the bootstrap, check for the 0xaa55 signature. If it 336 # is present, execute the bootstrap we just loaded. 337 # 338 popw %si # Restore %si (active part entry) 339 movb %dl,(%si) # Patch part record with drive num 340 cmpw $MAGIC,0x1fe(%bx) # Bootable? 341 jne err_noboot # No, error out. 342 # Else, start loader 343 344 start_loader: xorw %ax,%ax 345 movw %ax,%es # Reset %es to zero 346 jmp $0,$LOAD # Jump to boot code 347 348 349 ################################################################################ 350 351 # Auxiliary functions 352 353 354 # 355 # Load a sector (64-bit LBA at %si) from disk %dl into %es:%bx by creating 356 # a EDD packet on the stack and passing it to the BIOS. Trashes %ax and %si. 357 # 358 read: pushl 0x4(%si) # Set the LBA 359 pushl 0x0(%si) # address 360 pushw %es # Set the address of 361 pushw %bx # the transfer buffer 362 pushw $0x1 # Read 1 sector 363 pushw $0x10 # Packet length 364 movw %sp,%si # Packet pointer 365 movw $0x4200,%ax # BIOS: LBA Read from disk 366 int $0x13 # Call the BIOS 367 add $0x10,%sp # Restore stack 368 jc err_reading # If error 369 ret 370 371 372 # 373 # Output an ASCIZ string pointed at by %si to the console via the BIOS. 374 # 375 putstr.0: movw $0x7,%bx # Page:attribute 376 movb $0xe,%ah # BIOS: Display 377 int $0x10 # character 378 putstr: lodsb # Get character 379 testb %al,%al # End of string? 380 jnz putstr.0 # No 381 ret 382 383 384 # 385 # Various error message entry points. 386 # 387 err_part_table: movw $msg_badtable,%si # "Bad Part. Table!" 388 call putstr 389 jmp halt 390 391 392 err_reading: movw $msg_ioerror,%si # "Read Error!" 393 call putstr 394 jmp halt 395 396 397 err_noboot: movw $msg_noloader,%si # "No Sys Loader!" 398 call putstr 399 # jmp halt # ("halt" is right here) 400 401 402 halt: cli 403 hlt 404 jmp halt 405 406 407 ############################################################################### 408 409 # Data section 410 411 412 # Error messages 413 414 .if VALIDATE_DRV 415 # Messages must be shortened so the code fits 440 bytes 416 msg_badtable: .asciz "BadPTbl!" 417 msg_ioerror: .asciz "IOErr!" 418 msg_noloader: .asciz "NoSysLdr!" 419 .else 420 msg_badtable: .asciz "Bad Part. Table!" 421 msg_ioerror: .asciz "Read Error!" 422 msg_noloader: .asciz "No Sys Loader!" 423 .endif 424 425 426 # Boot partition UUID signature 427 428 .org UUID,0x0 # Zero-pad up to UUID offset 429 430 boot_uuid: .long 0x42465331 # 'BFS1' (formally, UUID time-low) 431 .word 0x3ba3 # UUID time-mid 432 .word 0x10f1 # UUID time-high & version (v1) 433 .byte 0x80 # UUID DCE 1.1 variant 434 .byte 0x2a # '*' (formally, UUID clock-seq-low) 435 .byte 0x48 # 'H' 436 .byte 0x61 # 'a' 437 .byte 0x69 # 'i' 438 .byte 0x6b # 'k' 439 .byte 0x75 # 'u' 440 .byte 0x21 # '!' 441 442 # Disk signature 443 444 .org DISKSIG,0x0 # Zero-pad up to signature offset 445 446 sig: .long 0 # OS Disk Signature 447 .word 0 # "Unknown" in PMBR 448 449 450 # Partition table 451 452 .org PT_OFF,0x0 # Won't pad, just documenting 453 454 partbl: .fill 0x10,0x4,0x0 # Partition table 455 .word MAGIC # Magic number