 |
|
파일 시스템
루트 파일 시스템
일반적으로 리눅스는 단일한 루트 파일 시스템을 하나만 갖는다. 부트 동안 장치 드라이버 같은 것들을 로드하고 설정하기 위해 임시 루트 파일 시스템을 사용하고, 그러고 나서 실제 루트 파일 시스템을 얻어 옮겨가는 게 일반적이다. TS-7800도 이러한 SD 드라이버와 다양한 설정 옵션을 위해 임시 파일 시스템(초기 램디스크나 initrd라고 부름)을 사용한다. 사실 램디스크는 다른 시스템에서 부트 로더에 의해 조작될 수도 있는 많은 것(사용할 최종 루트 파일 시스템을 결정하는 것 따위)을 위해 사용된다.
파일 시스템 조작
일반적인 경고가 적용된다. 파일 시스템 오퍼레이션에는 대부분 루트 권한을 필요로 한다. 몇 가지 예외 사항과 차선책이 있다. 가장 주목할 만한 방법은 fakeroot 유틸리티/라이브러리인데, 이걸 쓰면 "루트인 척 하는 지원 기능"을 이용하여 애플리케이션을 빌드할 수 있도록 해준다. 이걸 이용해 가상 루트 파일 시스템을 조작하여 소유자, 권한 등을 제어한다. 그렇지만 권한 등 관련 내용은 분리된 데이터베이스에서 관리되며 실제 권한에 대한 오퍼레이션은 필요없다. 이는 루트가 아닌 사용자가 가상 루트 권한을 갖고 디렉터리 계층 구조를 조작할 수 있도록 하며, 궁극적으로 사용자가 생성할 수 없는 권한을 갖는 파일을 담는 아카이브나 파일 시스템 이미지를 생성할 수 있다.
루트 변경
확실히 말해 이야기의 일부분이긴 하지만 chroot 명령으로 루트 파일 시스템을 바꾸는 것만으로는 충분치 않다. 이를 위한 도구가 pivot_root로서 어떤 이름이 붙은 디렉터리를 새로운 루트 디렉터리로 만들어 옛날 루트 디렉터리를 다른 이름으로 "이동"(실제로는 마운트 포인트를 변경)한다.
아주 최초는 아닌 루트
이 튜토리얼의 목적상 필자는 보드와 함께 제공되는 기본 initrd 이미지면 충분하다고 가정한다. 리눅스 커널 배포판에서는 적당한 initrd 이미지를 만들어낼 수 있을 만한 어느 정도의 지원은 하고 있고, 이걸 자세히 안다는 게 실제 배포판을 빌드하는 걸 이해하는 데에 결정적으로 중요한 요소는 아니다. 필자는 그저 시스템을 이동하는 데 필요한 중요한 내용을 소개할 것이고, 그러고 나서 실제 루트 파일 시스템이 어떻게 되어 가는지에 초점을 맞출 것이다.
파일 시스템 이미지
대부분의 리눅스 사용자는 ISO CD-ROM이나 DVD 파일 시스템으로 된 이미지 파일에 익숙할 것이다. 리눅스는 여타 파일 시스템의 이미지를 생성하여 사용할 수 있도록 지원한다. 사실 디스크 파티션이라고 해도 -o loop 옵션으로 mount하여 쓸 수 있도록 파일로 취급해버릴 수도 있다. 예를 들어 필자가 이번 작업을 하면서 TS-7800에서 사용하는 initrd 이미지 복사본을 하나 만들었는데 다음 같이 하였다.
$ dd if=/dev/sdd3 of=initrd.dist bs=16k
$ cp initrd.dist initrd.local
이 파일만 있으면 파일 시스템에 뭐가 있는지 보기 위해 마운트하는 게 가능하다. 복사본으로 이름 붙인 initrd.local은 편집한 로컬 버전이다. initrd.dist는 나중에 깨졌을 경우를 대비해둔 안전한 원본이다.
$ mount -o loop initrd.local /mnt
initrd는 무슨 일을 하는가?
initrd는 실제 루트 파일 시스템을 찾고 마운트하기 위해 장치를 부트스트랩하는 데 사용되는 가장 기본적인 초기 파일 시스템을 제공한다. 기본 커널 설정은 루트로서 initrd(/dev/ram0)를 사용하도록 고정되어 있고 시작 시 linuxrc 스크립트를 구동하도록 하고 있다. 서로 다른 루트 파일 시스템들에 대해 조금씩 변형된 형태로 제공되는 스크립트들이 몇 가지 있긴 하다. 확실한 건 linuxrc-sdroot를 살펴보는 것이다.
initrd 준비
linuxrc-sdroot 프로그램은 루트로 SD카드를 사용하도록 시스템을 설정하려 시도한다. 네 번째 fdisk 파티션에 ext3 파일 시스템으로 SD카드를 정확히 설정했다고 가정하고 스크립트는 해당 파일 시스템을 마운트한 후 파일 시스템 상에서 /sbin/init를 구동한다. 이는 괜찮은 전략 같아 보인다. 따라서 initrd 이미지에 약간의 변화가 필요하다. 먼저 linuxrc 심볼릭 링크가 linuxrc-sdroot를 가리키도록 변경한다. 두 번째로 원래 설정되어 있던 데비안(Debian) 빌드 대신 uClibc 빌드로 동작하도록 스크립트를 업데이트한다.
SD 드라이버
TS-7800용 SD 드라이버에는 비공개(proprietary) 모듈이 포함되어 있어서 tssdcard.ko 파일을 런타임에 수동으로 복사해 넣어 로드해야 한다. 배포판 initrd에 있는 파일은 새로운 커널에서 잘 동작하기에 변경해줄 필요는 없다.
부트스트랩 루틴 전환
커널은 linuxrc라는 프로그램을 구동한다. 기본값으로 이는 linuxrc-fastboot라는 프로그램에 대한 심볼릭 링크인데, initrd 루트 파일 시스템으로 빠르게 전환된다. 이 링크를 지우고 linuxrc-sdroot 대신에 linuxrc를 링크하면 드라이버가 로드가 될 경우 시스템은 SD 상의 마지막 파티션으로부터 부트를 시도한다.
부트스트랩 루틴 변경
스크립트는 에러를 검사하고, 에러가 발견되면 내장 플래시로 mount한다. 에러가 없다면 SD카드로 파일 시스템을 마운트를 하며 그러고 나서 변경을 시도한다. 사실 부트스트랩 루틴은 이 빌드에 영향을 주는 작은 기교를 갖고 있는데, pivot_root 호출 후 마지막 클린업 작업을 위해 rootfs가 아닌 자체 마운트 유틸리티를 사용하려고 시도한다. 그런데 이게 데비안 설치본과는 잘 동작하는 데 최소화 버전인 uClibc 설치본과는 동작하지 않는다. 해결책은 파일 끝 부분(else 이후 부분)의 다음 pivot_root 명령줄을 바꿔주는 것이다.
pivot_root . ./initrd
/bin/mount -n --move ./initrd/dev ./dev
/bin/mount -n --move ./initrd/sys ./sys
/bin/mount -n --move ./initrd/proc ./proc
exec /sbin/init < $CONSOLE > $CONSOLE 2>&1
이렇게 하면 스크립트가 다른 시스템의 동적 연결 실행 파일을 실행하는 대신 여러분이 생성할 새로운 실행 파일(uClibc, 정적 연결 실행 파일)을 구동하도록 할 수 있다(튜토리얼 없이 했더라면 아마도 이것저것 다 설정해 보고 암호같은 오류 메시지를 받아본 다음에서야 알았을 것이다).
디스크 이미지 언마운트
initrd 디스크 이미지는 다음과 같이 언마운트한다.
$ umount /mnt
|