Files
kernel-study/README.md
T
2026-01-07 18:10:32 +09:00

169 lines
4.8 KiB
Markdown

# Build Linux from Scratch
## Prerequisites
```bash
apt install build-essential bison flex libssl-dev libelf-dev \
ncurses-dev bc git
apt install qemu-system-x86 qemu-utils
apt install e2fsprogs grub-pc-bin xorriso
apt install nasm
```
## Build
```bash
git clone <REPOSITORY_URL>
cd kernel-study
git clone --depth 1 --branch linux-6.6.y https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git linux
cd linux
make defconfig
# make menuconfig
cd ..
make
```
## run
```bash
make run
```
## disk.img structure
### 1. 디스크 전체 구조도 (Overview)
```text
[ MBR ] [ GRUB Core ] [ Partition 1 (RootFS) ] [ Partition 2 (HomeFS) ] [ Free Space ]
| | | | |
Sec 0 Sec 1 Sec 2048 Sec 526336 Sec 788480
(0B) (512B) (1MB) (257MB) (385MB)
```
---
### 2. 구역별 상세 분석 (Byte-level Breakdown)
모든 섹터 크기는 **512 Bytes**입니다.
#### ① 섹터 0: MBR (Master Boot Record)
* **위치:** `0` ~ `511` bytes (총 512 bytes)
* **구성:**
* `0 ~ 445` (446 bytes): **GRUB Stage 1 (`boot.img`)**. 부팅 시 가장 먼저 실행되는 기계어 코드.
* `446 ~ 509` (64 bytes): **파티션 테이블**. (`sfdisk`가 작성함). 파티션 1, 2의 정보가 16바이트씩 기록됨.
* `510 ~ 511` (2 bytes): **부트 시그니처 (`0x55 0xAA`)**. BIOS가 "이건 부팅 가능한 디스크다"라고 인식하는 도장.
#### ② 섹터 1 ~ 2047: GRUB Core & Gap (예비 공간)
* **위치:** `512` ~ `1,048,575` bytes (약 1MB 구간)
* **설명:**
* MBR과 첫 번째 파티션 사이의 **"빈 공간(Gap)"**입니다.
* **섹터 1 (`seek=1`)**부터 **GRUB Stage 1.5/2 (`core.img`)**가 들어갑니다.
* 파일 시스템이 없는 영역(`Raw Data`)이므로, GRUB이 자신을 여기에 숨겨놓고 MBR에서 점프해 옵니다.
* 현대적인 파티셔닝 툴은 성능 최적화(Alignment)를 위해 첫 파티션을 1MB(`2048 sector`)부터 시작하게 잡는데, 그 남는 공간을 알뜰하게 쓰는 겁니다.
#### ③ 섹터 2048 ~ 526,335: Partition 1 (/ - RootFS)
* **위치:** `1,048,576` bytes (1MB 지점) ~ `269,484,031` bytes
* **크기:** **256MB** (`256 * 1024 * 1024` bytes)
* **내용:** `rootfs.img`의 내용이 비트 단위로 그대로 복사됨.
* **파일 시스템:** Ext4
* **내용물:** `/bin`, `/boot(bzImage)`, `/init`, `/dev` 등 OS 시스템 파일.
* **특징:** 매번 빌드할 때마다 새로 포맷되고 덮어씌워짐.
#### ④ 섹터 526,336 ~ 788,479: Partition 2 (/home - HomeFS)
* **위치:** `269,484,032` bytes (약 257MB 지점) ~ `403,701,759` bytes
* **시작점 계산:** `ROOT_OFFSET(2048)` + `ROOT_SECTORS(256MB어치)` = `526336` 섹터.
* **크기:** **128MB** (`128 * 1024 * 1024` bytes)
* **내용:** `homefs.img`의 내용.
* **파일 시스템:** Ext4
* **내용물:** 사용자 텍스트 파일, 소스 코드 등.
* **특징:** `make run` 종료 시 `disk.img`에서 다시 백업받아 보존됨.
#### ⑤ 섹터 788,480 ~ 1,048,575: Unallocated Space (빈 공간)
* **위치:** `403,701,760` bytes ~ `536,870,911` bytes (끝)
* **크기:** **127MB** (총 512MB - 1MB(Gap) - 256MB(Root) - 128MB(Home))
* **설명:**
* 현재 파티션이 잡혀있지 않은 **잉여 공간**입니다.
* 나중에 스왑 파티션을 만들거나, 제3의 파티션을 만들 때 쓸 수 있습니다.
* 지금은 그냥 `0`으로 채워져 있습니다.
---
### 3. 요약표 (한눈에 보기)
| 구역 | 시작 섹터 | 시작 바이트 (Offset) | 크기 | 용도 |
| --- | --- | --- | --- | --- |
| **MBR** | 0 | 0 (`0x0`) | 512 B | 부트로더(Stage1) + 파티션 테이블 |
| **Gap** | 1 | 512 (`0x200`) | ~1 MB | **GRUB Core (`core.img`)** |
| **P1** | 2048 | 1,048,576 (`0x100000`) | 256 MB | **Root Filesystem (System)** |
| **P2** | 526336 | 269,484,032 (`0x10100000`) | 128 MB | **Home Filesystem (User)** |
| **Free** | 788480 | 403,701,760 | 127 MB | (사용 안 함) |
## `make run`
```bash
ifconfig eth0 10.0.2.15
route add default gw 10.0.2.2
medit req.txt
GET / HTTP/1.0
Host: 1.1.1.1
:w
:q
nc 1.1.1.1 80 < req.txt
```
## Legacy
### Run
```bash
gcc -static -o init/init init/init.c
dd if=/dev/zero of=disk.img bs=1M count=512 status=none
echo -e "n\np\n1\n2048\n\nw" | fdisk disk.img > /dev/null
dd if=disk.img of=part.img bs=512 skip=2048 status=none
mkfs.ext4 part.img
debugfs -w -R "mkdir /boot" part.img
debugfs -w -R "mkdir /boot/grub" part.img
debugfs -w -R "write init/init /init" part.img
debugfs -w -R "write linux/arch/x86/boot/bzImage /boot/bzImage" part.img
debugfs -w -R "write grub/grub.cfg /boot/grub/grub.cfg" part.img
dd if=part.img of=disk.img bs=512 seek=2048 conv=notrunc status=none
```
Or, alternatively
```bash
make
```