강좌

HOME > 강좌 >
강좌| 리눅스 및 오픈소스에 관련된 강좌를 보실 수 있습니다.
 
누구나 쉽게 배우는 임베디드 리눅스⑤
조회 : 18,019  


누구나 쉽게 배우는 임베디드 리눅스


루트
파일 시스템은
어떻게 구성되는가

 

 

지난 호에서는 리눅스 커널을 빌드하고 실행해 보면서,

커널 부팅 메시지가 출력 도중 멈추는 데까지 확인을 보았다.

커널 이미지만 가지고서는 부팅을 하는 불충분하기 때문이다.

이번 시간에는 부팅을 완료하는 데까지 필요한 마지막 조건인 루트 파일 시스템에 대해 다룰 것이다.

 

_ 장영준 삼성전자 SW연구소 Linux Technology Group 선임 연구원

 

연재 순서

임베디드 리눅스 걸음마

교차 개발 환경을 구축하자

부트로더 설정은 이렇게

커널을 올려보자

루트 파일 시스템은 어떻게 구성되는가

2% 부족함을 채워보자

 

 

부팅에 필요한 파일 시스템, RFS

리눅스가 적재된 PC 사용하기 위해서는 필요한 요소가 바로 하드디스크, 플래시와 같은 저장장치이다. 여기에는 PC 사용하기 위해 필요한 프로그램과 자료들이 저장돼 있고, 시스템 초기화 각종 주변장치들을 제어하기 위한 파일 부팅에 필요한 내용도 포함돼 있다. 리눅스에서 이러한 저장장치는 파일 시스템으로 관리되고 있는데, 시스템 초기화 관리에 필요한 내용을 담고 있어 부팅에 필요한 파일 시스템을 루트 파일 시스템(Root File System, 이하 RFS)이라고 한다.

리눅스가 설치된 PC 보면/라는 디렉토리가 있고, /아래의 하위 디렉토리로 /bin, /sbin, /lib등의 디렉토리가 있음을 확인할 있다. 여기서/라는 디렉토리는 저장장치와 연결이 되어 있어, 리눅스의 동작에 필요한 기능을 담고 있다. 이때/ 루트 파일 시스템(RFS) 된다.

그렇다면 커널 부팅을 완료하기 위해서는 타겟에 RFS 적재하고, 커널에서 RFS 어느 위치에 있는가를 알려주는 과정을 거쳐야 것이다. 이제부터 RFS 구축하고, 이를 이용하여 커널 부팅을 완료하는 과정에 대해 알아 보겠다.

 

RFS 디렉토리 생성

RFS 만들기에 앞서, 그동안의 과정에서는 oss라는 유저 계정을 만들어 사용해 왔는데, 이번 시간은 root 계정으로 진행을 하겠다. 과정 중간에 root 계정으로만 있는 일들이 있기 때문이다. root 계정으로 RFS 구성하는 작업은 자칫 PC 시스템 파일을 잘못 건드릴 우려가 있기 때문에 다른 작업 비해 각별한 주의를 요한다.

먼저, RFS 디렉토리를 생성한다.

 

# cd ~oss/

# mkdir mk_rfs

# cd mk_rfs

# mkdir rfs tmp

 

 

여기에서 rfs RFS 구성할 디렉토리이고, tmp 과정 중에 사용될 임시 디렉토리이다. 이어서 실제 RFS 구성하게 rfs 디렉토리를 구성해 보자.

 

# cd rfs

# mkdir bin sbin etc dev lib usr mnt proc sys

 

 

이제부터는 디렉토리의 내용을 채워 보도록 하겠다.

 

busybox 설치

RFS 구성하는데 필요한 프로그램들을 설치하는 과정이다.

리눅스를 구동하는데 필요한 가장 기본이 되는 프로그램은 (shell)이다. GUI모드가 아닌 커맨드 라인 모드로 리눅스 부팅을 하게 되면 프롬프트가 뜨게 되고, 여기에서 명령어를 입력하여 다양한 프로그램을 실행하게 된다. 이러한 역할을 수행하는 쉘을 비롯하여, 시스템 동작에 필요한 ls, mv, cp, ps등의 유틸리티를 설치해야 기본적인 리눅스 명령어를 실행할 기반이 갖춰지는데, 이러한 프로그램 각각을 구하여 빌드해서 설치해도 되지만, 여기서는 임베디드 리눅스에서 많이 사용되는 busybox라는 프로그램을 이용하기로 한다.

busybox 역시 오픈소스이기 때문에 무료로 사용가능하고,공식사이트는http://www.busybox.net/

