NFS 파일 시스템으로 부팅하기

■ 개요

이 문서는 ESP-CX 에서 NFS 파일 시스템을 이용하여 부팅하기 위한 처리 내용을 기술한 문서입니다.

■ 의의

네트워크 내의 서버 환경에서 NFS 를 통해 개발 보드를 부팅할 수 있게 합니다.
개발 환경에 NFS 를 통해 보드에서 제한되는 용량의 한계를 해소하고 파일 수정 및 테스트가 용이 하도록 하고자 한 것입니다.

■ 참고

이 문서는 제공되는 커널 및 램디스크 복사 등의 설명은 생략하고 진행하였으므로 이해해주시기 바랍니다.

■ 테스트 환경

개발 서버 : FALinux 의 Fedora Core 3서버
개발 보드 : FALinux 의 ESP-CX 보드
부트로더 버전 : EZBOOT.X5. ESP-CX V1.02

■ 적용 환경

ESP-CX 보드에서 진행한 절차대로 EZ-X5, ESP-MMI보드에서 Nfs 부트를 성공을 하였습니다.

0. 참고 문서

제 목 : EZ-X5 NFS 루트 마운팅 <유영창 님의 글>
주 소 : http://wiki.falinux.com/wiki.php/NFS%B7%E7%C6%AE%C8%AD%C0%CF%BD%C3%BD%BA%C5%DB
제 목 : NFS를 통한 루트 파일 시스템 마운트하기(nfsroot)
주 소 : http://wiki.kldp.org/wiki.php/LinuxdocSgml/Kernel-nfsroot-TRANS

1. 개발 서버에서 준비

사내 개발 서버인 Arm26 서버에서 작업을 하였습니다.

응용 : 작업을 진행한 서버 대신 VMware 에서 환경을 통해 진행하실 수 있습니다. (Arm26 서버 -> VMware 가상 서버)

가장 먼저 해야 할것은 서버에서 보드에 NFS 파일 시스템을 지원해야 하기 때문에 이와 관련된 처리를 해야 합니다.

다음은 서버에 NFS 지원을 위한 필요한 작업 내용입니다.

서버에서 제공할 NFS 파일 시스템 디렉토리를 생성합니다.

이름을 nfsroot 라고 지었습니다.

[root@arm26 /]# mkdir /nfsroot

작업 환경에 권한 제약이 없도록 모든 권한을 부여해 줍니다.

[root@arm26 /]# chmod 777 /nfsroot

NFS 파일 시스템의 환경 파일을 수정하여 위에서 제작된 디렉토리를 NFS 서비스 디렉토리로 만들어 줍니다.

[root@arm26 /]# vi /etc/exports

아래 NFS 환경 설정 파일 내용은 각 PC 마다 다를 수 있습니다.

[원래 파일 내용]

/nfs localhost(rw,insecure,sync)
/nfs 192.168.10.0/24(rw,insecure,sync)

기존 내용에 다음을 추가 합니다.
위에서 /nfsroot 라는 디렉토리를 만들었으니 넣어줍니다.
(vi 에서 Shift+Y 로 복사하여 P 로 붙여넣기를 한 후 수정하면 편함!)

[추가 내용]

/nfsroot 192.168.10.0/24(rw,insecure,sync)

내용을 추가하면 바뀐 내용은 아래와 같습니다.

[수정된 파일 내용]

/nfs localhost(rw,insecure,sync)
/nfs 192.168.10.0/24(rw,insecure,sync)
/nfsroot 192.168.10.0/24(rw,insecure,sync)

위의 환경설정에서 바뀐 내용을 적용하기 위해 nfs 재시작 하도록 하겠습니다.

nfs 명령어가 있는 디렉토리로 이동합니다.

[root@arm26 nfs]# cd /etc/init.d/

nfs 명령어를 재시작 하도록 합니다.
restart 명령어 보다는 확실히 해주기 위해서 stop 후에 start 를 해줍니다.

