GRUB master boot record - Hardware

This is a discussion on GRUB master boot record - Hardware ; Like the Boot Records of an OS, the first three bytes could be called the Jump Instruction. But only the first two bytes are being used to form the actual JMP (Jump) instruction to the rest of the executable code; ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: GRUB master boot record

  1. GRUB master boot record

    Like the Boot Records of an OS, the first three bytes could be called
    the Jump Instruction. But only the first two bytes are being used to
    form the actual JMP (Jump) instruction to the rest of the executable
    code; the third byte (90h) is just a NOP instruction ('No Op' do
    nothing). So the execution jumps over the 71 next bytes which can be
    thought of as a BIOS Parameter Block (or BPB);
    BIOS parameter block (BPB) is a description of the physical medium
    (hard disk or floppy) that might be stored in a file system’s Volume
    Boot Record. File systems with a BIOS parameter block include FAT16,
    FAT32, HPFS, and NTFS. ECMA-107 or ISO/IEC 9293 (which describes FAT
    as for flexible/floppy and optic distal disk cartridges) also
    describes this as an FDC Descriptor or an FDC Extended Descriptor.


    00000000 EB48 jmp short 0x4a
    00000002 90 nop
    Jump to the start of the program at 0x7c00 and is jumped to with CS:IP
    0:0x7c00.
    Jump over BPB data area to main body of code.
    This BPB Data Area (BIOS Parameter Block) is filled with useful data
    for any program examining it as a normal Volume Boot Record.

    The BYTES in the BPB which are referenced in the code below are:

    [00000005] -> 8E D0 BC 00 B0 B8 00 00 8E D8 8E C0 FB BE
    ("Disk Address Packet" for LBA mode.)

    [00000040] -> 80 ("Boot Drive") NOTE: For those of you with multi-
    OS
    booting systems, if your Linux installation with GRUB's
    remaining software (stage2, menu file, etc.) is located
    somewhere other than on the Primary Master drive, this
    value will be 81, 82, etc. depending upon which drive
    that Linux OS's /boot/grub directory is located.

    [00000041] -> 00 ("Force LBA mode byte")
    [00000042] -> 00 80 (8000h) Memory location where GRUB stores the
    next stage of the code to execute.
    [00000044] -> Note: A very important location for anyone using
    GRUB!
    This (4-byte) Quad-Word contains the location of GRUB's
    stage2 file in sectors! You will always see the bytes
    01 00 00 00 in this location whenever GRUB has been
    installed in the first track (Sectors 1 ff.) of an HDD;
    immediately following the GRUB MBR in Absolute Sector 0.

    [00000048] -> 00 08 (800h) [Don't confuse this with the 8000 at
    00000042.]

    00000003 10
    00000004 8E
    00000005 D0
    00000006 BC
    00000007 00
    00000008 B0
    00000009 B8
    0000000A 00
    0000000B 00
    0000000C 8E
    0000000D D8
    0000000E 8E
    0000000F C0
    00000010 FB
    00000011 BE
    00000012 00
    00000013 7C
    00000014 BF
    00000015 00
    00000016 06
    00000017 B9
    00000018 00
    00000019 02
    0000001A F3
    0000001B A4
    0000001C EA
    0000001D 21
    0000001E 06
    0000001F 00
    00000020 00
    00000021 BE
    00000022 BE
    00000023 07
    00000024 38
    00000025 04
    00000026 75
    00000027 0B
    00000028 83
    00000029 C6
    0000002A 10
    0000002B 81
    0000002C FE
    0000002D FE
    0000002E 07
    0000002F 75
    00000030 F3
    00000031 EB
    00000032 16
    00000033 B4
    00000034 02
    00000035 B0
    00000036 01
    00000037 BB
    00000038 00
    00000039 7C
    0000003A B2
    0000003B 80
    0000003C 8A
    0000003D 74
    0000003E 03
    0000003F 02
    00000040 80
    00000041 00
    00000042 00
    00000043 80
    00000044 8B
    00000045 82
    00000046 00
    00000047 00
    00000048 00
    00000049 08


    General setup:

    0000004A FA cli
    This line will Clear Interrupt Flag
    This is a workaround for buggy BIOSes which don't pass boot drive
    correctly. If GRUB is installed into a HDD, check if DL is masked
    correctly. If not, assume that the BIOS passed a bogus value and set
    DL to 0x80, since this is the only possible boot drive. If GRUB is
    installed into a floppy, this does nothing (only jump).

    0000004B EA507C0000 jmp 0x0:0x7c50
    Long Jump to the next instruction because some bogus BIOSes jump to
    07C0:0000 instead of 0000:7C00.

    00000050 31C0 xor ax,ax
    00000052 8ED8 mov ds,ax
    00000054 8ED0 mov ss,ax
    set up %ds and %ss as offset from 0

    00000056 BC0020 mov sp,0x2000
    set up the REAL stack

    00000059 FB sti
    Set Interrupt Flag
    This instruction sets the interrupt flag (IF) in the EFLAGS register.
    After the IF flag is set, the processor begins responding to external,
    mask able interrupts after the next instruction is executed.

    0000005A A0407C mov al,[0x7c40] <<<<<<<< Boot Drive
    Check if we have a forced disk reference here

    0000005D 3CFF cmp al,0xff
    Compare GRUB_INVALID_DRIVE and al

    0000005F 7402 jz 0x63

    jump to the next instruction because some bogus BIOSes jump to
    07C0:0000 instead of 0000:7C00.

    00000061 88C2 mov dl,al

    00000063 52 push dx
    Save drive reference first thing!

    00000064 BE767D mov si,0x7d76
    00000067 E83401 call 0x19e
    Print a notification message on the screen.
    The first line “0x7d76” is the place of the string “GRUB” on memory.
    “0x19e” is the place of the function that print the messageon screen
    that have the following code in GRUB stage1.s code:
    lodsb
    cmpb $0, %al
    jne 1b /* if not end of string, jmp to display */
    ret


    0000006A F6C280 test dl,0x80
    do not probe LBA if the drive is a floppy
    0x80 is STAGE1_BIOS_HD_FLAG that explained before.

    0000006D 7454 jz 0xc3
    Jump to the “0xc3” on the memory if zero flag is set and that named
    “chs_mode” and it determine the hard disk geometry from the BIOS! If
    it happened first, so that LS-120 IDE floppies work correctly.

    0000006F B441 mov ah,0x41
    Function 41h of INT13
    00000071 BBAA55 mov bx,0x55aa
    00000074 CD13 int 0x13
    Test for INT13 Extensions
    Check if LBA is supported
    %dl may have been clobbered by INT 13, AH=41H.
    This happens, for example, with AST BIOS 1.04.

    00000076 5A pop dx
    00000077 52 push dx

    00000078 7249 jc 0xc3
    0000007A 81FB55AA cmp bx,0xaa55
    0000007E 7543 jnz 0xc3
    Use CHS if fails
    “0xc3” is the place of memory whit label “chs_mode” that I explained
    before and will explain more in end of this paper.

    00000080 A0417C mov al,[0x7c41] <<<< Force LBA mode byte
    00000083 84C0 test al,al
    check if AH=0x42 is supported if FORCE_LBA is zero

    00000085 7505 jnz 0x8c
    Jump if “lba_mode”
    00000087 83E101 and cx,byte +0x1
    0000008A 7437 jz 0xc3

    0000008C 668B4C10 mov ecx,[si+0x10]
    Save the total number of sectors

    00000090 BE057C mov si,0x7c05
    Set %si to the disk address packet

    00000093 C644FF01 mov byte [si-0x1],0x1
    Set the mode to non-zero

    00000097 668B1E447C mov ebx,[0x7c44]

    0000009C C7041000 mov word [si],0x10
    The size and the reserved byte

    000000A0 C744020100 mov word [si+0x2],0x1
    The blocks

    000000A5 66895C08 mov [si+0x8],ebx
    The absolute address (low 32 bits)

    000000A9 C744060070 mov word [si+0x6],0x7000
    “0x7000” is the segment of buffer address
    000000AE 6631C0 xor eax,eax

    000000B1 894404 mov [si+0x4],ax

    000000B4 6689440C mov [si+0xc],eax

    000000B8 B442 mov ah,0x42
    000000BA CD13 int 0x13
    BIOS call "INT 0x13 Function 0x42" to read sectors from disk into
    memory
    Call with %ah = 0x42
    %dl = drive number
    %ds:%si = segment : offset of disk address packet
    Return:
    %al = 0x0 on success; err code on failure

    000000BC 7205 jc 0xc3
    LBA read is not supported, so fallback to CHS.

    000000BE BB0070 mov bx,0x7000
    “0x7000” is STAGE1_BUFFERSEG

    000000C1 EB7D jmp short 0x140
    “0x140” is copy_buffer

    The code below is “chs_mode” that I explained a little before.
    Determine the hard disk geometry from the BIOS!
    We do this first, so that LS-120 IDE floppies work correctly.

    000000C3 B408 mov ah,0x8
    Function 08 of INT13

    000000C5 CD13 int 0x13
    Get Drive Parameters

    000000C7 730A jnc 0xd3
    The call failed, so maybe use the floppy probe instead.
    “0xd3” is the place of label final_init
    The call failed, so maybe use the floppy probe instead.

    000000C9 F6C280 test dl,0x80
    “0x80” is a value of STAGE1_BIOS_HD_FLAG

    000000CC 0F84F300 jz near 0x1c3
    “0x1c3” is a label whit name: floppy_probe that I will showthe
    implantation further.

    Nope, we definitely have a hard disk, and we're screwed.

    000000D0 E98D00 jmp 0x160
    Hard disk error * hd_probe_error


    000000D3 BE057C mov si,0x7c05
    000000D6 C644FF00 mov byte [si-0x1],0x0
    set the mode to zero

    000000DA 6631C0 xor eax,eax
    000000DD 88F0 mov al,dh
    save number of heads

    the following code is for final initialize:
    000000DF 40 inc ax
    000000E0 66894404 mov [si+0x4],eax
    save number of cylinders

    000000E4 31D2 xor dx,dx
    000000E6 88CA mov dl,cl
    000000E8 C1E202 shl dx,0x2
    000000EB 88E8 mov al,ch
    000000ED 88F4 mov ah,dh

    000000EF 40 inc ax
    000000F0 894408 mov [si+0x8],ax

    000000F3 31C0 xor ax,ax
    000000F5 88D0 mov al,dl
    000000F7 C0E802 shr al,0x2

    000000FA 668904 mov [si],eax
    save number of sectors

    the following code is for setup sectors:

    000000FD 66A1447C mov eax,[0x7c44]
    load logical sector start (bottom half)

    00000101 6631D2 xor edx,edx
    zero %edx

    00000104 66F734 div dword [si]
    divide by number of sectors

    00000107 88540A mov [si+0xa],dl
    save sector start

    0000010A 6631D2 xor edx,edx
    Zero %edx

    0000010D 66F77404 div dword [si+0x4]
    divide by number of heads

    00000111 88540B mov [si+0xb],dl
    save head start

    00000114 89440C mov [si+0xc],ax
    save cylinder start

    00000117 3B4408 cmp ax,[si+0x8]
    0000011A 7D3C jnl 0x158
    “0x158” is a label with this name geometry_error
    do we need too many cylinders?
    This is the loop for taking care of BIOS geometry translation (ugh!)

    0000011C 8A540D mov dl,[si+0xd]
    get high bits of cylinder

    0000011F C0E206 shl dl,0x6
    shift left by 6 bits

    00000122 8A4C0A mov cl,[si+0xa]
    get sector

    00000125 FEC1 inc cl
    normalize sector (sectors go from 1-N, not 0-(N-1) )

    00000127 08D1 or cl,dl
    composite together

    00000129 8A6C0C mov ch,[si+0xc]
    sector+hcyl in cl, cylinder in ch

    0000012C 5A pop dx
    restore %dx

    0000012D 8A740B mov dh,[si+0xb]
    Head number

    BIOS call "INT 0x13 Function 0x2" to read sectors from disk into
    memory
    Call with %ah = 0x2
    %al = number of sectors
    %ch = cylinder
    %cl = sector (bits 6-7 are high bits of "cylinder")
    %dh = head
    %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
    %es:%bx = segmentffset of buffer
    Return:
    %al = 0x0 on success; err code on failure

    00000130 BB0070 mov bx,0x7000
    “0x7000” is STAGE1_BUFFERSEG

    00000133 8EC3 mov es,bx
    load %es segment with disk buffer

    00000135 31DB xor bx,bx
    %bx = 0, put it at 0 in the segment

    00000137 B80102 mov ax,0x201
    0000013A CD13 int 0x13 function 2 of int13

    0000013C 722A jc 0x168
    “0x168” is labeb with this name: read_error

    0000013E 8CC3 mov bx,es

    The following code is for copy buffer:

    00000140 8E06487C mov es,[0x7c48]
    We need to save %cx and %si because the startup code in stage2 uses
    them without initializing them.
    00000144 60 pusha
    00000145 1E push ds

    00000146 B90001 mov cx,0x100
    00000149 8EDB mov ds,bx
    0000014B 31F6 xor si,si
    0000014D 31FF xor di,di

    0000014F FC cld
    00000150 F3A5 rep movsw

    00000152 1F pop ds
    00000153 61 popa

    00000154 FF26427C jmp near [0x7c42] WORD <<< 8000 hex.

    boot stage2
    This is where we jump to the next stage of the code which GRUB loaded
    from the HDD into Memory locations 0000:8000 hex and following:

    END OF MAIN LOOP

    Section for Displaying Error Messages:
    BIOS Geometry translation error (past the end of the disk geometry!).

    The following code is for geometry_error:
    00000158 BE7C7D mov si,0x7d7c --"Geom Error"
    0000015B E84000 call 0x19e -- Display it on screen.
    0000015E EB0E jmp short 0x16e -- Finish it and 'lock-
    up'
    Jump to the label “general_error”

    The following code is for hd_probe_error:
    Disk probe failure
    00000160 BE817D mov si,0x7d81 -- "Hard Disk Error"
    00000163 E83800 call 0x19e -- Display it on screen.
    00000166 EB06 jmp short 0x16e -- Finish it and 'lock-up'

    Read error on the disk:
    read_error:
    00000168 BE8B7D mov si,0x7d8b -- "Read Error"
    0000016B E83000 call 0x19e -- Display it on screen

    general_error:
    0000016E BE907D mov si,0x7d90 -- (For displaying "
    Error")
    00000171 E82A00 call 0x19e -- Display it on screen

    stop:
    00000174 EBFE jmp short 0x174
    go here when you need to stop the machine hard after an error
    condition

    Location of the GRUB ID String
    Define string “GRUB ” :
    00000176 47
    00000177 52
    00000178 55
    00000179 42
    0000017A 20
    0000017B 00
    Define string “Geom” :
    0000017C 47
    0000017D 65
    0000017E 6F
    0000017F 6D
    00000180 00

    Define string “Hard Disk”:
    00000181 48
    00000182 61
    00000183 72
    00000184 64
    00000185 20
    00000186 44
    00000187 69
    00000188 73
    00000189 6B
    0000018A 00

    Define string “Read”:
    0000018B 52
    0000018C 65
    0000018D 61
    0000018E 64
    0000018F 00

    Define string “ Error”:
    00000190 20
    00000191 45
    00000192 72
    00000193 72
    00000194 6F
    00000195 72
    00000196 00

    Display Character Subroutine:
    00000197 BB0100 mov bx,0x1

    0000019A B40E mov ah,0xe
    Function 0Eh of INT10

    0000019C CD10 int 0x10
    Display the character

    0000019E AC lodsb

    0000019F 3C00 cmp al,0x0

    000001A1 75F4 jnz 0x197
    if not end of string, jmp to display
    000001A3 C3 ret


    000001A4 00
    000001A5 00
    000001A6 00
    000001A7 00
    000001A8 00
    000001A9 00
    000001AA 00
    000001A8 00
    000001AC 00
    000001AD 00
    000001AE 00
    000001AF 00
    000001B0 00
    000001B1 00
    000001B2 00
    000001B3 00
    000001B4 00
    000001B5 00
    000001B6 00
    000001B7 00



    Finally, GRUB makes sure not to use any of the bytes between offsets
    1B8h and 1BBh because they're used by Microsoft® Windows™ NT/2000/XP/
    2003 as the NT Drive Serial Number; which in our example above is the
    four-byte WORD 00000000h.

    000001B8 00
    000001B9 00
    000001BA 00
    000001BB 00

    000001BC 00
    000001BD 00

    Partition Table in Memory:
    Although GRUB is a Boot Manager, its stage1 code follows the structure
    of all MBRs by placing the standard four-entry Partition Table in its
    agreed upon location (offsets 01BEh through 01FDh) which is followed
    by the standard Word-sized signature ID of AA55h.
    000001BE 80
    000001BF 01
    000001C0 01
    000001C1 00
    000001C2 83
    000001C3 FE
    000001C4 3F
    000001C5 0C
    000001C6 3F
    000001C7 00
    000001C8 00
    000001C9 00
    000001CA 8E
    000001CB 2F
    000001CC 03
    000001CD 00
    000001CE 00
    000001CF 00
    000001D0 01
    000001D1 0D
    000001D2 83
    000001D3 FE
    000001D4 BF
    000001D5 DE
    000001D6 CD
    000001D7 2F
    000001D8 03
    000001D9 00
    000001DA 52
    000001DB FC
    000001DC B0
    000001Dd 00
    000001DE 00
    000001DF 00
    000001E0 81
    000001E1 DF
    000001E2 82
    000001E3 FE
    000001E4 FF
    000001E5 0E
    000001E6 1F
    000001E7 2C
    000001E8 B4
    000001E9 00
    000001EA 30
    000001EB C4
    000001EC 0B
    000001ED 00
    000001EE 00
    000001EF 00
    000001F0 00
    000001E1 00
    000001F2 00
    000001F3 00
    000001F4 00
    000001F5 00
    000001F6 00
    000001F7 00
    000001F8 00
    000001F9 00
    000001FA 00
    000001FB 00
    000001FC 00
    000001FD 00

    000001FE 55
    000001FF AA


  2. Re: GRUB master boot record

    Navid Shakibapour writes:

    > Like the Boot Records of an OS, the first three bytes could be called
    > the Jump Instruction. But only the first two bytes are being used to
    > form the actual JMP (Jump) instruction to the rest of the executable


    I asked on another newsgroup if there was any particular reason to
    post that. But multiple postings to several groups? What possible
    reason could there be for that?

+ Reply to Thread