linux-bootstrap-1.md 40% 번역 완료

Signed-off-by: 0xF0D0 <goodbumsu@gmail.com>
pull/563/head
0xF0D0 6 years ago
parent 891ab036e1
commit a82f3f7739

@ -129,42 +129,42 @@ db 0xaa
이 어셈블리를 다음명령어로 빌드해 보아라:
```
nasm -f bin boot.nasm && qemu-system-x86\_64 boot
nasm -f bin boot.nasm && qemu-system-x86_64 boot
```
This will instruct [QEMU](http://qemu.org) to use the `boot` binary that we just built as a disk image. Since the binary generated by the assembly code above fulfills the requirements of the boot sector (the origin is set to `0x7c00` and we end with the magic sequence), QEMU will treat the binary as the master boot record (MBR) of a disk image.
[QEMU](http://qemu.org)는 우리가 빌드한 `boot` binary를 disk image로 사용할 것이다. 위 어셈블리 코드로 빌드한 이미지는 boot sector의 요구사항(origin이 `0x7c00`으로 세팅되어있고 마지막이 0x55, 0xaa로 끝나는 것)을 만족하므로, QEMU는 바이너리를 disk image의 master boot record(MBR)로 인식할 것이다.
You will see:
다음 예를 보자:
![Simple bootloader which prints only `!`](http://oi60.tinypic.com/2qbwup0.jpg)
![`!`를 프린트하는 간단한 부트로더](http://oi60.tinypic.com/2qbwup0.jpg)
In this example, we can see that the code will be executed in `16-bit` real mode and will start at `0x7c00` in memory. After starting, it calls the [0x10](http://www.ctyme.com/intr/rb-0106.htm) interrupt, which just prints the `!` symbol; it fills the remaining `510` bytes with zeros and finishes with the two magic bytes `0xaa` and `0x55`.
이 예제애서, 우리는 코드가 `16-bit` real mode에서 실행되고 `0x7c00`주소에서 시작하는 것을 볼 수 있다. 그후 [0x10](http://www.ctyme.com/intr/rb-0106.htm) 인터럽트를 통해 `!`를 출력한다; 나머지 510 byte는 0으로 채워져있고 마지막 두 magic byte `0xaa`, `0x55`로 마무리 된다.
You can see a binary dump of this using the `objdump` utility:
binary dump는 `objdump` utility를 통해 볼 수 있다:
```
nasm -f bin boot.nasm
objdump -D -b binary -mi386 -Maddr16,data16,intel boot
```
A real-world boot sector has code for continuing the boot process and a partition table instead of a bunch of 0's and an exclamation mark :) From this point onwards, the BIOS hands over control to the bootloader.
실제 boot sector는 0으로채워지고 느낌표를 출력하는 대신 부팅과정 코드와 partition table로 이루어져 있다 :) 이후로부터, BIOS는 부트로더에게 제어를 넘겨준다.
**NOTE**: As explained above, the CPU is in real mode; in real mode, calculating the physical address in memory is done as follows:
**참고**: 위에 설명되어있듯이, CPU는 real mode에 있다; real mode에서는 메모리의 물리주소 계산법이 다음과 같이 이루어 진다.
```
PhysicalAddress = Segment Selector * 16 + Offset
```
just as explained above. We have only 16-bit general purpose registers; the maximum value of a 16-bit register is `0xffff`, so if we take the largest values, the result will be:
Real mode에서는 오직 16-bit 범용 레지스터만 갖고있다; 16-bit 레지스터의 최대값은 `0xffff`이다, 따라서 우리가 최대 주소를 대입한다면 결과는 다음과 같다.
```python
>>> hex((0xffff * 16) + 0xffff)
'0x10ffef'
```
where `0x10ffef` is equal to `1MB + 64KB - 16b`. An [8086](https://en.wikipedia.org/wiki/Intel_8086) processor (which was the first processor with real mode), in contrast, has a 20-bit address line. Since `2^20 = 1048576` is 1MB, this means that the actual available memory is 1MB.
`0x10ffef``1MB + 64KB - 16byte`이다. [8086](https://en.wikipedia.org/wiki/Intel_8086) 프로세서는 (real mode를 탑재한 첫 프로세서), 반대로, 20-bit 주소를 사용한다. `2^20 = 1048576` 는 1MB이므로, 실제 사용가능한 메모리 주소는 1MB라는 뜻이 된다.
In general, real mode's memory map is as follows:
보통, real mode의 memory map은 다음과 같다:
```
0x00000000 - 0x000003FF - Real Mode Interrupt Vector Table
@ -180,24 +180,24 @@ In general, real mode's memory map is as follows:
0x000F0000 - 0x000FFFFF - System BIOS
```
In the beginning of this post, I wrote that the first instruction executed by the CPU is located at address `0xFFFFFFF0`, which is much larger than `0xFFFFF` (1MB). How can the CPU access this address in real mode? The answer is in the [coreboot](http://www.coreboot.org/Developer_Manual/Memory_map) documentation:
이 포스트의 시작점에서, 나는 CPU의 첫 명령어가 `0xFFFFFFF0`에 위치한다고 했었다, 이 주소는 `0xFFFFF` (1MB)보다 큰값이다. 어떻게 CPU가 real mode에서 이 주소에 접근할 수 있을까? 정답은 [coreboot](http://www.coreboot.org/Developer_Manual/Memory_map) 문서에 있다:
```
0xFFFE_0000 - 0xFFFF_FFFF: 128 kilobyte ROM mapped into address space
```
At the start of execution, the BIOS is not in RAM, but in ROM.
실행이 시작할 때, BIOS는 RAM에 있지않다, ROM에 위치해 있는 것이다.
Bootloader
부트로더
--------------------------------------------------------------------------------
There are a number of bootloaders that can boot Linux, such as [GRUB 2](https://www.gnu.org/software/grub/) and [syslinux](http://www.syslinux.org/wiki/index.php/The_Syslinux_Project). The Linux kernel has a [Boot protocol](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/Documentation/x86/boot.txt) which specifies the requirements for a bootloader to implement Linux support. This example will describe GRUB 2.
[GRUB 2](https://www.gnu.org/software/grub/) 이나 [syslinux](http://www.syslinux.org/wiki/index.php/The_Syslinux_Project)처럼 Linux를 부트할 수 있는 부트로더는 많다. Linux 커널은 [Boot protocol](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/Documentation/x86/boot.txt) 요구사항을 명시해 부트로더가 Linux support를 구현할 수 있게했다. 다음 예시는 GRUB 2를 설명할 것이다.
Continuing from before, now that the `BIOS` has chosen a boot device and transferred control to the boot sector code, execution starts from [boot.img](http://git.savannah.gnu.org/gitweb/?p=grub.git;a=blob;f=grub-core/boot/i386/pc/boot.S;hb=HEAD). This code is very simple, due to the limited amount of space available, and contains a pointer which is used to jump to the location of GRUB 2's core image. The core image begins with [diskboot.img](http://git.savannah.gnu.org/gitweb/?p=grub.git;a=blob;f=grub-core/boot/i386/pc/diskboot.S;hb=HEAD), which is usually stored immediately after the first sector in the unused space before the first partition. The above code loads the rest of the core image, which contains GRUB 2's kernel and drivers for handling filesystems, into memory. After loading the rest of the core image, it executes the [grub_main](http://git.savannah.gnu.org/gitweb/?p=grub.git;a=blob;f=grub-core/kern/main.c) function.
이전과 이어서, 이제 `BIOS`는 boot 장비를 선택했고 boot sector code로 제어를 넘겼다, 실행은 [boot.img](http://git.savannah.gnu.org/gitweb/?p=grub.git;a=blob;f=grub-core/boot/i386/pc/boot.S;hb=HEAD) 에서 시작한다. 이 코드는 제한된 메모리 공간때문에 간단하며, GUB 2의 core image로 점프할 포인터를 갖고있다. 코어이미지는 [diskboot.img](http://git.savannah.gnu.org/gitweb/?p=grub.git;a=blob;f=grub-core/boot/i386/pc/diskboot.S;hb=HEAD)로 시작하며, 보통 첫 sector의 바로 다음이나 첫 partition의 사용되지 않은 공간에 저장되어 있다. 나머지 core image를 메모리에 올린 뒤에, [grub_main](http://git.savannah.gnu.org/gitweb/?p=grub.git;a=blob;f=grub-core/kern/main.c) 함수를 실행시킨다.
The `grub_main` function initializes the console, gets the base address for modules, sets the root device, loads/parses the grub configuration file, loads modules, etc. At the end of execution, the `grub_main` function moves grub to normal mode. The `grub_normal_execute` function (from the `grub-core/normal/main.c` source code file) completes the final preparations and shows a menu to select an operating system. When we select one of the grub menu entries, the `grub_menu_execute_entry` function runs, executing the grub `boot` command and booting the selected operating system.
`grub_main` 함수는 콘솔을 초기화하고, module들의 base address를 구하고, root device를 세팅하고 grub 설정을 불러오고, module를 로딩하는 등의 작업을 한다. 실행의 마지막 부분에서 `grub_main` 함수는 grub을 normal mode(CPU의 모드와 무관)로 옮긴다. `grub_normal_execute` (`grub-core/normal/main.c`) 함수는 마지막 준비를 끝내고 OS선택 메뉴를 보여준다. 우리가 grub menu entry중 하나를 선택하면, `grub_menu_execute_entry` 함수가 grub `boot`명령어를 실행해 선택된 OS를 부팅한다.
As we can read in the kernel boot protocol, the bootloader must read and fill some fields of the kernel setup header, which starts at the `0x01f1` offset from the kernel setup code. You may look at the boot [linker script](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/setup.ld#L16) to confirm the value of this offset. The kernel header [arch/x86/boot/header.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S) starts from:
Kernal boot protocol을 읽어보면, 부트로더는 커널 setup code의 `0x01f1` offset에 위치한 kernal setup header를 읽고 채워야 한다. [linker script](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/setup.ld#L16) 를 보면 오프셋값을 확인할 수 있다. 커널 헤더 [arch/x86/boot/header.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S) 는 다음과 같이 시작한다:
```assembly
.globl hdr

Loading…
Cancel
Save