[root@arm26 init.d]# ./nfs stop
[root@arm26 init.d]# ./nfs start

2. 보드에서 NFS 가 마운트 되었는지 확인합니다.

사용된 보드는 회사 제품 중의 하나인 ESP-CX 보드 입니다.

시리얼 통신이 가능한 터미널 프로그램을 사용하여 보드에 연결을 합니다.

보드에 전원을 인가한 후에 부팅을 합니다.

로그인 후에 아래와 같이 마운트 할 곳을 찾아서 폴더 이동을 합니다.

개발 보드 에서 /mnt 디렉토리 아래 nfs 디렉토리에 개발 서버의 nfsboot 디렉토리를
마운트 할 것입니다.

아래와 같이 이동을 합니다.

[root@falinux ~]$ cd ..

[root@falinux /]$ ls
app etc lost+found root tmp
bin home mnt sbin usr
dev lib proc sys var

[root@falinux /]$ cd mnt

[root@falinux mnt]$ ls
cf mmc nand nfs temp usb

위와 같이 이동을 하여 /mnt 디렉토리 아래 nfs 디렉토리가 있는 것을 확인합니다.
없을 경우 mkdir 명령어로 디렉토리를 생성해 줍니다.

[root@falinux /]$ mkdir -p /mnt/nfs

이용에 제약이 없도록 모든 권한을 주도록 합니다.

[root@falinux /]$ chmod 777 /mnt/nfs

아래와 같은 명령어로 개발 보드에 서버의 디렉토리를 마운트 해줍니다.

개발 서버의 아이피가 192.168.10.26 이므로 지정해주고 /nfsroot 라고 만든 디렉토리를
개발 보드의 /mnt/nfs 로 마운트 합니다.

[root@falinux /]$ mount -t nfs -o nolock 192.168.10.26:/nfsroot /mnt/nfs/

3. 개발 서버에서 부트에 필요한 커널 작업을 합니다.

개발시 사용되었던 ESP-CX 보드의 커널과 램디스크를 내용을 복사합니다.

제품 구매시 사용했던 CD안에 이미지가 존재합니다.

project 라는 디렉토리에 esp-cx-nfsroot 라는 디렉토리를 만들어서 ESP-CX 관련 커널을 넣었습니다.

/project/esp-cx-nfsroot/kernel

복사가 완료된 후에 esp-cx-nfsroot 디렉토리로 이동합니다.

[root@arm26 project]# cd esp-cx-nfsroot

kernel 디렉토리 안으로 들어갑니다.

[root@arm26 esp-cx-nfsroot]# cd kernel

커널의 내용을 수정하기 위해서 최신 커널 디렉토리로 들어갑니다.

ESP-CX에 사용된 커널의 최신 버전은 linux-2.6.11.9 이었습니다.

[root@arm26 kernel]# cd linux-2.6.11.9/

커널에서 옵션을 수정해주기 위하여 아래와 같은 명령을 수행합니다.

[root@arm26 linux-2.6.11.9]# make menuconfig

메뉴 컨피그 화면에서 아래 그림과 같이 메뉴를 이동하여 항목에 체크를 해주시면 됩니다.

진행할 과정은 다음과 같습니다.

Networking support --->
Networking options --->
[*] IP: kernel level autoconfiguration
[*] IP: DHCP support (NEW)
[*] IP: BOOTP support (NEW)
[*] IP: RARP support (NEW)

진행되는 과정을 아래 그림과 같이 하나씩 따라가시면 됩니다.

Networking support ---> 메뉴로 이동합니다.

Networking options ---> 메뉴로 이동합니다.

아래 설명에서 빨간색으로 표시된 항목은 필수적으로 체크를 해야하고
그 아래 항목은 부수적으로 자동으로 아이피를 받을 때 체크하는 항목입니다.

[*]   IP:  kernel level autoconfiguration
[*] IP: DHCP support (NEW)
[*] IP: BOOTP support (NEW)
[*] IP: RARP support (NEW)

