Home | History | Annotate | Download | only in BootSector
      1 #------------------------------------------------------------------------------
      2 #*
      3 #*   Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
      4 #*   This program and the accompanying materials
      5 #*   are licensed and made available under the terms and conditions of the BSD License
      6 #*   which accompanies this distribution.  The full text of the license may be found at
      7 #*   http://opensource.org/licenses/bsd-license.php
      8 #*
      9 #*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 #*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 #*
     12 #*    gpt.asm
     13 #*
     14 #*   Abstract:
     15 #*
     16 #------------------------------------------------------------------------------
     17 
     18     #.MODEL small
     19 #   .dosseg
     20     .stack:
     21     .486p:
     22     .code16
     23 
     24 .equ                      BLOCK_SIZE,  0x0200
     25 .equ                      BLOCK_MASK,  0x01ff
     26 .equ                      BLOCK_SHIFT, 9
     27 
     28 # ****************************************************************************
     29 # Code loaded by BIOS at 0x0000:0x7C00
     30 # ****************************************************************************
     31 
     32         .org 0x00
     33 Start:
     34 
     35 # ****************************************************************************
     36 # Start Print
     37 # ****************************************************************************
     38 
     39     movw $0xb800, %ax
     40     movw %ax, %es
     41     movw $0x7c0, %ax
     42     movw %ax, %ds
     43     leaw %cs:StartString, %si
     44     movw $10, %cx
     45     movw $160, %di
     46     rep
     47     movsw
     48 
     49 # ****************************************************************************
     50 # Print over
     51 # ****************************************************************************
     52 
     53 # ****************************************************************************
     54 # Initialize segment registers and copy code at 0x0000:0x7c00 to 0x0000:0x0600
     55 # ****************************************************************************
     56         xorw  %ax, %ax                  # AX = 0x0000
     57         movw  $0x7c00, %bx              # BX = 0x7C00
     58         movw  $0x600, %bp               # BP = 0x0600
     59         movw  RelocatedStart, %si       # SI = Offset(RelocatedStart)
     60         movw  $0x200, %cx               # CX = 0x0200
     61         subw  %si, %cx                  # CS = 0x0200 - Offset(RelocatedStart)
     62         leaw  (%bp,%si,), %di           # DI = 0x0600 + Offset(RelocatedStart)
     63         leaw  (%bx,%si,), %si           # BX = 0x7C00 + Offset(RelocatedStart)
     64         movw  %ax, %ss                  # SS = 0x0000
     65         movw  %bx, %sp                  # SP = 0x7C00
     66         movw  %ax, %es                  # ES = 0x0000
     67         movw  %ax, %ds                  # DS = 0x0000
     68         pushw %ax                       # PUSH 0x0000
     69         pushw %di                       # PUSH 0x0600 + Offset(RelocatedStart)
     70         cld                             # Clear the direction flag
     71         rep
     72         movsb                           # Copy 0x0200 bytes from 0x7C00 to 0x0600
     73         retl                            # JMP 0x0000:0x0600 + Offset(RelocatedStart)
     74 
     75 # ****************************************************************************
     76 # Code relocated to 0x0000:0x0600
     77 # ****************************************************************************
     78 
     79 RelocatedStart:
     80 # ****************************************************************************
     81 # Get Driver Parameters to 0x0000:0x7BFC
     82 # ****************************************************************************
     83         xorw  %ax, %ax      # ax = 0
     84         movw  %ax, %ss      # ss = 0
     85         addw  $0x1000, %ax
     86         movw  %ax, %ds
     87 
     88         movw  $0x7c00, %sp  # sp = 0x7c00
     89         movw  %sp, %bp      # bp = 0x7c00
     90 
     91         movb  $8, %ah                             # ah = 8 - Get Drive Parameters Function
     92         movb  %dl, PhysicalDrive(%bp)             # BBS defines that BIOS would pass the booting driver number to the loader through DL
     93         int   $0x13                               # Get Drive Parameters
     94         xorw  %ax, %ax                # ax = 0
     95         movb  %dh, %al                # al = dh
     96         incb  %al                     # MaxHead = al + 1
     97         pushw %ax                     # 0000:7bfe = MaxHead
     98         movb  %cl, %al                # al = cl
     99         andb  $0x3f, %al              # MaxSector = al & 0x3f
    100         pushw %ax                     # 0000:7bfc = MaxSector
    101 
    102 # ****************************************************************************
    103 # Read GPT Header from hard disk to 0x0000:0x0800
    104 # ****************************************************************************
    105         xorw    %ax, %ax
    106         movw    %ax, %es                          # Read to 0x0000:0x0800
    107         movw    $0x800, %di                       # Read to 0x0000:0x0800
    108         movl    $1, %eax                          # Read LBA #1
    109         movl    $0, %edx                          # Read LBA #1
    110         movw    $1, %bx                           # Read 1 Block
    111         pushw   %es
    112         call    ReadBlocks
    113         popw    %es
    114 
    115 # ****************************************************************************
    116 # Read Target GPT Entry from hard disk to 0x0000:0x0A00
    117 # ****************************************************************************
    118         cmpl  $0x20494645, %es:(%di)              # Check for "EFI "
    119         jne   BadGpt
    120         cmpl  $0x54524150, %es:4(%di)             # Check for "PART"
    121         jne   BadGpt
    122         cmpl  $0x00010000, %es:8(%di)             # Check Revision - 0x10000
    123         jne   BadGpt
    124 
    125         movl  %es:84(%di), %eax                   # EAX = SizeOfPartitionEntry
    126         mulb  GptPartitionIndicator(%bp)          # EAX = SizeOfPartitionEntry * GptPartitionIndicator
    127         movl  %eax, %edx                          # EDX = SizeOfPartitionEntry * GptPartitionIndicator
    128         shrl  $BLOCK_SHIFT, %eax                  # EAX = (SizeOfPartitionEntry * GptPartitionIndicator) / BLOCK_SIZE
    129         andl  $BLOCK_MASK, %edx                   # EDX = Targer PartitionEntryLBA Offset
    130                                                   #     = (SizeOfPartitionEntry * GptPartitionIndicator) % BLOCK_SIZE
    131         pushl %edx
    132         movl  %es:72(%di), %ecx                   # ECX = PartitionEntryLBA (Low)
    133         movl  %es:76(%di), %ebx                   # EBX = PartitionEntryLBA (High)
    134         addl  %ecx, %eax                          # EAX = Target PartitionEntryLBA (Low)
    135                                                   #     = (PartitionEntryLBA +
    136                                                   #        (SizeOfPartitionEntry * GptPartitionIndicator) / BLOCK_SIZE)
    137         adcl  %ebx, %edx                          # EDX = Target PartitionEntryLBA (High)
    138 
    139         movw  $0xA00, %di                         # Read to 0x0000:0x0A00
    140         movw  $1, %bx                             # Read 1 Block
    141         pushw %es
    142         call  ReadBlocks
    143         popw  %es
    144 
    145 # ****************************************************************************
    146 # Read Target DBR from hard disk to 0x0000:0x7C00
    147 # ****************************************************************************
    148         popl  %edx                                # EDX = (SizeOfPartitionEntry * GptPartitionIndicator) % BLOCK_SIZE
    149         addw  %dx, %di                            # DI = Targer PartitionEntryLBA Offset
    150         cmpl  $0xC12A7328, %es:(%di)              # Check for EFI System Partition "C12A7328-F81F-11d2-BA4B-00A0C93EC93B"
    151         jne   BadGpt
    152         cmpl  $0x11d2F81F, %es:4(%di)             #
    153         jne   BadGpt
    154         cmpl  $0xA0004BBA, %es:8(%di)             #
    155         jne   BadGpt
    156         cmpl  $0x3BC93EC9, %es:0xc(%di)           #
    157         jne   BadGpt
    158 
    159         movl  %es:32(%di), %eax                   # EAX = StartingLBA (Low)
    160         movl  %es:36(%di), %edx                   # EDX = StartingLBA (High)
    161         movw  $0x7C00, %di                        # Read to 0x0000:0x7C00
    162         movw  $1, %bx                             # Read 1 Block
    163         call  ReadBlocks
    164 
    165 # ****************************************************************************
    166 # Transfer control to BootSector - Jump to 0x0000:0x7C00
    167 # ****************************************************************************
    168         xorw  %ax, %ax
    169         pushw %ax                       # PUSH 0x0000
    170         movw  $0x7c00, %di
    171         pushw %di                       # PUSH 0x7C00
    172         retl                            # JMP 0x0000:0x7C00
    173 
    174 # ****************************************************************************
    175 # ReadBlocks - Reads a set of blocks from a block device
    176 #
    177 # EDX:EAX = Start LBA
    178 # BX      = Number of Blocks to Read (must < 127)
    179 # ES:DI   = Buffer to store sectors read from disk
    180 # ****************************************************************************
    181 
    182 # si = DiskAddressPacket
    183 
    184 ReadBlocks:
    185         pushal
    186         pushw %ds
    187         xorw  %cx, %cx
    188         movw  %cx, %ds
    189         movw  $0x600, %bp                       # bp = 0x600
    190         leaw  AddressPacket(%bp), %si
    191         movb  %bl, %ds:2(%si)                   #    02 = Number Of Block transfered
    192         movw  %di, %ds:4(%si)                   #    04 = Transfer Buffer Offset
    193         movw  %es, %ds:6(%si)                   #    06 = Transfer Buffer Segment
    194         movl  %eax, %ds:8(%si)                  #    08 = Starting LBA (Low)
    195         movl  %edx, %ds:0xc(%si)                #    0C = Starting LBA (High)
    196         movb  $0x42, %ah                        # ah = Function 42
    197         movb  PhysicalDrive(%bp), %dl           # dl = Drive Number
    198         int   $0x13
    199         jc    BadGpt
    200         popw  %ds
    201         popal
    202         ret
    203 
    204 # ****************************************************************************
    205 # Address Packet used by ReadBlocks
    206 # ****************************************************************************
    207 AddressPacket:
    208         .byte 0x10                      # Size of address packet
    209         .byte 0x0                       # Reserved.  Must be 0
    210         .byte 0x1                       # Read blocks at a time (To be fixed each times)
    211         .byte 0x0                       # Reserved.  Must be 0
    212         .word 0x000                     # Destination Address offset (To be fixed each times)
    213         .word 0x000                     # Destination Address segment (To be fixed each times)
    214 AddressPacketLba:
    215         .long 0x0,0x0                   # Start LBA (To be fixed each times)
    216 AddressPacketEnd:
    217 
    218 # ****************************************************************************
    219 # ERROR Condition:
    220 # ****************************************************************************
    221 
    222 BadGpt:
    223     movw $0xb800, %ax
    224     movw %ax, %es
    225     movw $0x60, %ax
    226     movw %ax, %ds
    227     leaw %cs:ErrorString, %si
    228     movw $10, %cx
    229     movw $320, %di
    230     rep
    231     movsw
    232 Halt:
    233     jmp   Halt
    234 
    235 StartString:
    236     .byte 'G', 0x0c, 'P', 0x0c, 'T', 0x0c, ' ', 0x0c, 'S', 0x0c, 't', 0x0c, 'a', 0x0c, 'r', 0x0c, 't', 0x0c, '!', 0x0c
    237 ErrorString:
    238     .byte 'G', 0x0c, 'P', 0x0c, 'T', 0x0c, ' ', 0x0c, 'E', 0x0c, 'r', 0x0c, 'r', 0x0c, 'o', 0x0c, 'r', 0x0c, '!', 0x0c
    239 
    240 # ****************************************************************************
    241 # PhysicalDrive - Used to indicate which disk to be boot
    242 #                 Can be patched by tool
    243 # ****************************************************************************
    244     # .org   0x01B6 # Just for passing build.
    245 PhysicalDrive:        .byte 0x80
    246 
    247 # ****************************************************************************
    248 # GptPartitionIndicator - Used to indicate which GPT partition to be boot
    249 #                         Can be patched by tool
    250 # ****************************************************************************
    251    # .org   0x01B7  # Just for passing build.
    252 GptPartitionIndicator: .byte 0
    253 
    254 # ****************************************************************************
    255 # Unique MBR signature
    256 # ****************************************************************************
    257    # .org   0x01B8  # Just for passing build.
    258     .ascii "DUET"
    259 
    260 # ****************************************************************************
    261 # Unknown
    262 # ****************************************************************************
    263     # .org   0x01BC  # Just for passing build.
    264     .word 0
    265 
    266 # ****************************************************************************
    267 # PMBR Entry - Can be patched by tool
    268 # ****************************************************************************
    269     # .org   0x01BE  # Just for passing build.
    270     .byte 0       # Boot Indicator
    271     .byte 0xff    # Start Header
    272     .byte 0xff    # Start Sector
    273     .byte 0xff    # Start Track
    274     .byte 0xee    # OS Type
    275     .byte 0xff    # End Header
    276     .byte 0xff    # End Sector
    277     .byte 0xff    # End Track
    278     .long 1       # Starting LBA
    279     .long 0xFFFFFFFF # End LBA
    280 
    281     # .org   0x01CE  # Just for passing build.
    282     .long  0,0,0,0
    283     # .org   0x01DE  # Just for passing build.
    284     .long  0,0,0,0
    285     # .org   0x01EE  # Just for passing build.
    286     .long 0,0,0,0
    287 
    288 # ****************************************************************************
    289 # Sector Signature
    290 # ****************************************************************************
    291 
    292   # .org      0x01FE  # Just for passing build.
    293 SectorSignature:
    294   .word     0xaa55      # Boot Sector Signature
    295 
    296 
    297 
    298