이다. 자세한 정보 소스 코드를 구할 있다. busybox 위에서 언급한 shell 비롯하여, ls, mv, cp 기본적으로 필요한 프로그램들을 한데 묶어 busybox라는 하나의 파일로서 실행되도록 만들어 준다. 필요한 기능들을 하나로 관리해 주기 때문에 설치가 편리하고, 무엇보다도 각각을 직접 만들었을 때보다 실행파일의 크기가 현저히 작아진다는 이유로, 저장공간에 제약을 받는 임베디드 리눅스에서 많이 사용되고 있다. 물론, 크기를 작게 만들기 위한 프로그램이기 때문에, 모든 기능이 들어 있는 것은 아니므로, 필요한 프로그램을 추가로 설치해야 필요가 생기기도 하는데, 기본 기능만을 필요로 하는 임베디드 시스템에서는 busybox 하나만으로도 충분히 사용 가능하다.

그러면 busybox 설치 방법에 대해 알아보겠다. 여기서는 최신 안정 버전인 1.8.2 기준으로 설명한다.

 

먼저, 공식 사이트에서 소스 코드를 다운로드받고, 압축을 해제한다.

 

# wget http://busybox.net/downloads/busybox-1.8.2.tar.bz2

# tar - xjf busybox-1.8.2.tar.bz2

# cd busybox-1.8.2

 

busybox 빌드는 리눅스 커널과 비슷한 방식으로 진행된다. Makefile ARCH CROSS_COMPILE

항목을 다음과 같이 수정한다.

 

Makefile (Line 175)

 

#ARCH ?= $(SUBARCH)

#CROSS_COMPILE ?=

ARCH = arm

CROSS_COMPILE = arm-linux-

 

다음으로 busybox 빌드하기 위한 옵션을 지정한다.

 

# make menuconfig

위와 같은 화면이 나오고, 목적에 맞게 필요한 프로그램을 등록하거나 기능을 선택할 있다. 디폴트로 자주 사용되는 옵션이 지정되어 있으므로, 여기서는 옵션 변경 없이 저장하고 종료한다.

 

 

마지막으로 빌드 인스톨 작업을 수행한다.

 

# make

# make CONFIG_PREFIX=./_inst install

 

인스톨 과정에 추가된 CONFIG_PREFIX 빌드가 완료된 busybox _inst 디렉토리로 설치해준다.

 

생성된 _inst 디렉토리의 내용을 보면 bin, linuxrc, sbin, usr 라는 디렉토리 파일이 생성되었음을 확인할 있고, 이를 RFS 복사한다.

 

# cp - af _inst/* ~oss/mk_rfs/rfs/

 

* lib

 

커널 부팅 후에 init 등의 프로그램을 실행하기 위해 필요한 라이브러리를 구성한다. 라이브러리는 설치된 툴체인 디렉토리에서 찾을 있다. 강좌에서 설치

툴체인의 라이브러리들은 /opt/crosstool/gcc-3.4.5-

glibc-2.3.6/arm-linux/lib 위치해 있다.

필요한 최소한의 파일은 다음과 같다.

ld-2.3.6.so

ld-linux.so.2

libcrypt-2.3.6.so

libcrypt.so

libcrypt.so.1

libm-2.3.6.so

libm.so

libm.so.6

libc.so.6

libc-2.3.6.so

 

# cp - af /opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux/lib/ld-2.3.6.so ~oss/mk_rfs/rfs/lib/

 

위와 같은 방법으로 lib 디렉토리로 파일들을 복사한다. 이때, -a 옵션을 붙이도록 한다. 파일들 중에는 링크 파일도 포함되어 있기 때문에 속성을 그대로 유지하여 복사하기 위함이다.

 

 

* etc

etc 디렉토리는 시스템 환경 설정에 필요한 내용을 담고 있으며 모두 텍스트 파일로 구성되어 있기 때문에, 편집기를 이용하여 수정할 있다. 다음과 같이 구성한다. inittab 이라는 파일을 생성하고 아래와 같이 입력한다.

 

# vi inittab

::sysinit:/etc/rc.sysinit

::ctrlaltdel:/sbin/reboot

::respawn:/bin/sh

 

 

rc.sysinit 파일을 생성한다.

 

# vi rc.sysinit

mount -n -t proc /proc /proc

 

rc.sysinit 실행 가능한 파일이어야 하므로, 다음과 같이 실행 권한을 부여한다.

 

# chmod +x rc.sysinit

 

 

* dev

디바이스 파일들이 위치하는 디렉토리이다. 디바이스 파일은 리눅스 시스템에 장착되어 있는 여러 가지 장치들을 제어하기 위한 특수 파일로서, mknod라는 명령어를 사용하여 만들 있고, 루트 권한으로만 만들 있다. 보통은 장치 파일들의 개수가 많은 편이기 때문에, 일일이 직접 생성하기보다는 MAKEDEV 라는 script 이용하거나, udev라는 동적 생성 방법을 이용한다. busybox에서는 mdev 라는 기능을 이용할 수도 있다. 지면 관계상 이들 방법에 대한 소개는 하지 않고, 여기서는 필요한 최소한의 파일들만을 호스트 PC /dev 디렉토리에서 복사해 사용하겠다.

 

