Grub Boot Analysis Stage1

Source: Internet
Author: User
Tags abs

Original URL:

Http://blog.chinaunix.net/uid-24774106-id-3497929.html

=============================================


Introduction

People playing Linux, will certainly have heard of grub this magical thing, that is, when the boot up to pull down a menu let us choose the operating system of that dongdong. I am lazy, I have not thoroughly pondered this grub working principle flow. Recently working on a grub-related issue, it took some time to learn about grub.

Gossip less. Let's first look at the Linux startup process flowchart:


This flowchart is Daniel M. Tim Jones was drawn in the inside Linux boot process. A clear show shows us what the computer does when we start the button. What I want to share today is the Stage1 bootloader part, and the Stage2 bootloader part.


Need to know, just enter Stage1 bootloader, the operating system has not started to run (nonsense, grbu his elderly is called the operating system), there is no file system concept, that directly run the operating system executable file, you can wash and sleep, Grub his old man is facing a impoverished situation.


Below I began to learn grub. Of course, now the mainstream desktop has already used the Grub 2,grub 0.9x system now collectively known as Grub Legacy, only fix bugs, no longer develop new feature. But many of the company's servers run on grub. For example, our product is still grub. The following experiments I have done are based on the 2.6.24 kernel operating system, unlike the Ubuntu operating system at home.


MBR and Stage1

The MBR is the abbreviation for the Master boot record, which is the master boot records. Knowing my blog, I wrote an article last year that analyzed the zoning information in the MBR. We jump to the/boot/grub/grub directory, you can see a file called Stage1, of course, there are stage2, a little ann not dry, we will slowly mention. We download a grub 0.95 or grub 0.97 code and we can see that there is a stage1 in the Stage1 directory. The assembly file of S. What is the relationship between them.

First, the MBR. MBR is a disk of 0 cylinders, 0 tracks, 1 sectors (sectors from 1 start counting), since it is a sector, size is determined, is 512 bytes. The MBR is strictly said to consist of three parts

[0,0x1be] The first 446 bytes are bootstrap code area, is a program · [0x1be,0x1fe), 64 bytes, is the partition table information. I have a key analysis in the previous blog post. [0X1FE,0X1FF], signature information, is that these two bytes are 55AA.


Careful bobbin can be found that the size of the/boot/grub/stage1 file is also 512 bytes a sector so large. We can compare the contents of the MBR and/boot/grub/stage1 files. Getting the MBR method is simpler, DD is OK, as follows:

DD IF=/DEV/SDA of=mbr_0_512 bs=512 count=1

In this way, we get the 0 cylinder surface of the disk, the contents of the 0 Track 1 sectors, that is, the MBR, stored in the mbr_0_512 file: Look at the contents of the file:

