강좌

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


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

커널을 올려보자

 

 

이제 드디어 강좌의 핵심인 리눅스 커널을 올려볼 시간이 되었다.

SMDK2440보드를 기준으로 하여 타겟에 리눅스 커널을 올리고,

실행해 보기까지의 과정을 중점적으로 살펴보기로 한다.

 

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

 

 

연재 순서

임베디드 리눅스 걸음마

교차 개발 환경을 구축하자

부트로더 설정은 이렇게

커널을 올려보자

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

2% 부족함을 채워보자

 

커널 다운로드

리눅스 커널은 http://kernel.org 사이트에서 버전인 2.6.23.9 기준으로 설명한다.

 

 

# wget ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.23.9.tar.bz2

# tar -xjf linux-2.6.23.9.tar.bz2

# cd linux-2.6.23.9

 

 

빌드 환경 설정

커널을 빌드할 위치는 피시(호스트)인데, 커널을 적재하여 실행할 보드(타겟) SMDK2440 보드이다.

따라서 SMDK2440 보드에 적재하기 위한 이미지를 생성하기 위해 크로스 빌드를 해야 하는데, 이는 Makefile 파일을 수정해 주면 된다.

 

리눅스 top 디렉토리에 있는 Makefile 다음과 같이 수정한다. (185 line)

# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile

#ARCH ?= $(SUBARCH)

#CROSS_COMPILE ?=

ARCH = arm

CROSS_COMPILE = arm-linux-

# Architecture as present in compile.h

..

 

 

ARCH 에는 빌드할 아키텍처의 종류를 명시한다. 디폴트로는 현재 빌드를 수행하는 호스트의 아키텍처가 선택된다. i386 되기 때문에, 크로스 빌드를 위해서는 arm이라고 명시해 줘야 한다.

CROSS_COMPILE 에는 빌드를 수행할 툴체인의 prefix 명시한다. 여기서는 강좌에서 사용하는 툴체인인arm-linux- 세팅하면 된다.

 

다음으로 커널 디렉토리 초기화를 수행한다.

 

# make distclean

 

과정은 커널 빌드시 커널 디렉토리 내에 생성되는 중간 파일(*.o)들과, 그밖에 임시 파일(*.tmp,*.ori, ) 들을 모두 지워, 커널을 처음 다운로드 받았을 때의 파일만을 남겨두고 모두 지우는 역할을한다. , 커널 디렉토리의 초기화 상태로 만들어 주는 것이다.

 

 

다음으로, SMDK2440 용으로 빌드하기 위한 커널 옵션을 설정한다.

 

# make menuconfig

 

 

위와 같은 화면이 나오고, 사용할 타겟에 맞는 옵션을 지정해 주면 된다. 그런데 리눅스 커널은 많은 종류의 아키텍처 디바이스를 지원하기 때문에 설정해 줘야 사항이 많다. 각각의 플랫폼 별로 모든 옵션을 전부 선택하는 것은 쉽지 않은 일이기 때문에, 미리 디폴트로 정의된 설정 파일을 읽어 들이는 기능도 제공한다. ARM 플랫폼의 경우는 arch/arm/configs 디렉토리에 몇몇 타겟에 대한 디폴트 설정 파일이 제공되고, SMDK2440 경우는 s3c2410_defconfig 파일을 사용하면 된다.

 

# cp arch/arm/configs/s3c2410_defconfig .config

# make oldconfig

 

 

해당 디폴트 설정 파일을 .config 파일로 복사하고, make menuconfig 대신에 위와 같이 oldconfig명령을 사용하면 된다.

 

오픈소스로 제공되는 리눅스커널은 상당히 많은 종류의 보드와 디바이스 드라이버를

지원하기 때문에 특정 보드에서 수행되도록 하기 위해서는 약간의 수정 과정이 필요한

경우도 있다.

 

SMDK2440 수정사항

오픈소스로 제공되는 리눅스 커널은 상당히 많은 종류의 보드와 디바이스 드라이버를 지원하기 때문에 특정 보드에서 수행되도록 하기 위해서는 약간의 수정 과정이 필요한 경우도 있다. 여기서는 SMDK2440 보드에서 리눅스 커널을 동작시키기 위해 필요한 수정 사항에 대해 알아본다. 먼저, 2440보드의 번호를 지정하는 코드를 추가한다. 커널이 동작하는데 있어, CPU 보드에 따라 달라지는 부분이 있기 때문에, 커널 부팅 초반에 해당 보드의 CPU 보드의 종류를 세팅하는 루틴이 들어가 있다. 아래와 같은 코드를 추가한다.

 

arch/arm/kernel/head.S (Line 84)

 

.section .text.head, ax

.type stext, %function

ENTRY(stext)

#ifdef CONFIG_CPU_S3C2440

mov r0, #0

mov r1, #(MACH_TYPE_S3C2440 & 0xff)

orr r1, r1, #(MACH_TYPE_S3C2440 & 0xff00)

#endif

msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode

@ and irqs disabled

mrc p15, 0, r9, c0, c0                  @ get processor id

 

 

추가된 루틴은 R1 레지스터에 2440 보드의 고유번호를 세팅하는 코드이다. 이후에 값을 이용하여 2440 커널임을 인식하게 된다. 과정은 원래 부트로더에서 세팅을 해줘야 하는 값인데 강좌에서는 편의상 커널의 코드를 수정하는 방식을 채택하였다.

MACH_TYPE_S3C2440 이라는 매크로가 2440 보드의 고유번호를 나타내는데, 매크로가 정의된

include/asm/mach-types.h 헤더파일도 아래와 같이 추가해준다.

 

arch/arm/kernel/head.S (Line 24)

 