아래 그림을 보고 설정해 주시면 됩니다.

IP: kernel level autoconfiguration 메뉴를 체크하면 숨겨져 있던 항목이 나타납니다.

위의 그림과 설명을 보고 진행하였으면 아래와 같이 진행하여 체크해 주시면 됩니다.
위의 항목은 자동으로 아이피를 할당받을 때 사용되는 항목이므로 수동으로 설정할 경우엔 반드시 체크할 필요는 없습니다. 필자는 자동으로 지정해 줄 것이므로 체크를 해주었습니다.

그 다음으로 진행될 내용입니다.

File systems  --->
Network File Systems --->
<*> NFS file system support
[*] Provide NFSv3 client support
[*] Provide NFSv4 client support (EXPERIMENTAL)
[*] Allow direct I/O on NFS files (EXPERIMENTAL)
[*] Root file system on NFS

File systems ---> 메뉴로 이동합니다.

Network File Systems ---> 메뉴로 이동합니다.

<*> NFS file system support 메뉴가 보이는 데, 체크를 하면 아래 세부메뉴가 나타납니다.

<*> NFS file system support 의 메뉴 아래에 다음과 같은 항목이 나타납니다.
여기서 아래 세부 항목과 상관없이 아래 메뉴의 [*] Root file system on NFS 부분에 체크를 해야합니다.

 [*]   Provide NFSv3 client support
[*] Provide NFSv4 client support (EXPERIMENTAL)
[*] Allow direct I/O on NFS files (EXPERIMENTAL) [*] Root file system on NFS

위의 그림과 같이 설정을 하였으면 종료를 하면서 저장을 합니다.

옵션을 수정하였으니 커널 내용을 zImage 로 만들어야 합니다.

아래 명령어를 이용하여 zImage 를 만듭니다.

[root@arm26 linux-2.6.11.9]# make zImage

이렇게 만들어진 이미지를 zImage.x5.esp-cx-nfs 라는 이름으로 저장하도록 하겠습니다.

개발 보드에서 이지부트 메뉴를 통해 불러올 수 있도록 /tftpboot 디렉토리에 저장하도록 다음과 같이 수행합니다.

[root@arm26 linux-2.6.11.9]# cp arch/arm/boot/zImage /tftpboot/zImage.x5.esp-cx-nfs

5. 개발 보드에서의 nfs 설정

이제 개발 보드에서 이지부트 메뉴를 통해 부팅시에 기존의 램디스크에서 이미지를 불러오는 방식에서
개발 서버에서 마운트 시킨 NFS FILE SYSTEM 디렉토리인 /nfsroot 를 통해 부팅하기 위해 아래와 같은 작업을 진행하였습니다.

먼저 0번 항목의 참고 문서를 보고 NFS FILE SYSTEM 에 대한 네트워크 설정을 아래와 같이 진행하였습니다.

진행할 항목에 대해서 생각해 보았습니다.

루트 파일 시스템이 NFS 를 사용할 것임을 알려줍니다.

root=/dev/nfs

NFS 파일 시스템 정보는 다음과 같았습니다.

nfsroot=[(server-ip):](nfsroot-dir) [(nfs-options)]

우리는 보통 다음과 같이 마운트 합니다. 약간은 틀리더라도 이와 비슷한 조건이 붙습니다.

mount -t nfs -o nolock 192.168.10.26:/nfsroot /mnt/nfs

위의 nfsroot 정보를 개발 서버 IP 와 NFS FILE SYSTEM 이 들어갈 폴더, 그리고 옵션을 아래와 같이 적어주었습니다.

nfsroot=192.168.10.26:/nfsroot,nolock

그 다음은 IP 항목입니다.
각 항목의 내용은 참조 문서에서 가져와서 적어 놓았습니다.