# cd ~oss/mk_rfs/rfs/dev

# cp - af /dev/console .

 

console이라는 디바이스 파일을 복사한 것인데, 이와 같은 방법으로 zero, null, mem, urandom, tty, ttyS*, ram* 파일도 복사하도록 한다.

 

이상으로 RFS 구성하는데 필요한 최소한의 내용 구성을 완료하였다. 다음으로 구성을 가지고, RFS 이미지를 만드는 과정을 알아본다.

 

* RFS 이미지 생성

RFS 타겟에 적재 가능한 형태로 만들기 위해 RFS 이미지를 만드는 과정은 다음과 같다. 과정 역시 루트 권한으로 수행해야 한다.

 

# cd ~oss/mk_rfs

 

dd 명령을 이용하여 4M 크기를 가지는 ram_2440 이라는 이름의 파일을 생성한다.

 

# dd if=/dev/zero of=ram_2440 bs=1K count=4096

 

다음으로 파일 시스템을 생성한다. 여기서는 mke2fs 명령을 사용하여 ext2 파일시스템으로 생성하기로 한다. 명령어 수행시Proceed anyway? (y,n)이라는 물음이 나오는데, 이때는 y 입력하면 된다.

 

# mke2fs ram_2440

 

생성된 이미지에 RFS 디렉토리를 복사한다. 다음과 같은 과정을 거친다.

 

# mount ram_2440 tmp - o loop

# cp - af rfs/* tmp/

# umount ram_2440

# gzip -9 ram_2440

 

 

과정을 거치면, ram_2440.gz 라는 파일이 생성됨을 확인할 있다.

 

 

* 커널 옵션 변경

마지막으로, 생성된 RFS 이미지의 위치를 커널이 있도록, 커널 옵션을 수정하여 재빌드하는 과정이 필요하다. 리눅스 디렉토리로 이동하여 커널의 환경설정 파일인 .config 파일의 CONFIG_CMDLINE 항목을 다음과 같이 수정한다.

 

# vi .config

CONFIG_CMDLINE="root=/dev/ram0 rw initrd=0x30800000,4M console=ttySAC0"

 

RFS 이미지를 타겟의 램에 적재하여 램디스크로서 실행할 것이기 때문에, RFS 적재될 위치인

0x30800000 번지 크기 4M 지정해 주고, 커널을 재빌드한다.

 

# make oldconfig

# make zImage

 

 

* 커널 부팅

이상으로 RFS 구성을 마쳤고, 최종적으로 커널을 부팅해볼 차례가 되었다.

지난 시간에 타겟에 커널을 실행시킨 상황에서 RFS 램디스크 이미지를 추가로 적재하여, 커널 부팅을 완료하는 과정을 알아보기로 한다. 먼저, 커널 이미지를 /tftpboot 디렉토리로 복사한다.

# cd /home/oss/elinux/linux-2.6.23.9

# cp arch/arm/boot/zImage /tftpboot

 

다음으로 램디스크 이미지를 /tftpboot 디렉토리로 복사한다.

 

# cd /home/oss/elinux/mk_rfs/

# cp ram_2440.gz /tftpboot

 

필요한 이미지를 tftpboot 디렉토리로 옮긴 , 타겟을 실행하여 적절한 위치에 해당 이미지를

다운로드 한다.

(TARGET) # tftp 30008000 zImage

(TARGET) # tftp 30800000 ram_2440.gz

 

지난 호에서와 같이 커널의 시작 주소인 0x30008000 번지를 실행하면, 커널 부팅 0x30800000번지에 있는 RFS 찾게 되고, 이를 이용하여 부팅의 마지막 과정인 RFS 프로그램을 실행하여 커널 프롬프트가 뜨는 것을 확인할 있다.

(TARGET) # go 30008000

 

 

 

지금까지 장장 5회에 걸쳐 리눅스를 임베디드 시스템 타겟에서 실행시키는 필요한 모든 과정에 대해 살펴 보았다. 상당히 많은 내용을 한정된 지면에 실으려다 보니, 필요한 과정만을 소개하게 되었고, 언급하지 못하고 지나친 부분이 많았는데, 마지막 회에서는 이러한 점들을 보충하는 차원에서 2%부족한 부분을 채워보는 시간을 가지도록 하겠다.

 

 

출처 : 공개 SW 리포트 11호 페이지 50 ~ 55 발췌(2008 03) - 한국소프트웨어 진흥원 공개SW사업팀 발간

 


[원글링크] : https://www.linux.co.kr/home2/board/subbs/board.php?bo_table=lecture&wr_id=1649


이 글을 트위터로 보내기 이 글을 페이스북으로 보내기 이 글을 미투데이로 보내기

 
한국소프트웨어진흥원 공개SW사업팀