#include <asm/thread_info.h>

#include <asm/system.h>

#include <asm/mach-types.h>

#if (PHYS_OFFSET & 0x001fffff)

 

 

다음으로, LCD Framebuffer MTD 기능을 제거한다. 기능들은 SMDK2440 보드에서사용하기

위해서는 소스 코드의 수정이 필요한 상태이므로 커널을 동작시켜 보는데 초점을 맞추는 강좌에서는 제거하기로 한다.

 

커널 옵션 메뉴에서 디폴트로 선택되어 있는 아래 개의 옵션을 끄면 된다.

Device Drivers

Graphics support

[ ] S3C2410 LCD framebuffer support

Device Drivers

Memory Technology Device (MTD) support

NAND Device Support

[ ] NAND Flash support for S3C2410/S3C2440 SoC

 

 

커널 빌드

다음 명령으로 커널을 빌드하여 실행 이미지를 생성한다.

 

# make zImage

 

에러 없이 제대로 빌드가 되었다면, arch/arm/boot 디렉토리에 zImage 라는 파일이 생성될 것이다. 파일을 타겟에서 사용하게 된다.

 

커널 실행하기

SMDK2440 보드에서 커널을 실행하기 위해서는, 먼저 호스트에 생성된 커널 이미지를 타겟으로 복사하는 과정을 거쳐야 한다. 먼저, 커널에서의 환경 설정을 살펴본다.

 

1. IP 설정

호스트와 타겟간 네트웍 통신을 하기 위해 IP 설정한다. 호스트에는 이미 IP 존재하고 있을 것이지만 (ifconfig 명령으로 확인할 있다.) 여기서는 private IP 이용하여 타겟과의 연결을 한다. 물론, 통신만 이루어 진다면 다른 IP 사용해도 무방하다.

- 호스트 : 192.168.95.1

- 타겟 : 192.168.95.2

설정을 한다. 먼저, 호스트 PC에서는 다음과 같이 설정한다.

 

# ifconfig eth0:1 192.168.95.1

 

 

2. tftp 설정

호스트에 있는 커널 이미지를 타겟으로 전송하기 위한 프로토콜로서 tftp 사용한다.

호스트에 tftp 설치되어 있다고 가정한 상태에서 진행하기로 한다. 만일 설치가 안되어 있다면 우분투의 경우 apt-get 명령을 이용하여 설치하면 된다.

 

설치가 되어 있다면 tftp 활성화 상태를 확인해 본다. /etc/xinetd.d/tftp

 

# vi /etc/xinetd.d/tftp

service tftp

{

socket_type = dgram

protocol = udp

wait = yes

user = root

server = /usr/sbin/in.tftpd

server_args = -s /tftpboot

disable = no

per_source = 11

cps = 100 2

flags = IPv4

}

 

위와 같이 /etc/xinetd.d/tftp 파일을 열어 disable 항목이 no 세팅되어있는지 확인해 본다. 만약 yes 되어 있다면 no 수정해 준다. 다음으로 tftp 서비스를 포함하고 있는 xinet 데몬을 활성화한다.

 

# /etc/init.d/xinetd start

 

 

3. 타겟 환경 설정

부트로더에서의 설정을 살펴보겠다. U-Boot에서는 환경 변수를 설정하는 방식으로 환경 설정을 하게된다. 지난호에서 설정한 부트로더가 적재된 타겟의 전원을 켜면 부트로더 프롬프트가 나오게 되고 이때, printenv 명령을 실행해 본다.

 

printenv 명령으로 화면과 같이 설정된 환경 변수를 볼 있다. 여기에서 setenv 명령어를 이용해 다음 항목을 세팅하면 된다.

 

# setenv ipaddr 192.168.95.2

# setenv serverip 192.168.95.1

# setenv gatewayip 192.168.95.1

# setenv netmask 255.255.255.0

# setenv ethaddr 11:22:33:44:55:66:77

# saveenv

 

 

위와 같이 네트웍 정보를 세팅하고, 마지막으로 saveenv 명령으로 저장을 하면 네트웍 설정이 완료되고, tftp 이용하여 다운로드를 받을 있게 된다. 먼저, 호스트의 리눅스 이미지를 준비한다. 리눅스디렉토리의 arch/arm/boot 디렉토리에 생성된 zImage 파일을 /tftpboot 디렉토리로 복사한다. Tftp프로그램은 /tftpboot 디렉토리에 있는 파일을 다운로드 있다.

 

(HOST) # cp arch/arm/boot/zImage /tftpboot

 

이후, 타겟에서는 tftp 명령으로 다운로드 받으면 된다.

 

(TARGET) # tftp 30008000 zImage

 

명령은 호스트의 /tftpboot 디렉토리에 있는 zImage파일을 타겟의 30008000 번지에 저장하라는 명령이다.

 

 

다운로드가 정상적으로 완료되었다면, go 명령어를 통해 커널을 실행하면 된다.

 

# go 30008000

 

 

zImage 파일을 다운로드 받은 번지를 실행하면 리눅스 커널이 수행되고, 아래와 같은 결과가 나타난다. 아직 모든 준비가 끝난 것이 아니기 때문에 메시지가 출력되다가 마지막에 correct root=’… 이라고 출력된 커널이 멈추게 된다. RFS (Root File System)

아직 없기 때문에 발생하는 문제이다. 다음호 에서 RFS 대해 다루게 되면 비로소 타겟에서 리눅스 부팅이 완료되어 커널 프롬프트가 뜨는 것을 확인할 있을 것이다

 

 

 

출처 : 공개 SW 리포트 10호 페이지 54 ~ 59 발췌(2007 12) - 한국소프트웨어 진흥원 공개SW사업팀 발간

 


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


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

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