'KERNEL'에 해당되는 글 1건
EZ_X5용 리눅스 2.6 커널 포팅 :: 2008/01/03 21:18 by 김형식(17기)
안녕하세요. 쓸데없이 캐바쁜 김형식입니다. 이번에 YAFFS 파일 시스템의 개조 중 압축 부분을 담당하고 있는데, 구현 및 테스트를 EZ-X5 보드에 하는 과정이 포함되어 있어, 먼저 EZ-X5에 Linux kernel 2.6부터 올리는 과정을 진행했습니다. 사실 2.4 커널에서 해도 되긴한데, 솔직히 2.4 커널을 올려서 하는 것은 윈도 98에서 디바이스 드라이버 개발하겠다 하는것과 비슷한 것이라 2.6에서 해보려고 합니다. 참고로 리눅스 커널은 2.6.23.9가 최신 버전이며, 2.4 대와 다르게 2.6에서는 버전이 하나 올라갈때마다 갈아엎는구나 라는 표현이 맞을정도로 빠르게 변하고 있습니다. 뭐 서론은 이정도로 하구요;
이미 falinux에 2.6.11 버전을 기준으로 커널이 올라와있으나, 실제로 컴파일이 제대로 되지 않고 정리가 안되어있는 면이 많아서 어쩔수없이 맨땅에 헤딩을 했습니다. 다행히도, social724님이 올리신 hwp 문서에 어느정도 정확한 가이드가 올라와있어서 이것을 기준으로 진행하였습니다. 원본은 여기서 얻으실 수 있습니다.
1> 개발환경 설정
작업은 공포의 빡돌아 리눅스인 fedora 6에서 진행했습니다. 물론 fedora 8에서 하셔도 문제는 없더군요.
1. 먼저 kernel.org에 가서 깨끗한 바닐라 커널 소스를 받습니다.
http://www.kernel.org/pub/linux/kernel/v2.6/ 에 가셔서 2.6.16.55를 받으시면 됩니다.
사실 최신 버전인 2.6.23.9로 진행해봤는데 몇가지 문제가 있어서 진행을 하지 못했습니다. 이 부분에 대해서는 일단 생략을 하겠습니다.
2. 이놈을 특정 디렉토리에 풀어주어야하죠.
저는 /development 라는 디렉토리에 풀어내고, 그담에 linux라고 이름을 바꿨습니다. 즉, /development/linux/ 안에 리눅스 커널 소스가 들어있는겁니다.
3. falinux에 가셔서 toolchain과 ramdisk를 받습니다.
이 글을 쓰는 시점에 falinux.com에 접속하니 사이트가 죽어서 페도라 2용으로 나온 arm-linux-* toolchain과 ramdisk를 받으시면 됩니다.
뭐 설치 방법은 그 사이트에 적힌대로 하라는대로 하면 됩니다. 이 부분은 좀 더 설명을 보강하겠습니다.
4. ezboot를 설정합니다.
사실 이건 그닥 순서와 관계가 없습니다만, 다음과 같은 내용이 되도록 각 항목을 먼저 설정하셔야합니다.
- 램디스크 비율을 수정해야합니다. 이 부분을 몰라서 캐삽질을 했는데;
F. NAND-Partition MByte [1:5:58] (kernel:ramdisk:app) 을 2:5:57 로 설정하시고 해 보세요..
설정후 다음과 같이 하세요.
EZBOOT> nek
EZBOOT> ner
EZBOOT> nea
NAND의 영역을 지웠으면... 커널과 램디스클 다운로드 하시면 됩니다.
현재 커널의 용량이 1312392 bytes 입니다. 따라서 기존의 1Mbyte 용량을 초과해서 발생하는 에러입니다.
라고 찾아보니 나왔습니다. 정말 그런것 같습니다;
- Machine Architecture Number를 785로 수정해줍니다.
2> 커널 소스 수정
1. Machine Architecture Number을 확인해봅니다.
사실 특별히 확인을 하지 않아도, EZ-X5는 785로 등록이 되어있습니다. 보드를 새로 만들었다면, 우선 개발하고자 하는 보드에 대한 machine architecture 번호를 설정해주어야 하는 데
실제로는 타겟 머신을 등록하는 ARM 리눅스 개발자 사이트에서 설정을 해주어야 하는거라고 하네요.
참고로 해당 ARM 리눅스 개발자 사이트는 아래와 같습니당.
http://www.arm.linux.or.uk/developer/machines
2. /development/linux/Makefile을 수정합니다.
이 후 Makefile을
열어서 ARCH 와 CROSS_COMPILE에 값을 할당합니다.
line 175 ARCH ?= arm
line 176
CROSS_COMPILE ?= arm-linux-
이는 해당
architecture는 우리가 사용하고자 하는 SoC의 코어가 arm 계열임을 나타내고
사용할 크로스 컴파일러는
arm-linux-gcc, arm-linux-ld 등과 같이 prefix로 arm-linux-가
설정되어 컴파일 됨을 의미한다고 합니다.
3. make
lubbock_defconfig을 진행합니다.
lubbock 보드는 인텔에서 만든 테스트용 개발 보드로 arch/arm/config 폴더에 lubbock_defconfig 라는 default 설정파일이 있는데 이를 이용해 보드에 맞는 설정을 하게 됩니다. 이는 lubbock의 기본 설정파일을 이용해 더욱 쉽게 커널의 설정파일을 만들기 위해서 사용된다고 보시면 됩니다. 정상적으로 컴파일이 완료되면 arch/arm/boot/zImage 파일이 생성되게 되는데 이 파일이 보드에 올라갈 커널의 이미지 파일이 되는겁니다. 한가지 중요한 점은 일단 여기까지 해보고 꼭 컴파일해서 문제가 없는지 체크를 해보시는 것이 중요합니다. 2.6.17.14 버전을 받아서 여기까지 진행하면 특별히 설정을 변경하지 않아도 zImage가 나오지 않더군요. (링커 에러 발생) 그래서 어쩔수없이 한단계 낮춘 2.6.16.55로 진행을 하게 되었습니다.
4. 새로운 보드에 해당하는
machine 구조체를 정의하기 위한 파일을 생성합니다.
ez_x5 보드의 경우 PXA255
CPU를 사용하므로 /arch/arm/mach-pxa/ 디렉토리에서 machine_desc 구조체를 설정할 새로운 소스 파일을 만듭니다. 여기서는 ez_x5.c와 ez_x5.h라는 파일을 만들어 사용하도록 합니다. 파일은 이미 제가 서버에 올려놓았으니, 이 부분을 복사해서 가져다가 쓰시면 됩니다. 참고로 커널 2.6.23에서부터는 pxa_init_irq()가 pxa25x_init_irq()로 바뀌었습니다.
5. arch/arm/mach-pxa의 Kconfig와 Makefile 수정합니다.
7번에서 제작한 파일을 실제로 커널에 포함시키려면
arch/arm/mach-pxa/ 폴더에 Kconfing와 Makefile을 수정해야 합니다.수정하시다보면 감을 잡으시겠지만 Kconfig 파일은 make menuconfig를 진행해서 커널 컴파일을 할때 나타나는 메뉴의 내용이라고 보시면 되겠습니다.
- Kconfig 수정
lubbock 항목 뒤에 다음과 같은 항목을 추가합니다.
config ARCH_EZ_X5
bool "EZ_X5
Development Platform"
select PXA25x
- Makefile 수정
lubbock 항목 뒤에 역시 추가합니다.
obj-$(CONFIG_MACH_EZ_X5) +=ez_x5.o
위의 Kconfig 파일과 Makefile에 대해 살펴보면 우선 make meunconfig의 System Type에서 EZ_X5 Development Platform을 선택하면 CONFIG_MACH_EZ_X5 가 include/linux/autoconf.h 파일에 1로 설정이 되어 make 수행 시 Makefile의 해당 라인에 의해 ez_x5.o에 해당하는 object 파일이 만들어진다고 social428님이 설명을 이미 해두셨네요.
6. include/asm-arm/arch-pxa/uncomressed.h 파일을 수정합니다.
위에서 default로 사용된 lubbock 보드는 FFUART를 사용해서 serial 통신을 하는 반면 ez-x5보드는 STUART를 이용해서 serial 통신을 하기 때문에 serial 통신을 위해서
include/asm-arm/arch-pxa/uncomressed.h
파일에서
#define
UART FFUART 부분을 #define UART STUART로 수정합니다.
7. make menuconfig를 수정합니다.
- System Type 중 ARM System type(PXA2xx-based)을 확인하여, 만약 다른 값으로 설정이 되어 있다면 값을 PXA2xx-based로 설정합니다.
- Intel PXA2XX
implementations 에서 Select Target Board에서 EZ-X5
Development Platform을 선택합니다.
- Boot option에서 Default
Command String에 console=ttyS2,115200으로 설정을 합니다.
- 그리고 social724님이 적은 문서에는 없지만 PCCARD(PCMCIA) 부분은 해제를 해주셔야합니다. 이부분에서 가끔 에러가 날 때가 있더군요.
- 뭐 불필요한 설정들을 모두 해제하고 make menuconfig를 종료합니다.
8. 커널 이미지를 테스트해봅니다.
- make 명령을 수행하고
arch/arm/boot/zImage를 /tftpboot/zImage.x5로 복사합니다.
- ez 부트로더를 이용해 해당 파일을 ez-x5로 이동시킵니다 (tfk 명령을 사용합니다.)
- 자세한 내용은 ezboot 사용법을 참조하세요. 물론 minicom을 미리 띄우셨으리라 생각합니다.
- 보드를 리셋해서 제대로 부팅되는지 확인해봅니다.
(rst 명령을 사용하면 소프트웨어 리셋이 가능합니다.)
- 커널이 로드되면서
uncompressed linux....... 다음에 boot the linux 어쩌구 저쩌구 메시지가 뜨지 않고 그냥 화면이 멈췄다면
- 6번 과정에서
include/asm-arm/arch-pxa/uncompressed.h파일이 정확히 수정되었는지 확인해봅니다.
- 만약 uncompressed linux.... 메시지가 뜬 후 화면에
아무 메시지가 뜨지 않은 경우 1번 과정에서 machine 관련 값들이 정확하게 설정되었는지 확인해봅니다.
- 화면에 커널 메시지가 뜨고 램디스크를 찾을수 없다면서 커널 패닉이 나면 정상적으로 커널이 올라간겁니다.
9. arch/arm/kernel/setup.c 파일을 수정합니다.
이제 부트로더에서 넘어온
cmd 값들이 커널이 실행되는 과정에서 적용될 수 있도록 arch/arm/kernel/setup.c 파일을 수정하는 과정을 진행하겠습니다. ez 보드의 경우, ezboot를 그대로 이용하기 때문에 ez-board에서 저장한 nand의
주소에서 값을 읽어와서 설정하는 방법으로 cmd 값들을 할당하게 된다고 합니다.아쉽게도 social724님이 올리신 문서에서 이 부분은 오류가 상당히 있는 편입니다. 그래서 해결방법을 몰라서 헤매다가, 마이크로소프트웨어 지난호 부분에 ezboot에 관한 내용이 있어 그 부분을 보고 수정하였습니다.
수정된 부분은 다음과 같습니다. 원래 문서에서는 line 786에 저장되어 있는 nand 메모리 주소에서 해당 cmd를 읽어 와서 char* from에 할당 하는 루틴을 추가한다고 적혀있습니다.
{
TBootLoaderParam *ptrEzParm = (TBootLoaderParam)0xC0000000;
if( ptrEzParam->MagicNumber == 0x20030702)
{
if(!strcmp(ptrEzParam->MagicStr, "CMD= "))
{
strcat(from, " ");
strcat(from, ptrEzParam->CommandLine);
}
}
}
#endif
주소값이 틀려있으니 위와 같이 수정만 하시면 별탈없이 부트로더에서 커맨드를 받아와서 성공적으로 부팅을 하게 됩니다.
10. 램디스크를 설정합니다.
개발환경 에서 언급한 램디스크를 그대로 사용해도 됩니다.
이 부분은 원래의 문서 내용에 틀린 부분이 없으므로 그대로 사용해도 됩니다. 다만 이 부분은 필수가 아니고 직접 NAND에서 부팅을 해도 된다는 사실을 미리 적습니다.
make menuconfig 실행
Device Driver -->
Block Device Driver -->
RAM Disk Support 설정
Loopback Device support 설정
Default Number of RAM disks 값을 1로 설정
Default Ramdisk Size 12288 로 설정 (12M의 램디스크를 사용하기 위해서)
Initial RAM file system and RAM disk(initramfs/initrd) support 설정
저장을 하고 make를 실행합니다.이미 RAM 파일 시스템이 만들어져 부트로더에 의해 해당 주소에 12M 크기의 RAM 디스크의 압축파일 (ramdisk-12M.gz)이 있다면 커널은 아래와 같은 메시지를 출력하게 됩니다.
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 filesystem) readonly
11. C8900 설정
이 부분은 저희 프로젝트에 필수가 아닙니다. 이 부분은 스킵합니다. 제가 삽질을 해본 결과, 해당문서 부분은 2.6.23 커널에 대해서 동작을 하지 않습니다. 똑같이 해도 안되니, 아마 2.6.23에서 바뀐 부분이 있는것 같은데 어느 부분인지 정확히 모르겠더군요.혹시 성공하시면 저한테 알려주시면 정말 감사하겠습니다.
yaff 파일 시스템을 사용하기 위해 MTD 디바이스 드라이버를 설정해야합니다. 이 부분은 2.6.23에서 보면 인터페이스가 크게 바뀌고 있는 곳이라 기존 것을 공부하시면 도루묵이 됩니다(?!)
이부분을 갈아엎으려고 한참 삽질을 했는데, 뭐랄까 정말 어렵습니다 ㅡㅠ; 일단 간단하게 FALINUX에서 올린 2.6.11 커널 버전의 MTD 중 NAND 디렉토리를 그대로 복사해서 쓰는 것으로 하겠습니다.
좀 더 적어보자면, EZ-X5 보드 방식의 NAND 연결방식은 일종의 구식이 되었습니다. 어떻게 하면 제대로 연결하는지 정확히 모르겠는데, 일단 ez_x5.c 파일 부분에 대해서 필요한 부분이 정확히 기록되어있지 않으므로 2.6.23으로 하면 NAND 자체가 인식이 되지 않습니다; 드라이버 파일을 새로운 인터페이스에 맞게 만들던가 혹은 보드 자체를 다시 만들어야할것 같더군요.
이 후 drivers/mtd/nand/Kconfig 파일과 Makefile을 수정해 make menuconfig에서 이 파일을 설정할 수 있도록 해줘야합니다.
13. yaffs 파일시스템 소스를 패치합니다
yaffs의 소스를 CVS를 통해 받아옵니다. 다음의 링크에 자세하게 나와있습니다.
http://www.yaffs.net/node/346
여기서 yaffs2와 yaffs가 있는데, 저희는 yaffs를 사용하므로 다음과 같이 긁어옵니다.
cvs checkout yaffs
이 소스를 그대로 활용을 할 수가 없습니다. 뭐랄까 많은 부분이 빠져있는데, 다음과 같은 설정이 필요합니다.
일단 이러한 수정이 필요한 이유는 yaffs 1번째 버전은 2.4 기준으로 작성이 시작되서 2.5 커널까지 개발이 되었고, 그리고 yaffs2가 2.6 커널에 맞게 작성이 되서 그렇습니다.
즉, 완전히 다른 파일 시스템이 아니고 yaffs를 최적화시키고 2048byte용 NAND에도 동작할 수 있게 만든 파일시스템이 yaffs2이므로
yaffs에 버그가 있으면 yaffs2를 참조하시면 매우 정신적으로(?) 유익합니다.
1) 일단 yaffs_mtdif.c 파일을 yaffs2 repository에서 받아와서 겹쳐쓰는 과정이 필요합니다.
2) 그리고 커널 버전이 2.6.18이 넘어가는 경우, inode structure가 바뀌어서 해당 부분의 수정이 필요한데,
이러한 부분은 yaffs2에서 어떻게 바뀌었는지 참조를 하면서 진행하면 됩니다.
잠깐 인용을 해보면 yaffs2에서는 다음과 같이 버전에 따라서 구분을 해둔 것을 볼 수 있습니다.
....
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
#define yaffs_InodeToObjectLV(iptr) (iptr)->i_private3) 그리고 yaffs2의 경우, 단순히 patch-ker.sh 파일을 실행시키면 되나, yaffs의 경우 그게 제대로 안되는것 같습니다.
#else
#define yaffs_InodeToObjectLV(iptr) (iptr)->u.generic_ip
#endif
#define yaffs_InodeToObject(iptr) ((yaffs_Object *)(yaffs_InodeToObjectLV(iptr)))
#define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode)
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
#define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->s_fs_info)
#else
#define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp)
#endif
....
그래서 일단 수동으로 복사하고 KConfig 파일과 Makefile이 제대로 되었는지 점검해줄 필요가 있습니다.
4) 그리고 patch-ker.sh 스크립트는 직접 "커널소스 디렉토리/fs/yaffs"로 복사를 하는 것이 아니고 링크를 걸고 있으나 이게 꼬일때가 있더군요.
귀찮으신 부분은 직접 복사를 해주셔도 되겠습니다. 이러한 부분을 모두 반영해서 이 문서의 마지막 부분에 반영한 부분의 소스가 링크 되어있으니 궁금하신 분은 보시면 되겠습니다.
후기.
- 가끔 yaffs에서 파일 삭제가 안되는 경우가 있는데, yaffs 자체의 문제같습니다.
다시 한번 지우면 잘 지워지는것 같고, 파일시스템을 꽉 채우고 봐도 그런걸로 보니 뭔가 2.6 커널에 안맞는것 같은데, 이 부분은 찾아보고 다시 올려보겠습니다.
- 또다른 포팅기 문서도 있습니다. 다 하고 나서 찾아버렸는데, 상당히 허무하더군요 ㅡㅠ
