The translation is temporarily closed for contributions due to maintenance, please come back later.

Translation

(itstool) path: sect1/para
English
It is worth looking at the <filename>Makefile</filename> for <filename>boot0</filename> (<filename>sys/boot/i386/boot0/Makefile</filename>), as it defines some of the run-time behavior of <filename>boot0</filename>. For instance, if a terminal connected to the serial port (COM1) is used for I/O, the macro <literal>SIO</literal> must be defined (<literal>-DSIO</literal>). <literal>-DPXE</literal> enables boot through <acronym>PXE</acronym> by pressing <keycap>F6</keycap>. Additionally, the program defines a set of <emphasis>flags</emphasis> that allow further modification of its behavior. All of this is illustrated in the <filename>Makefile</filename>. For example, look at the linker directives which command the linker to start the text section at address <literal>0x600</literal>, and to build the output file <quote>as is</quote> (strip out any file formatting):
Context English Chinese (Simplified) (zh_CN) State
The very last thing in the <acronym>POST</acronym> is the <literal>INT 0x19</literal> instruction. The <literal>INT 0x19</literal> handler reads 512 bytes from the first sector of boot device into the memory at address <literal>0x7c00</literal>. The term <emphasis>first sector</emphasis> originates from hard drive architecture, where the magnetic plate is divided into a number of cylindrical tracks. Tracks are numbered, and every track is divided into a number (usually 64) of sectors. Track numbers start at 0, but sector numbers start from 1. Track 0 is the outermost on the magnetic plate, and sector 1, the first sector, has a special purpose. It is also called the <acronym>MBR</acronym>, or Master Boot Record. The remaining sectors on the first track are never used. <acronym>POST</acronym>的最后一步是执行<literal>INT 0x19</literal>指令。 这个指令从引导设备第一个扇区读取512字节,装入地址<literal>0x7c00</literal>。 <emphasis>第一个扇区</emphasis>的说法最早起源于硬盘的结构,硬盘面被分为若干圆柱形轨道。给轨道编号,同时又将轨道分为 一定数目(通常是64)的扇形。0号轨道是硬盘的最外圈,1号扇区, 第一个扇区(轨道、柱面都从0开始编号,而扇区从1开始编号) 有着特殊的作用,它又被称为主引导记录(Master Boot Record, <acronym>MBR</acronym>)。 第一轨剩余的扇区常常不使用。
This sector is our boot-sequence starting point. As we will see, this sector contains a copy of our <filename>boot0</filename> program. A jump is made by the <acronym>BIOS</acronym> to address <literal>0x7c00</literal> so it starts executing.
The Master Boot Record (<literal>boot0</literal>) 主引导记录 (<literal>boot0</literal>)
<primary>MBR</primary> <primary>MBR</primary>
After control is received from the <acronym>BIOS</acronym> at memory address <literal>0x7c00</literal>, <filename>boot0</filename> starts executing. It is the first piece of code under FreeBSD control. The task of <filename>boot0</filename> is quite simple: scan the partition table and let the user choose which partition to boot from. The Partition Table is a special, standard data structure embedded in the <acronym>MBR</acronym> (hence embedded in <filename>boot0</filename>) describing the four standard PC <quote>partitions</quote> <_:footnote-1/>. <filename>boot0</filename> resides in the filesystem as <filename>/boot/boot0</filename>. It is a small 512-byte file, and it is exactly what FreeBSD's installation procedure wrote to the hard disk's <acronym>MBR</acronym> if you chose the <quote>bootmanager</quote> option at installation time. Indeed, <filename>boot0</filename> <emphasis>is</emphasis> the <acronym>MBR</acronym>.
As mentioned previously, the <literal>INT 0x19</literal> instruction causes the <literal>INT 0x19</literal> handler to load an <acronym>MBR</acronym> (<filename>boot0</filename>) into memory at address <literal>0x7c00</literal>. The source file for <filename>boot0</filename> can be found in <filename>sys/boot/i386/boot0/boot0.S</filename> - which is an awesome piece of code written by Robert Nordier. 如前所述, <literal>INT 0x19</literal> 指令装载 MBR, 也就是 <filename>boot0</filename> 的内容至内存地址 0x7c00。 再看文件 <filename>sys/boot/i386/boot0/boot0.S</filename>, 可以猜想这里面发生了什么 - 这是引导管理器, 一段由 Robert Nordier书写的令人起敬的程序片段。
A special structure starting from offset <literal>0x1be</literal> in the <acronym>MBR</acronym> is called the <emphasis>partition table</emphasis>. It has four records of 16 bytes each, called <emphasis>partition records</emphasis>, which represent how the hard disk is partitioned, or, in FreeBSD's terminology, sliced. One byte of those 16 says whether a partition (slice) is bootable or not. Exactly one record must have that flag set, otherwise <filename>boot0</filename>'s code will refuse to proceed. MBR里,也就是<filename>boot0</filename>里, 从偏移量0x1be开始有一个特殊的结构,称为 <emphasis>分区表</emphasis>。其中有4条记录 (称为<emphasis>分区记录</emphasis>),每条记录16字节。 分区记录表示硬盘如何被划分,在FreeBSD的术语中, 这被称为slice(d)。16字节中有一个标志字节决定这个分区是否可引导。 有仅只能有一个分区可设定这一标志。否则, <filename>boot0</filename>的代码将拒绝继续执行。
A partition record has the following fields: 一个分区记录有如下域:
the 1-byte filesystem type 1字节 文件系统类型
the 1-byte bootable flag 1字节 可引导标志
the 6 byte descriptor in CHS format 6字节 CHS格式描述符
the 8 byte descriptor in LBA format 8字节 LBA格式描述符
A partition record descriptor contains information about where exactly the partition resides on the drive. Both descriptors, <acronym>LBA</acronym> and <acronym>CHS</acronym>, describe the same information, but in different ways: <acronym>LBA</acronym> (Logical Block Addressing) has the starting sector for the partition and the partition's length, while <acronym>CHS</acronym> (Cylinder Head Sector) has coordinates for the first and last sectors of the partition. The partition table ends with the special signature <literal>0xaa55</literal>. 一个分区记录描述符包含某一分区在硬盘上的确切位置信息。 LBA和CHS两种描述符指示相同的信息,但是指示方式有所不同:LBA (逻辑块寻址,Logical Block Addressing)指示分区的起始扇区和分区长度, 而CHS(柱面 磁头 扇区)指示首扇区和末扇区。
The <acronym>MBR</acronym> must fit into 512 bytes, a single disk sector. This program uses low-level <quote>tricks</quote> like taking advantage of the side effects of certain instructions and reusing register values from previous operations to make the most out of the fewest possible instructions. Care must also be taken when handling the partition table, which is embedded in the <acronym>MBR</acronym> itself. For these reasons, be very careful when modifying <filename>boot0.S</filename>.
Note that the <filename>boot0.S</filename> source file is assembled <quote>as is</quote>: instructions are translated one by one to binary, with no additional information (no <acronym>ELF</acronym> file format, for example). This kind of low-level control is achieved at link time through special control flags passed to the linker. For example, the text section of the program is set to be located at address <literal>0x600</literal>. In practice this means that <filename>boot0</filename> must be loaded to memory address <literal>0x600</literal> in order to function properly.
It is worth looking at the <filename>Makefile</filename> for <filename>boot0</filename> (<filename>sys/boot/i386/boot0/Makefile</filename>), as it defines some of the run-time behavior of <filename>boot0</filename>. For instance, if a terminal connected to the serial port (COM1) is used for I/O, the macro <literal>SIO</literal> must be defined (<literal>-DSIO</literal>). <literal>-DPXE</literal> enables boot through <acronym>PXE</acronym> by pressing <keycap>F6</keycap>. Additionally, the program defines a set of <emphasis>flags</emphasis> that allow further modification of its behavior. All of this is illustrated in the <filename>Makefile</filename>. For example, look at the linker directives which command the linker to start the text section at address <literal>0x600</literal>, and to build the output file <quote>as is</quote> (strip out any file formatting):
<filename>sys/boot/i386/boot0/Makefile</filename> <filename>sys/boot/i386/boot0/Makefile</filename>
BOOT_BOOT0_ORG?=0x600
LDFLAGS=-e start -Ttext ${BOOT_BOOT0_ORG} \
-Wl,-N,-S,--oformat,binary
BOOT_BOOT0_ORG?=0x600
LDFLAGS=-e start -Ttext ${BOOT_BOOT0_ORG} \
-Wl,-N,-S,--oformat,binary
Let us now start our study of the <acronym>MBR</acronym>, or <filename>boot0</filename>, starting where execution begins.
Some modifications have been made to some instructions in favor of better exposition. For example, some macros are expanded, and some macro tests are omitted when the result of the test is known. This applies to all of the code examples shown.
<filename>sys/boot/i386/boot0/boot0.S</filename> <filename>sys/boot/i386/boot0/boot0.S</filename>
start:
cld # String ops inc
xorw %ax,%ax # Zero
movw %ax,%es # Address
movw %ax,%ds # data
movw %ax,%ss # Set up
movw 0x7c00,%sp # stack
start:
cld # String ops inc
xorw %ax,%ax # Zero
movw %ax,%es # Address
movw %ax,%ds # data
movw %ax,%ss # Set up
movw 0x7c00,%sp # stack
When in doubt, we refer the reader to the official Intel manuals, which describe the exact semantics for each instruction: <link xlink:href="http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html"/>.
This first block of code is the entry point of the program. It is where the <acronym>BIOS</acronym> transfers control. First, it makes sure that the string operations autoincrement its pointer operands (the <literal>cld</literal> instruction) <_:footnote-1/>. Then, as it makes no assumption about the state of the segment registers, it initializes them. Finally, it sets the stack pointer register (<literal>%sp</literal>) to address <literal>0x7c00</literal>, so we have a working stack.
The next block is responsible for the relocation and subsequent jump to the relocated code.
movw $0x7c00,%si # Source
movw $0x600,%di # Destination
movw $512,%cx # Word count
rep # Relocate
movsb # code
movw %di,%bp # Address variables
movb $16,%cl # Words to clear
rep # Zero
stosb # them
incb -0xe(%di) # Set the S field to 1
jmp main-0x7c00+0x600 # Jump to relocated code
movw $0x7c00,%si # Source
movw $0x600,%di # Destination
movw $512,%cx # Word count
rep # Relocate
movsb # code
movw %di,%bp # Address variables
movb $16,%cl # Words to clear
rep # Zero
stosb # them
incb -0xe(%di) # Set the S field to 1
jmp main-0x7c00+0x600 # Jump to relocated code
As <filename>boot0</filename> is loaded by the <acronym>BIOS</acronym> to address <literal>0x7C00</literal>, it copies itself to address <literal>0x600</literal> and then transfers control there (recall that it was linked to execute at address <literal>0x600</literal>). The source address, <literal>0x7c00</literal>, is copied to register <literal>%si</literal>. The destination address, <literal>0x600</literal>, to register <literal>%di</literal>. The number of bytes to copy, <literal>512</literal> (the program's size), is copied to register <literal>%cx</literal>. Next, the <literal>rep</literal> instruction repeats the instruction that follows, that is, <literal>movsb</literal>, the number of times dictated by the <literal>%cx</literal> register. The <literal>movsb</literal> instruction copies the byte pointed to by <literal>%si</literal> to the address pointed to by <literal>%di</literal>. This is repeated another 511 times. On each repetition, both the source and destination registers, <literal>%si</literal> and <literal>%di</literal>, are incremented by one. Thus, upon completion of the 512-byte copy, <literal>%di</literal> has the value <literal>0x600</literal>+<literal>512</literal>= <literal>0x800</literal>, and <literal>%si</literal> has the value <literal>0x7c00</literal>+<literal>512</literal>= <literal>0x7e00</literal>; we have thus completed the code <emphasis>relocation</emphasis>.
Next, the destination register <literal>%di</literal> is copied to <literal>%bp</literal>. <literal>%bp</literal> gets the value <literal>0x800</literal>. The value <literal>16</literal> is copied to <literal>%cl</literal> in preparation for a new string operation (like our previous <literal>movsb</literal>). Now, <literal>stosb</literal> is executed 16 times. This instruction copies a <literal>0</literal> value to the address pointed to by the destination register (<literal>%di</literal>, which is <literal>0x800</literal>), and increments it. This is repeated another 15 times, so <literal>%di</literal> ends up with value <literal>0x810</literal>. Effectively, this clears the address range <literal>0x800</literal>-<literal>0x80f</literal>. This range is used as a (fake) partition table for writing the <acronym>MBR</acronym> back to disk. Finally, the sector field for the <acronym>CHS</acronym> addressing of this fake partition is given the value 1 and a jump is made to the main function from the relocated code. Note that until this jump to the relocated code, any reference to an absolute address was avoided.
The following code block tests whether the drive number provided by the <acronym>BIOS</acronym> should be used, or the one stored in <filename>boot0</filename>.
main:
testb $SETDRV,-69(%bp) # Set drive number?
jnz disable_update # Yes
testb %dl,%dl # Drive number valid?
js save_curdrive # Possibly (0x80 set)
main:
testb $SETDRV,-69(%bp) # Set drive number?
jnz disable_update # Yes
testb %dl,%dl # Drive number valid?
js save_curdrive # Possibly (0x80 set)
This code tests the <literal>SETDRV</literal> bit (<literal>0x20</literal>) in the <emphasis>flags</emphasis> variable. Recall that register <literal>%bp</literal> points to address location <literal>0x800</literal>, so the test is done to the <emphasis>flags</emphasis> variable at address <literal>0x800</literal>-<literal>69</literal>= <literal>0x7bb</literal>. This is an example of the type of modifications that can be done to <filename>boot0</filename>. The <literal>SETDRV</literal> flag is not set by default, but it can be set in the <filename>Makefile</filename>. When set, the drive number stored in the <acronym>MBR</acronym> is used instead of the one provided by the <acronym>BIOS</acronym>. We assume the defaults, and that the <acronym>BIOS</acronym> provided a valid drive number, so we jump to <literal>save_curdrive</literal>.

Loading…

No matching activity found.

Browse all component changes

Glossary

English Chinese (Simplified) (zh_CN)
No related strings found in the glossary.

Source information

Source string comment
(itstool) path: sect1/para
Source string location
book.translate.xml:568
String age
a year ago
Source string age
a year ago
Translation file
books/zh_CN/arch-handbook.po, string 66