 |
|
루트 파일 시스템 배치
루트 파일 시스템에는 무엇이 들어가 있는가?
루트 파일 시스템은 /sbin/init를 필요로 한다. 굳이 전통적인 유닉스 스타일의 init가 아니라 맞춤 형태의 프로그램이 될 수도 있지만 콘솔 셸 등 모든 것이 완비된 작업 환경을 제공한다면 시스템과 동작하기가 더 쉬울 것이다.
기본 라이브러리와 헤더
crosstool-ng는 라이브러리 코드와 헤더를 제공하는 기본 시스템 루트를 생성했다. 복사본을 하나 만들자.
$ cp -r toolchain/arm-unknown-linux-uclibc/sys-root rootfs
지금 당장은 권한 부분에 대한 문제를 수정하는 데에 수고를 들이지는 않도록 하자. 실제 배포 시에는 이를 수정하고 싶겠지만 데모용으로는 해로울 게 없다. 이것이 라이브러리(그리고 헤더)의 미래 빌드가 사용할 루트 파일 시스템의 첫 번째 기본 부분이다.
비지박스
임베디드 루트 파일 시스템에서 비지박스(bustbox)는 아마도 최상의 출발점일 것이다. 비지박스는 단일 바이너리에 핵심이 되는 시스템 유틸리티를 모두 내장한 합리적인 종합 세트라 할 수 있는데 수행할 기능이 무엇인지 결정하기 위해 호출 시 불리는 이름을 사용한다. 이렇게 할 경우 많은 링크와 결합되어 있기에 메인 시스템에 많은 프로그램이 작은 공간 안으로 들어갈 수 있다. 항상 필요한 건 아니지만 우리 목표를 위해선 편리하게 쓸 수 있다.
비지박스 다운로드
비지박스는 다운로드 페이지(참고자료 참조)에서 다운로드할 수 있다. 아카이브에는 표준 tarball이 있고 빌드 디렉터리에서 압축을 풀어낼 수 있다. 필자는 버전 1.10.2를 사용했다.
비지박스 설정
비지박스는 crosstool-ng과 리눅스 커널에서 사용되는 것과 비슷한 설정 도구로 빌드한다. 기본 설정으로 빌드하려면 make defconfig를 실행한다. 이렇게 하여 기본 설정을 생성한다. 이어 make menuconfig를 하여 설정을 변경한다. "Busybox Settings"에서 "Build Options" 메뉴로 가서 정적 빌드(static build)를 하도록 설정한다. 이렇게 해야 한다. uClibc의 기본 crosstool-ng 빌드에서 필요하기 때문이다. 실행 파일 크기를 줄이기 위해 동적 연결 바이너리를 선호할 수도 있겠지만 크기 문제는 거의 모든 바이너리가 그저 심볼릭 링크뿐인 시스템에서는 그렇게 큰 문제가 아니다. 커널에서처럼 최상위 Makefile은 컴파일러 도구의 이름에서 사용할 접두어를 사용하기 위해 CROSS_COMPILE 변수를 갖는다. 전에 사용했던 것과 똑같은 값으로 설정하자.
비지박스 빌드
비지박스를 빌드하기 위해선 make라고 치면 된다. 놀랍게도 빌드하는 동안 컴파일 문제가 있다는 것인데 필자의 경우엔 libbb.h 헤더에 <linux/types.h>를 추가해 줄 필요가 있었다는 것이다. 이상한 일이었지만 컴파일은 금새 끝났다.
비지박스 설치
비지박스를 설치하려면 make install을 해야 할 필요가 있으나 루트 파일 시스템 경로를 명시해야 한다.
$ make CONFIG_PREFIX=$HOME/7800/rootfs install
이는 busybox 바이너리를 복사하고 필요한 모든 링크를 생성한다. 루트 파일 시스템은 이제 라이브러리와 모든 공통 유닉스 유틸리티를 갖게 되었다. 빠진 게 뭘까?
장치 노드
장치 노드가 필요하다. 루트 파일 시스템에 장치 노드를 제공하는 데에는 두 가지 방법이 있다. 하나는 계획한 대로 장치 노드를 모두 정적으로 생성하는 것이고 나머지는 udev 같은 걸 쓰는 것인데 udev란 현재 커널용으로 현재 장치 노드 트리를 자동으로 제공하는 것이다. udev는 꽤나 우아한 방법이나 상당히 느릴 수 있고, 임베디드 시스템이 자신이 무슨 하드웨어 컴포넌트를 갖는지 예측할 수 있는 기능을 갖는 건 사치스러움이기도 하다.
필요한 장치 노드 생성
많은 프로그램이 장치 노드, 이를테면 /dev/console이나 /dev/null에 접근한다. 장치 노드는 전형적으로 ARM 시스템에서는 비지박스의 일부분인 mdev 유틸리티를 이용해 런타임에 만들어진다. 사실 이 작업은 이미 initrd 파일 시스템에서 행해졌다. 위의 변경 내용 중 하나는 이미 /dev 마운트 포인트에서 새로운 루트 파일 시스템으로 옮겼다. 손수 핵심적인 장치 노드를 생성할 수도 있으나 보통은 어려움을 겪을 필요가 없으니 mdev를 쓰는 게 현명한 방법이다.
마운트 포인트
마운트 포인트가 몇 개 필요하다. /sys와 /proc 마운트 포인트는 sysfs와 procfs 가상 파일 시스템을 이동하는 데 사용된다. /dev 디렉터리는 mdev에 의해 사용되는 tmpfs 파일 시스템을 마운트 포인트로서 사용한다. 이 디렉터리들은 여타 공간을 차지하지 않는다.
$ cd $HOME/7800/rootfs
$ mkdir sys proc dev
그 밖의 것들
/etc 디렉터리는 셸 프롬프트가 나타날 때까지는 엄격히 말해 필수적이지 않지만 셸 프롬프트가 나타난 후엔 아주 유용하다. 초기 부팅 동안 가장 중요한 부분은 init.d 서브디렉터리인데, init은 시스템의 시작에 필요한 파일을 여기서 검색한다. 간단한 rcS 스크립트를 생성한 후 초기 시스템 스타트업용으로 실행 권한을 부여해 보라.
$ mkdir rootfs/etc/init.d
다음과 같이 내용을 채워 넣고 rootfs/etc/init.d/rcS 파일을 생성하자.
#!/bin/sh
echo "Hello, world!"
이제 실행 파일로 만든다.
$ chmod 755 rootfs/etc/init.d/rcS
|