ip=(client-ip):(server-ip):(gw-ip):(netmask):(hostname):(device):(autoconf) (client-ip)
클라이언트의 IP 주소. 만약 비었다면 RARP나 BOOTP에 의해 결정된다.
어떤 프로토콜이 쓰일 것인지는 커널 설정시 결정한 것이나 파라미터에 달려있다.
비어있지 않다면 RARP나 BOOTP는 쓰이지 않는다. (server-ip)
NFS 서버의 IP 주소. 만약에 RARP가 클라이언트의 주소를 결정했고
이 파라미터가 비어있지 않다면 오직 여기서 정한 서버만이 받아들여진다.
RARP서버와 NFS서버를 다르게 하려면 RARP 서버를 여기에 써라.(혹은 빈칸으로 남겨놓던지),
그리고 NFS 서버를 "nfsroot"파라미터에 정해주면 된다.
만약 여기가 비어 있다면 RARP나 BOOTP에 응답한 서버가 NFS서버로 쓰일 것이다. (gw-ip)
서버가 다른 서브넷에 있을때의 게이트웨이의 IP 주소.
여기가 비어 있다면 게이트 웨이는 쓰이지 않고 서버가 로컬 네트워크에 있다고 가정하거나 BOOTP가 알려준 값을 쓴다.
로컬 네트워크 인터페이스에 대한 넷마스크.
비어 있다면 클라이언트 IP 주소에서 추측을 한 값이 넷마스크로 쓰인다.
아님 BOOTP 응답으로 설정되거나. (hostname)
클라이언트의 이름. 비었다면 클라이언트의 IP 주소는 아스키 표현으로 쓰이거나 BOOTP에 의한 값이 쓰인다. (device)
쓸 네트워크 디바이스의 이름.
비었다면 RARP나 BOOTP 요청에 대해 모든 디바이스가 쓰이고 먼저 응답받은 것이 설정된다.
하나의 디바이스만 있다면 여기를 빈칸으로 남겨두어도 좋다. (autoconf)
자동설정에 대한 방법. 여기서 설정한 RARP나 BOOTP가 쓰인다.
둘다 설정하거나 비워둔다면 커널 설정시 결정한 프로토콜이 쓰인다. "off"는 자동설정을 안 쓴다는 것이다.

위의 설명은 아래와 같이 정의할 수 있습니다.

ip = 보드 IP : 서버 IP : 게이트웨이 IP : 서브넷마스크 : 클라이언트 이름 : 이더넷 : 자동설정 여부.

순서에 따라서 아래와 같이 작성하였습니다.
보드 IP : 서버 IP : 게이트웨이 : 서브넷마스크 : 클라이언트 이름(x5xhost) : 이더넷0 사용 : IP 자동 설정은 OFF

ip=192.168.10.202:192.168.10.26:192.168.10.1:255.255.255.0:x5thost:eth0:off

위와 같이 3가지 항목에 대해 작성이끝났습니다.

아래는 정리된항목입니다.

완성된 내용
root=/dev/nfs
nfsroot=192.168.10.26:/nfsroot,nolock
ip=192.168.10.202:192.168.10.26:192.168.10.1:255.255.255.0:x5thost:eth0:off

6. NFS FILE SYSTEM 정보를 가지고 보드의 이지부트 메뉴에서 설정합니다.

보드를 부팅합니다. 일반적인 부팅을 하지 말고 를 눌러서 이지 부트 메뉴로 들어갑니다.

설정을 바꿔주기 위해 set 명령어를 칩니다.

EZBOOT> set

여러 메뉴가 보입니다.

먼저 확인할 것은 아래의 항목입니다.

2. LOCAL IP 는 보드에서의 IP 입니다.
3. 개발 서버의 IP 입니다.

위에서 NFS FILE SYSTEM 을 할때 적어놓았던 IP 와 맞는지 비교하여 확인해 줍니다.

1. MAC Address [fa:05:02:00:00:00]
2. LOCAL IP [192.168.10.202] ◀ 보드 아이피
3. HOST IP [192.168.10.26] ◀ 서버 아이피
4. Host tftp directory []
5. zImage file name [zImage.x5.esp-cx]
6. ram disk file name [ramdisk-12M.gz]
7. boot loader file name [ezboot.x5.esp-cx]

