# 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 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 ```