Under the/boot/grub/directory is the Stage1 file. (Don't be misled by images, I just copy stage1 files to my working directory)


You can see that these two files are mostly the same, in fact this part of the code is the same, as for the different places is [0x1b8, 0X1BB) This part of the optional disk Signature,windows products will use these 4 bytes, These 4 bytes are not available for Linux and grub.


2 [0x40, 0x50] Part of the difference, I temporarily do not understand

The conclusion is that the code portion of the/boot/grub/stage1 file and master boot record MBR is the same. In fact, this code is stage1/stage1 from the grub source code. s compiled out of. Stage1. S is grub's first file, then compiled after the code generated, exactly 512 bytes, not exactly, is necessary, otherwise can not put into 1 sectors.

The information for this MBR is set up by grub, as follows:


stage1 Source Analysis

Stage1 phase of the source code is the grub source stage/stage1. S, unfortunately he is Love at&t style of assembly, tortured me seven meat eight vegetarian, and looked at some of the online predecessors of the article, finally have some experience. Or I often say that sentence, glory belongs to the predecessor.


Where does the story start, or from the moment we press the power switch? Oh.


When we press the Power-on key to enter the system boot phase, what bios, post (power-on Self test, Power on self-test), anyway, it's a tantric term, and these are the things that we don't care about, we start with the last thing the system BIOS does, BIOS last thing: Boot the MBR from a floppy disk, hard drive, or optical drive based on the user-specified boot sequence. This procedure determines which boot device to boot from by comparing the end two bits of the location where the MBR is placed, in the order in which it is 0xaa55. After the determination, the MBR content of the boot device is read into the 0x7c00 position, and the last two digits are judged again, and then after the detection is correct, the guidance of phase 1 is performed, from which the second phase Stage1 bootloader phase is entered.


Simply put, the BIOS performs an int 0x19, loads the MBR content to 0x7c00, and then jumps to execute


Wait, why is 0x7c00 position? I visit the famous doctors, finally found a related blog "for why the BIOS will MBR read into the 0X7C00 address (under the x86 platform)", this brother to the system startup is also quite interested, there are a lot of blog writing is excellent, I learned a lot with him. A good English package can look directly at the why BIOS loads MBR into 0x7c00 in x86.


To put it simply, 0x7c00=32kb-1024b is the last KB of 32K, this magic number is not Intel's decision, so we can't find this magic number in X86 related documents, this magic number belongs to BIOS specifiction. This 0x7c00 is determined by the IBM PC 5150 BIOS developer team.


BIOS developer Team decided 0x7c00 Because:they wanted to leave as much room as possible for the OS to load itself within The 32KiB. 8086/8088 used 0x0-0x3ff for interrupts vector, and BIOS data area is after it. The boot sector is bytes, and stack/data area for boot program needed more bytes. So, 0x7c00, the last 1024B of 32KiB is chosen.

Ran for half a day, and we went on. We loaded the MBR code into the 0X7C00 and started executing the codes at the MBR, which focused on the code at the MBR, the stage1/stage1 in the grub source. S

        JMP AFTER_BPB
        NOP/* Do I care about this??? * *

        = _start + 4

The beginning is a jump instruction, jump directly to AFTER_BPB, the back of the NOP will not be implemented. ATER_BPB is defined later: for MBR binaries:


The first two bytes 0xeb48,eb is the jmp instruction, the third byte is 0x90, and this byte is the NOP instruction.

    AFTER_BPB:/* General

    Setup */CLI/*     we ' re not safe here! *
         * * *-a workaround for buggy BIOS es which don ' t pass boot
         * drive correctly. If GRUB is installed to a HDD, do
         * "Orb $0x80,%dl", otherwise "orb $0x00,%dl" (i.e. NOP).
         */
        . Byte   0x80, 0xca

The first is the CLI directive, disabling interrupts and then displaying the 80CA binary code. Look at the annotation, the meaning of this 80ca is Orb $0x80,%dl. The value of the DL register is 80.

DL = 00h 1st floppy disk ("Drive A:")
DL = 01h 2nd floppy disk ("Drive B:")
dl = 80h 1st hard disk
DL = 81H 2nd hard Disk

Because we are a disk-loaded MBR, we have 0x80 in our DL. Next Analysis:

        LJMP    $, $ABS (Real_start)

    Real_start:/

        * Set up%ds and%ss as offset from 0 */
        xorw    %ax,%ax
        MOVW    %ax,%ds
        movw    %ax,%SS/* Set up the real

        stack * * * MOVW    $STAGE 1_stackseg,%sp

        STI     * we ' re safe again * *
        Mov_mem_to_al (ABS (boot_drive))/  * MOVB ABS (boot_drive),%al/
        cmpb    $GRUB _invalid_drive,
        %al JE  1f
        movb    %al,%DL

Enter Real_start, Ax clear Zero, DS assignment 0,ss assignment 0, assign stage1_stackseg (0x2000) to SP, so set the stack segment address (stack top position) SS:SP = 0x0000:0x2000 in real mode. The interrupt allowed bit is then placed. The value in the DL register is then copied to the Al register, then the value of the AL register and the 0xFF comparison, for our scenario, we are in Al is 0x80, so, not equal to 0xFF, do not jump, continue to perform the 0x80 copy of Al to the DL register.

    1:/
        * Save Drive Reference thing!/
        pushw   %dx/

        * Print a notification
        message on the screen * * MSG (notification_string)/* Do not

        probe LBA if the drive is a floppy/
        testb   $STAGE 1_bios_hd_flag,%dl
        J Z  chs_mode/

        * check if LBA supported * *
        MOVB    $0x41,%ah movw $0x55aa    ,%bx
        int $ 0x13

Notification_string is grub, this section up to MSG is showing grub to the screen, because this msg is the detail and we press no table. Always the effect is that the screen shows grub. As we recall, the MBR content has the following information:



Testb this part is to detect whether the drive is a hard disk, if not the hard disk is a floppy disk, directly using Chs_mode, do not bother to judge. We know that the 80h and 81h are hard drives, so the probe corresponds to bit bit. If our boot device is a hard drive, press it we need to detect if LBA is supported.

Using the BIOS call INT 0x13 to determine whether the extension is supported, the LBA extension feature is divided into two subsets, as follows:

    The first subset provides the functionality necessary to access a large hard drive, including:

    ****************************************************************
    1. Check for extension presence: Ah  = 41h, bx = 0x55aa, DL = Drive (0x80 ~ 0xff)
    2. Extended read: Ah = 42h
    3. Extended write: Ah = 43h
    4. Verify sector: Ah = 44h
    5. Extended positioning : Ah = 47h
    6. Get drive parameters: Ah = 48h
    ****************************************************************

    The second subset provides support for locking and ejecting software control drives, including:
    ****************************************************************
    1. Check for extensions : Ah = 41h
    2. Lock/unlock drive: Ah = 45h
    3. Eject drive: Ah = 46h
    4. Get drive parameters: Ah = 48h
    5. Get extended drive change state: Ah = 49h
    ****************************************************************

We're using ah=41h,bx=0x55aa,dl=0x80, so check to see if the extension exists. This action will change the value of the CF flag bit. If you support LBA, then cf=0, otherwise cf=1.

        /* Use CHS if fails/
        JC  chs_mode
        cmpw    $0xaa55,%bx jne chs_mode/

        * Check if ah=0x42 is supported If Force_lba
        is zero/Mov_mem_to_al (ABS (FORCE_LBA))/   * MOVB ABS (FORCE_LBA),%al * * testb   %al,%al< C11/>jnz Lba_mode
        andw    $,%cx
        JZ  Chs_mode

We just had the BIOS use INT 0x13 to detect whether to use LBA mode. There are the following concentrations: Boot device is not 0x80,0x81, do not probe, directly using CHS mode to detect the results cf=1, apart, jump to CHS mode cf=0 whether the use of LBA. Also not necessarily, also need to judge BX==0X55AA,BX==0X55AA, adopt LBA mode, otherwise CHS mode

There is a Force_lba Byte, and if this bit is 1, then the LBA MODE is used directly, which is the bit.

0x41 corresponds to the 00, indicating that Force_lba is zero.

Next, is the flower opens two, each table one branch, one is called CHS, the other is called the LBA mode. CHS has become an anachronism, and it is the legacy of a time when hard disk capacity is small.

C means cylinders

H denotes heads

s represents sectors

which

The number of heads (Heads) indicates that the hard disk has a total of several heads, that is, several disks, the maximum number is 255 (8 bits storage). Numbering starting from 0.

The number of cylinders (cylinders) indicates that there are several tracks on each side of the hard disk, with a maximum number of 1023 (10 bits storage). Numbering starting from 0.

The number of sectors (sectors) indicates that there are several sectors on each track, with a maximum number of 63 (stored in 6 bits). Numbering starting from 1.


And now the hard disk is much larger than 8.414 GB (in accordance with the hard disk manufacturers commonly used in the calculation), CHS addressing methods can not meet the requirements. But so far, the hard drive parameter is often said to be the old CHS parameter. So why use these parameters. Backward

Since CHS is already out of date, we don't have to waste our time on it (so, how does it look like Chen Shimei?) Our focus is on LBA MODE.

        Lba_mode:/* Save the total number of sectors * * * MOVL 0x10 (%si),%ECX/* s Et%si to the disk address packet/MOVW $ABS (disk_address_packet),%si/* Set the mode to No N-zero * * MOVB $1 (%si) movl ABS (stage2_sector),%EBX/* The size and the R

            eserved byte */MOVW $0x0010, (%si)/* Blocks $2 (MOVW)  /* The absolute address (low bits)/MOVL%EBX, 8 (%SI)/* The segment of buffer address
            * * MOVW $STAGE 1_bufferseg, 6 (%si) xorl%eax,%eax MOVW%ax, 4 (%SI)
         MOVL%eax,%si/* 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 */MOVB $0x42,%ah int $0x13/* LBA Read is not supp  Orted, so fallback to CHS.
 * * JC Chs_mode MOVW $STAGE 1_bufferseg,%BX jmp copy_buffer

The address of the label Disk_address_packet is then assigned to SI, then the [si-1] memory Disposition 1 (that is, mode is set to 1, which means that the LBA extension reads; if it is 0, it is CHS addressing read).

MOVL ABS (Stage2_sector),%EBX, passes the number of sectors to be loaded or copied to the EBX registers.

    The memory pointed to by SI and its offset holds the disk parameter block, as follows:
    ******************************************************************
    Offset Size number description
    00h byte 8 block size (10h or 18h)
    01h BYTE 8 reserved, must be 0
    02h WORD 16 Transmission data block number, transmission completed after the transmission of the number of blocks
    04h DWORD 32 transmission data cache address
    08h Qword 64 Initial absolute sector area code (that is, the LBA number of the starting sector)
    ******************************************************************

Or as shown in the following illustration:

MOVW    $0x0010, (%SI) The results of the                      implementation are si[0] =10h, si[1]=00h MOVW    $2 (%si)                          The results of the implementation are si[2] =01h, si[3]=00h
/* The segment of buffer address    /MOVW $STAGE 1_bufferseg, 6 (%si)           the execution of the demerit is SI [ 6]=00h si[7]=07h

movl    ABS (stage2_sector),%ebx movl%ebx    , 8 (%si)

stage2_sector:
    . Long   1

The offset of this stage2_sector in the binary file is 0x44

We si[8] The long type stored is the LBA number of the starting sector, from sector 1th, which is 0 cylinders, 0 tracks, and 2 sectors. , Si [2] Record how many sectors to transfer, the value of 1, only one block of data, after reading, the contents of the sector to the SI offset 04h 05h 6h, 7h identified memory area 0x7000:0x0000. This is the function of int 13h (42).

The last piece of code is

Copy_buffer:
movw    ABS (stage2_segment),%es

/
 * We need to save%cx and%si because the startup code IN
  * Stage2 uses them without initializing.
 * *
pusha
pushw   %ds

movw $0x100,    %cx   //Cycle 0x100 times, that is, 256 times MOVW%bx    ,
%ds xorw    %si,%si
xorw    %di,%di

CLD

Rep
movsw                  //Copy 2 bytes at a time, a word

popw    %ds
Popa

/* boot stage2
/jmp * (stage2_address)

The meaning of this code is to move the 512 bytes that were just moved to 0x7000:000 and move to 0x8000:0000 again.


OK, we tracked the stage1 very painfully. s code, the final conclusion is: Stage1. s This compiled 512 byte code is to the 0 cylinder, 0 tracks, 2 sectors of 512 bytes copy to the 0x8000 place.


Very disappointed, it took a long time, finally got so little conclusion. Life is so, pay does not necessarily have a return, for us, just try, not ask the future, to live calmly.


What are the 512 bytes we read? When will you see GRUB's Choice OS interface? Rivers and lakes Legends of the Stage2 in the end is how, the river stage1.5 is how the story of the legend, and listen to let's, I was tired, do not write.


I did a PDF document format, need the package can be downloaded after slowly watching

Grub Boot Analysis Stage1.pdf



Reference documents:

1 STAGE1.S Source Code Analysis (this article is very good, a lot of content is to benefit from this blog post)

2 Wikipedia

3 GRUB Source Code Analysis (a great document)

4 The Mysteries arround "0X7C00" in x86 architecture BIOS bootloader

5 Linux/unix system Boot process (from power to operating system operation)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.