zImage 파일을 불러오는 것은 개발 서버에 디폴트로 "/tftpboot/%s" 로 지정되어 있습니다.

개발 서버에서 만들어 놓은 커널의 zImage 를 불러오도록 합니다.

우리는 zImage.x5.esp-cx-nfs 라고 이름을 붙이고 파일을 만들었습니다.

Select 에서 5번을 입력하고 이미지 파일 이름인 zImage.x5.esp-cx-nfs 를 적어줍니다.

Select >>5
5. zImage file name []
Newvalue : zImage.x5.esp-cx-nfs

아래와 같이 바뀐것을 확인할 수 있습니다.

5. zImage file name [zImage.x5.esp-cx]

그림에서 처럼 바뀐 것을 확인한 후, 저장을 하고 종료를 합니다.

Select >>S

Select >>0

저장된 정보를 적용하기 위해서 tfk 명령어를 이용하여 만든 커널을 개발 보드에 적용 시킵니다.

EZBOOT> tfk

아래와 같은 내용이 화면에 뜨면 정상적으로 완료 된 것입니다.

Receive zImage.x5.esp-cx-nfs
Send ARP Packet
ARP PACKET Resive
HOST MAC : [ 00 14 38 A7 65 0A ]
HOST IP : [192.168.10.26]
LOCAL IP : [192.168.10.202]
Resive Address : A180-0000
TFTP Request Send
OPTION [timeout 120 tsize 1233272]
ALL DATA RESIVE OK [ 1238090 bytes ]
Erase : OK
Write : OK
Verify: OK

다시 메뉴로 돌아가서 나머지 설정을 해줍니다.

EZBOOT> set

위에서 NFS FILE SYSTEM 을 준비하기 위해 만들었던 항목을 가져옵니다.
아래의 내용이었습니다.

root=/dev/nfs
nfsroot=192.168.10.26:/nfsroot,nolock
ip= 192.168.10.202:192.168.10.26:192.168.10.1:255.255.255.0:x5thost:eth0:off

위의 내용을 커널에서 부팅시 읽어올 수 있도록 커맨드 라인에 넣어줍니다.

이지 부트 메뉴 아래 3가지 부팅시 커널에서 처리할 명령입니다.

K. Kernel CMD 1st
M. Kernel CMD 2nd
N. Kernel CMD 3rd

각 항목에 내용을 추가하도록 하겠습니다.
완성된 내용을 한번에 등록하기엔 문장이 길어서 부분으로 끊어서 적용하도록 합니다.

이 때, 보드에서 필요한 명령어를 같이 사용하도록 해야 합니다.

램 디스크의 크기를 지정 mem = 64 추가

보드와 서버의 nfs 로 전송되는 네트워크 패킷 사이즈를 맞쳐주기위해rsize= 1024,wsize= 1024 추가

마지막에 처리될 콘솔 명령 console= ttyPXA2,115200 을 추가하였습니다.

그래서 아래와 같이 최종적으로 적어야 할 내용을 정리하였습니다.

최종적으로처리해야하는내용
mem=64M root=/dev/nfs nfsroot=192.168.10.26:/nfsroot,nolock,rsize=1024,wsize=1024
ip=192.168.10.202:192.168.10.26:192.168.10.1:255.255.255.0:x5thost:eth0:off
console=ttyPXA2,115200

최종적으로 정리된 내용을 아래와 같이 이지부트에 적용시킵니다.

EZBOOT> K
mem=64M root=/dev/nfs nfsroot=192.168.10.26:/nfsroot,nolock,rsize=1024,wsize=1024

EZBOOT> M
ip=192.168.10.202:192.168.10.26:192.168.10.1:255.255.255.0:x5thost:eth0:off

EZBOOT> N
console=ttyPXA2,115200

