---
title: "OpenBSD bsd.rd 해부하기 — 재부팅 없이 내부 구조 파헤치기"
published: 2026-02-17T23:03:27.000Z
canonical: https://jeff.news/article/947
---
# OpenBSD bsd.rd 해부하기 — 재부팅 없이 내부 구조 파헤치기

OpenBSD의 bsd.rd 파일을 실행 중인 시스템에서 7단계에 걸쳐 분해하는 실습 가이드. gzip 압축 → ELF 커널 → 내장 FFS 파일시스템의 중첩 구조를 표준 도구만으로 탐색하고, miniroot의 install.sub 스크립트와 76개 하드링크로 구성된 크런치 바이너리 구조를 확인함.

OpenBSD 관리자라면 한 번쯤 부팅해본 bsd.rd 파일을 재부팅 없이 실행 중인 시스템에서 분해해보는 실습 가이드임. 7단계에 걸쳐 겹겹이 쌓인 레이어를 하나씩 벗겨봄.

## bsd.rd의 구조: gzip → ELF → FFS

- bsd.rd는 gzip 압축 파일임. `file` 명령으로 확인 가능하고, boot(8) 로더가 부팅 시 자동으로 압축 해제함
- gzip을 풀면 ELF 64-bit 실행파일이 나옴. `/bin/ls`와 같은 포맷이지만 이건 커널임
- ELF 헤더의 매직넘버는 `7f 45 4c 46` (7f + "ELF" ASCII). 엔트리 포인트 `0xffffffff81001000`에서 CPU가 점프함
- `rdsetroot -s`로 내장 램디스크 크기를 확인하면 3,768,320 바이트, 약 3.59 MiB
- 커널 설정에서 `option RAMDISK`와 `pseudo-device rd` 두 지시자가 파일시스템 이미지 공간을 예약하는 구조임
- `rdsetroot -x`로 miniroot.fs를 추출하면 Unix FFS v1 파일시스템이 나옴. 블록 크기 4096, 실린더 그룹 1개

## miniroot 파일시스템 탐색

- `vnconfig`로 vnd0 디바이스에 연결하고 `mount -r`로 읽기 전용 마운트할 수 있음
- 파티션은 딱 하나, 4.2BSD(FFS) 타입으로 전체 이미지를 커버함. 스왑 없음

### install.sub — 하나의 스크립트가 세 역할

- `install`, `upgrade`, `autoinstall` 세 심볼릭 링크가 모두 `install.sub`를 가리킴
- install.sub은 65KB짜리 ksh 스크립트로, `$0`을 체크해서 어떤 모드로 호출됐는지 판단함
- `.profile`이 부팅 후 셸 시작 시 실행되며, sysctl(8)로 버전과 아키텍처를 런타임에 읽어옴 — 릴리즈 번호가 하드코딩되어 있지 않음

### 크런치 바이너리 — 76개 명령이 하나의 실행파일

- crunchgen(8)이 ls, df, ed, ksh 등 여러 명령의 소스를 하나의 `instbin` 바이너리로 컴파일함
- libc 같은 공통 코드를 한 번만 포함하므로 용량을 크게 절약함
- `argv[0]`을 확인해서 어떤 프로그램을 실행할지 결정하는 방식. ls로 호출하면 ls 로직 실행
- inode 번호가 동일한 76개 하드링크로 접근 가능. 원본 instbin 파일은 빌드 과정에서 삭제되지만 inode가 남아있어 문제없음
- 설정 파일은 동적 생성: list 파일 → makeconf.awk → instbin.conf → crunchgen이 Makefile과 C 소스 생성

### 최소한의 도구 세트

- bin/: cat, cp, dd, ed, ksh, ls, mv, rm, tar 등 기본 유틸리티
- sbin/: fdisk, disklabel, newfs로 파티셔닝과 포맷, ifconfig, dhcpleased, route로 네트워킹
- usr/bin/: ftp(다운로드), signify(검증), gunzip, sed, doas
- usr/sbin/: chroot, installboot(디스크 부팅 가능하게), pwd_mkdb
- etc/: signify 공개키, SSL 인증서, 최소한의 사용자 DB — 신뢰 부트스트래핑에 필요한 것만 포함

## 맨페이지 체인과 커스터마이징

- 맨페이지가 학습 경로를 구성함: rd(4) → rdsetroot(8) → vnconfig(8) → vnd(4). SEE ALSO 섹션을 따라가면 됨
- miniroot를 수정하고 다시 주입할 수 있음: 추출 → 읽기/쓰기 마운트 → 수정 → 언마운트 → `rdsetroot bsd.rd miniroot.fs` → gzip 압축
- 이렇게 하면 커스텀 bsd.rd를 만들 수 있음. 여전히 부팅 가능하면서 원하는 것을 추가한 상태

## 핵심 포인트

- bsd.rd는 gzip → ELF 커널 → 3.59 MiB FFS 파일시스템의 중첩 구조
- install.sub은 65KB ksh 스크립트로 $0 체크를 통해 install/upgrade/autoinstall 세 모드 처리
- crunchgen으로 빌드한 단일 instbin 바이너리가 76개 하드링크로 접근 가능
- miniroot에는 fdisk, disklabel, newfs, ftp, signify, installboot 등 설치에 필요한 최소 도구만 포함
- rdsetroot로 miniroot를 추출·수정·재주입하여 커스텀 bsd.rd 생성 가능

## 인사이트

맨페이지 SEE ALSO 섹션이 그대로 학습 경로가 되는 OpenBSD 문서 철학의 좋은 예시. 최소한의 도구로 최대한의 기능을 구현하는 설계가 인상적임.