아래 그림과 같이 바뀐것을확인합니다.

내용을 바꾸었으니 저장을 하고 종료를 합니다.

아래 명령어로 저장을 하고 종료를 합니다.

Select >>S

Select >>0

7. 서버에서 NFS FILE SYSTEM 부트에 필요한 파일을 복사하는 작업을 합니다.

NFS 부트는 기존의 개발 보드에서 램디스크 내용을 불러오는 것과 달리 nfs 네트워크를 통해
부팅하는 것 이므로 nfs 디렉토리에 부팅에 필요한 램디스크 이미지를 넣어야 합니다.

처음에 지정한 /nfsroot 디렉토리에 램디스크 파일들을 저장할 것 입니다.

다른 옵션이 없는 처음의 램디스크 이미지를 사용하기로 했습니다.

사내 개발 서버에 램디스크 이미지를 사용하였습니다. (CD안에 포함되어 있는 이미지를 사용하면 됩니다.)

개발 서버 내에 base_ramdiskroot 파일이 존재하였습니다.

아래 명령 처럼 부팅시 필요한 기본적인 램디스크 폴더 내용을 /nfsroot 로 복사하도록 합니다.

[root@arm26 /]# cp -a /ramdisk/base_ramdiskroot/* /nfsroot/

/nfsroot 로 파일 복사가 제대로 되었는지 확인하러 갑니다.

[root@arm26 nfsroot]# cd /nfsroot/

아래와 같이 파일 리스트가 뜨면 정상적으로 복사가 완료된 것입니다.

[root@arm26 nfsroot]# ls -al
합계 68
drwxrwxrwx 16 root root 4096 6월 27 16:22 .
drwxr-xr-x 26 root root 4096 6월 27 15:43 ..
drwxrwxrwx 2 root root 4096 8월 2 2005 app
drwxr-xr-x 2 root root 4096 8월 2 2005 bin
drwxr-xr-x 4 root root 4096 11월 1 2005 dev
drwxrwxrwx 4 nobody nobody 4096 11월 22 2005 etc
drwxr-xr-x 2 root root 4096 8월 2 2005 home
drwxr-xr-x 4 root root 4096 8월 2 2005 lib
drwxr-xr-x 8 root root 4096 8월 2 2005 mnt
drwxr-xr-x 2 root root 4096 8월 2 2005 proc
drwxrwxrwx 2 root root 4096 7월 19 2005 root
drwxr-xr-x 2 root root 4096 8월 2 2005 sbin
drwxrwxrwx 2 root root 4096 8월 2 2005 sys
drwxrwxrwx 2 root root 4096 8월 2 2005 tmp
drwxrwxrwx 8 nobody nobody 4096 7월 27 2005 usr
drwxr-xr-x 7 root root 4096 8월 2 2005 var

이 상태에서 그대로 개발 보드로 가서 NFS 부팅 시험을 하게되면 에러가 나게 됩니다.

init 에서 파일에 대한 권한이 없다고 합니다.

그러니 NFS 에서 모든 권한을 쓸 수 있도록 아래와 같이 명령을 해줍니다.

[root@arm26 deroot]# chmod 777 * -R

이제 전체적으로 확인해 봅니다.

지금까지 한 내용은 아래와 같습니다.

개발 서버 : nfs 환경 설정 -> 커널 옵션 수정 -> 램디스크 이미지 생성 -> nfs 부트에 필요한 파일 복사

개발 보드 : 이지부트에서 램디스크 커널 작업을 새로 올림 -> NFS 부트에 대한 IP를 커널의 명령어에 삽입

위와 같은 내용을 수행하였습니다.

8. 최종적으로 개발 보드에서 부팅을 하여 로그인이 제대로 되는지 확인을 합니다.

플래쉬 안의 램디스크 이미지가 아닌 네트워크 상의 서버 환경 내에서 저장된 램디스크를 통해서 부팅을 확인 하였습니다.

태그: *ESP-CX *NFS *Boot *부팅