EZ-X5 보드에 커널 2.6 을 포팅하는 방법을 기술한다. 여기서 설명하는 방법은 다음의 사이트를 참고로 했다.

디바이스 하나씩 하나씩을 포팅해가면서 수정포인트에 대한 의미를 알게될 것이다.
지금까지의 포팅의 의미가 따라하기 수준에 머물렀다면, 이제부터는 직접 새로운 길을 만들어가는 것이라 보면 된다.

준비운동하기

부트로더는 Falinux 에서 기본적으로 제공하는 EZBOOT V2.2.49 를 사용할 것이다. 여유가 된다면, U-Boot 포팅도 해보고 싶다.
참고로 보드에 EZBOOT 를 설치하는 방법은 http://forum.falinux.com/zbxe/?document_srl=483998 을 참고하기 바란다.

여기서 사용할 커널은 2.6.28.4 이다. 커널을 받고 압축을 푼다.

#tar xzf linux-2.6.28.4.tar.gz -C /opt

커널이미지를 보드로 다운로드하기 위해 tftp 서버가 구축되어야 한다.

#apt-get install tftpd

별다른 설정없이 이후 부팅시, inetd 데몬에 의해 자동으로 실행된다. 기준디렉토리는 /srv/tftp 이다. 커널이미지를 이곳에 복사하면 보드에서 다운로드가 가능하다.
이쯤해서 포팅 환경을 설명해야 겠다.

H/W IBM X40
OS Debian 6.0.6
컴파일러 gcc-4.4.5, arm-linux-gcc-3.4.3
네트워크설정 HOST PC(=1.1.1.1), Target Board(=1.1.1.2)

타겟보드의 경우, 이지부트 메뉴에서 IP 주소를 변경할 수 있다.
크로스 컴파일러는 http://forum.falinux.com/_zdownload/toolchain/arm-toolchain-3.4.3.tar.gz 에서 다운로드 받았다. 설치방법은 아래와 같다.

#tar xzf arm-toolchain-3.4.3.tar.gz -C /

참고로 말하면 여기서 소개한 포팅 환경을 가급적 맞추는 것이 좋다. 특히 커널과 크로스 컴파일러의 궁합은 무엇보다도 중요하기 때문에 똑같이 빌드하고 보드에 올렸다 하더라도 원하는 결과를 얻지 못할 수도 있다.
최신버전이 무조건 좋다는 선입견은 최소한 임베디드 분야에서는 통하지 않는다고 생각한다.

커널 포팅하기(1부)

가장 먼저해야할 일은 크로스컴파일러를 지정해주는 것이다. 아래와 같이 Makefile 파일을 수정한다.

#cd /opt/linux-2.6.28.4
#vi Makefile
...
export KBUILD_BUILDHOST := $(SUBARCH)
ARCH        ?= arm                                       // arm 으로 수정
CROSS_COMPILE   ?= arm-linux-                 // arm-linux- 로 수정
 
# Architecture as present in compile.h
...

이제 앞서 설치한 크로스컴파일러로 커널 빌드가 될 것이다.

요즘 커널은 지원하는 칩마다 kernel configuration 파일 제공한다. 예전에는 칩을 포팅하기 위해 여러가지 패치를 했던 것을 생각하면 참으로 편해진 것이다.
X5 보드는 Xscale255(PXA255) 이기 때문에 이에 대한 설정파일을 찾아야 한다. arch/arm/configs 아래에 가면 커널에서 기본적으로 지원하는 ARM 계열 칩들의 configuration 파일들이 있다. PXA255 칩을 위한 설정 파일들이 몇개 있는데, 이중에 lubbock_defconfig 파일을 사용한다.

#make lubbock_defconfig

위 명령어를 실행하면 kernel config 옵션들이 설정되어 .config 파일이 만들어진다.
이대로 커널 컴파일을 빌드해서 보드에 올려보자.

#make zImage
#cp arch/arm/boot/zImage /srv/tftp/

부팅도중에 아래 그림과 같이 멈춰버렸다.

Copy Kernel Image .....
Copy Ramdisk Image .....
Starting kernel [MARCH 3002]...
kernel command [EZBOOT mem=64M initrd=0xA0800000,5M root=/dev/ram ramdisk=16384 console=ttyPXA2,115200    ip0=1.1.1.2 mac=00:FA:07:78:65:05 netmask=255.255.255.0 gw=192.]

뭔가 잘못되었다. 추가로 수정이 필요하다.

arch/arm/mach-pxa/include/mach/uncompress.h 파일 수정해야 한다.

static inline void arch_decomp_setup(void)
{
//  if (machine_is_littleton())
        UART = STUART;
}

이제 다시 빌드해서 올려보자.

Copy Kernel Image .....
Copy Ramdisk Image .....
Starting kernel [MARCH 3002]...
kernel command [EZBOOT mem=64M initrd=0xA0800000,5M root=/dev/ram ramdisk=16384 console=ttyPXA2,115200    ip0=1.1.1.2 mac=00:FA:07:78:65:05 netmask=255.255.255.0 gw=192.]
Uncompressing Linux...................................................................................... done, booting the kernel.

전보다 한줄이 더 찍혔다.

부트로더에서 커널에 넘겨주는 부트 파라메터를 수정해야 한다. 이지부트에서 set 을 실행하면, 18번 항목 값이 아래와 같다.

...
18) KCMD 3 : console=ttyPXA2,115200
...

console 지정이 잘못되었다. 아래와 같이 수정한다.

18) KCMD 3 : console=ttyS2,115200

이번에는 커널쪽 코드(arch/arm/mach-pxa/lubbock.c)를 수정해야 한다.

MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
    /* Maintainer: MontaVista Software Inc. */
    .phys_io    = 0x40000000,
    .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
    .boot_params    = 0xa0000100,              // 추가
    .map_io     = lubbock_map_io,
    .init_irq   = lubbock_init_irq,
    .timer      = &pxa_timer,
    .init_machine   = lubbock_init,
MACHINE_END

정상 적으로 부팅이 진행되도록 하기 위해서는 머신 아키텍쳐 번호를 알아야 한다.
arch/arm/tools/mach-types 파일을 보면, 커널에서 지원하는 아키텍쳐들에 대한 숫자가 정의되어 있다. 우리가 사용한 lubbock 는 89 번이다.

lubbock         ARCH_LUBBOCK        LUBBOCK         89

이것을 이지부트 설정에 적용한다. 메뉴에서 간단하게 변경할 수 있다.

13) arm kernel arch number : 89

부팅 도중 멈추는 것은 config 파일에는 켜져있는 디바이스가 실제 타겟보드에는 없는 경우가 많기 때문에 발생한다.

Kernel Features  --->
           [ ] Timer and CPU usage LEDs
 
Device Drivers  --->
           Graphics support  --->
            < > Support for frame buffer devices  --->

위의 옵션들이 지정되어 있다면, 모두 해제한다.

지금까지의 수정사항을 반영하고 빌드후 부팅을 확인해보자.

...
console [ttyS2] enabled
pxa2xx-uart.3: ttyS3 at MMIO 0x41600000 (irq = 7) is a HWUART
smc91x: not found (-19).
pxa25x_udc: version 30-June-2007
Bad mode in data abort handler detected
Internal error: Oops - bad mode: 0 [#1]
Modules linked in:
CPU: 0    Not tainted  (2.6.28.4 #8)
PC is at 0xffff000c
LR is at 0xc029c42c
pc : [<ffff000c>]    lr : [<c029c42c>]    psr: 80000097
sp : c3e1dc68  ip : f00000d0  fp : c3e1dcbc
r10: 00000000  r9 : c0200898  r8 : c028a118
r7 : 000000c6  r6 : c3e12ba0  r5 : 80000013  r4 : c028a100
r3 : f00000c0  r2 : 00010001  r1 : 00000040  r0 : 00000006
Flags: Nzcv  IRQs off  FIQs on  Mode ABT_32  ISA ARM  Segment kernel
Control: 0000397f  Table: a0004000  DAC: 00000017
Process swapper (pid: 1, stack limit = 0xc3e1c260)
Stack: (0xc3e1dc68 to 0xc3e1e000)
dc60:                   00000006 00000040 00010001 f00000c0 c028a100 80000013 
dc80: c3e12ba0 000000c6 c028a118 c0200898 00000000 c3e1dcbc f00000d0 c3e1dc68 
dca0: c029c42c ffff000c 80000097 ffffffff c3e1dcd0 c3e1dcc0 c005a298 c00285ac 
dcc0: c028a100 c3e1dce0 c3e1dcd4 c005a2f4 c005a270 c3e1dd08 c3e1dce4 c0059520 
dce0: c005a2cc c3e12ba0 000000c6 00000000 c028a100 c01615b0 00000060 c3e1dd34 
dd00: c3e1dd0c c0059804 c0059418 00000000 c029518c 0000015c c02842f4 0000000b 
dd20: 00000000 00000000 c3e1dd5c c3e1dd38 c0014998 c005975c c029518c c02842fc 
dd40: 00000000 c029515c c029515c c02aa898 c3e1dd6c c3e1dd60 c0143aec c00147ac 
dd60: c3e1dd90 c3e1dd70 c014265c c0143ad8 c02842fc c029515c c02843a8 c029515c 
dd80: c3ef4060 c3e1ddac c3e1dd94 c01427e8 c014258c 00000000 c3e1ddb0 c0142784 
dda0: c3e1ddd4 c3e1ddb0 c0141554 c0142790 c3e035b8 c0284344 00000000 c029515c 
ddc0: c3e1c000 c0291b70 c3e1dde4 c3e1ddd8 c0142828 c014150c c3e1de14 c3e1dde8 
dde0: c0141ca0 c0142814 c0244a40 c001a068 c029515c c3e1c000 c0014a80 c029bc04 
de00: 00000000 00000000 c3e1de34 c3e1de18 c0142cb0 c0141c00 c001a068 c029513c 
de20: c3e1c000 c0014a80 c3e1de44 c3e1de38 c0143c0c c0142c24 c3e1de5c c3e1de48 
de40: c0143c58 c0143ba0 c001a068 c001a0cc c3e1de6c c3e1de60 c0014aa8 c0143c4c 
de60: c3e1dfd8 c3e1de70 c001e2ec c0014a8c c029b580 c029ba84 000012d0 c029ba80 
de80: 00000000 c3e1a000 00000000 0000000d c3e1def0 c3e1dea0 c006212c c0061318 
dea0: 00000000 00000044 000212d0 00000000 00000000 c3e1deec ffffffff 00000000 
dec0: 00000000 c3e1defc ffffffff 00000000 00000000 00000000 c3e36420 00000000 
dee0: c02a51f8 c3e03480 00000000 c3e1df40 c3e1defc c0115280 c007decc c3e16000 
df00: 00000000 000000d0 c02a3ddc 00000000 c3e1df38 c3e1df20 c3e37380 c3e37380 
df20: c3e36420 c02a3ddc 00000000 00000000 00000000 c3e1df50 c3e1df44 c01152a8 
df40: c01150f0 c3e1df78 c3e1df54 c00bb6ac c011529c c028a100 00000000 c3e37380 
df60: c3e1df94 000000c6 c02a3ddc c3e1df90 c3e1df7c c00bba00 c00bb680 c3e36420 
df80: c028a100 c3e1dfbc c3e1df94 c005afa4 c00bb990 00383931 00000000 c0010000 
dfa0: 00000106 c028b000 c028b03c 00000000 c3e1dfd8 c001a068 c001a0cc 00000000 
dfc0: 00000000 00000000 00000000 c3e1dff4 c3e1dfdc c0008b7c c001e29c 00000001 
dfe0: 00000000 00000000 00000000 c3e1dff8 c0038414 c0008b00 00053020 00053020 
Backtrace: 
[<c00285a0>] (lubbock_unmask_irq+0x0/0x50) from [<c005a298>] (default_enable+0x34/0x4c)
[<c005a264>] (default_enable+0x0/0x4c) from [<c005a2f4>] (default_startup+0x34/0x44)
 r4:c028a100
[<c005a2c0>] (default_startup+0x0/0x44) from [<c0059520>] (__setup_irq+0x114/0x1d0)
[<c005940c>] (__setup_irq+0x0/0x1d0) from [<c0059804>] (request_irq+0xb4/0xd4)
[<c0059750>] (request_irq+0x0/0xd4) from [<c0014998>] (pxa25x_udc_probe+0x1f8/0x2e0)
[<c00147a0>] (pxa25x_udc_probe+0x0/0x2e0) from [<c0143aec>] (platform_drv_probe+0x20/0x24)
 r8:c02aa898 r7:c029515c r6:c029515c r5:00000000 r4:c02842fc
[<c0143acc>] (platform_drv_probe+0x0/0x24) from [<c014265c>] (driver_probe_device+0xdc/0x17c)
[<c0142580>] (driver_probe_device+0x0/0x17c) from [<c01427e8>] (__driver_attach+0x64/0x84)
 r8:c3ef4060 r7:c029515c r6:c02843a8 r5:c029515c r4:c02842fc
[<c0142784>] (__driver_attach+0x0/0x84) from [<c0141554>] (bus_for_each_dev+0x54/0x88)
 r6:c0142784 r5:c3e1ddb0 r4:00000000
[<c0141500>] (bus_for_each_dev+0x0/0x88) from [<c0142828>] (driver_attach+0x20/0x28)
 r7:c0291b70 r6:c3e1c000 r5:c029515c r4:00000000
[<c0142808>] (driver_attach+0x0/0x28) from [<c0141ca0>] (bus_add_driver+0xac/0x228)
[<c0141bf4>] (bus_add_driver+0x0/0x228) from [<c0142cb0>] (driver_register+0x98/0x114)
[<c0142c18>] (driver_register+0x0/0x114) from [<c0143c0c>] (platform_driver_register+0x78/0x94)
 r7:c0014a80 r6:c3e1c000 r5:c029513c r4:c001a068
[<c0143b94>] (platform_driver_register+0x0/0x94) from [<c0143c58>] (platform_driver_probe+0x18/0x68)
[<c0143c40>] (platform_driver_probe+0x0/0x68) from [<c0014aa8>] (udc_init+0x28/0x40)
 r5:c001a0cc r4:c001a068
[<c0014a80>] (udc_init+0x0/0x40) from [<c001e2ec>] (__exception_text_end+0x5c/0x17c)
[<c001e290>] (__exception_text_end+0x0/0x17c) from [<c0008b7c>] (kernel_init+0x88/0xe8)
[<c0008af4>] (kernel_init+0x0/0xe8) from [<c0038414>] (do_exit+0x0/0x6a8)
 r5:00000000 r4:00000000
Code: bad PC value.
---[ end trace 35e990c1e637c887 ]---
Kernel panic - not syncing: Attempted to kill init!

드디어 부팅 메세지가 뿌려졌다. 하지만 도중 커널 패닉이 발생했다. 트레이스 정보를 보면, 플랫폼 초기화 루틴을 실행하다가 발생한 것 같다.
지금까지 작업이 PXA255 라는 SOC 자체와 UART 까지의 포팅이었다면, 지금부터 해야 할 작업은 SOC 와 인터페이싱하는 다른 디바이스들을 포팅하는 것이다.

커널 포팅하기(2부)

1부 작업의 시작은 기존의 lubbock 이라는 PXA255 기반의 타겟보드의 설정을 토대로 진행했었다. SOC 자체초기화와 UART 초기화까지는 성공했지만, 이후 초기화 과정에서 커널 패닉이 발생했었다.
그이유는 이렇다. lubbock 보드가 실제 타겟인 x5 보드와 다른 것이다. SOC 만 같을 뿐, 이더넷 칩 이라던가 메모리 사이즈, 맵 등이 모두 다르기 때문이다.
만일 lubbock 보드를 가지고 포팅했더라면, 지금까지의 수정만으로도 원하는 결과를 얻을 수 있었다.

서두가 너무 길었는데, 2부에서는 1부와는 달리 lubbock 보드의 코드를 사용하지 않고, x5 보드의 코드를 따로 작성하여 커널 빌드시, 해당 파일이 컴파일되도록 할 것이다.

별도의 코드를 작성할 것이기 때문에 포팅할 실제 보드를 커널에 추가해야 한다.
arch/arm/tools/mach-types 파일에 다음을 추가한다.

wj_board        MACH_WJ_X5      WJ_X5           1912           // 차후에 부트로더에도 같은 숫자로 세팅해야 한다

이제 초기화 시에 실행될 파일(arch/arm/mach-pxa/wj_x5.c)을 작성한다.

#include <linux/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/fb.h>
#include <linux/platform_device.h>
 
 
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
 
#include <mach/hardware.h>
#include <asm/irq.h>
 
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
 
#include <mach/pxa-regs.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/pxa2xx-gpio.h>
 
 
#include "generic.h"
 
 
static void __init ez_x5_init_irq(void)
{
    pxa25x_init_irq();
    set_irq_type(IRQ_GPIO(21), IRQ_TYPE_EDGE_RISING); // CS8900A
    set_irq_type(IRQ_GPIO(12), IRQ_TYPE_EDGE_RISING); // SL811
 
    set_irq_type(IRQ_GPIO(23), IRQ_TYPE_EDGE_FALLING); // 16550A    attach 7406
    set_irq_type(IRQ_GPIO(24), IRQ_TYPE_EDGE_FALLING); // 16550A
    set_irq_type(IRQ_GPIO(25), IRQ_TYPE_EDGE_FALLING); // 16550A
    set_irq_type(IRQ_GPIO(26), IRQ_TYPE_EDGE_FALLING); // 16550A
}
 
static struct platform_device *devices[] __initdata = {
//    &lubbock_flash_device[1],
};
 
static void __init ez_x5_init(void)
{
    platform_add_devices(devices, ARRAY_SIZE(devices));
 
}
 
static struct map_desc ez_x5_io_desc[] __initdata = {
    {
        .virtual = 0xf0000000,
        .pfn = __phys_to_pfn(0x00000000 + 0x000000),
        .length = 0x00400000,
        .type = MT_DEVICE,
    },
    {
        .virtual = 0xf1000000,
        .pfn = __phys_to_pfn(0x00000000 + 0x400000),
        .length = 0x00100000,
        .type = MT_DEVICE,
    },
        {
        .virtual = 0xf1500000,
        .pfn = __phys_to_pfn(PXA_CS1_PHYS + 0x800000),
        .length = 0x00100000,
        .type = MT_DEVICE,
    },
 
   {
        .virtual = 0xf1600000,
        .pfn = __phys_to_pfn(PXA_CS1_PHYS + 0xC00000),
        .length = 0x00100000,
        .type = MT_DEVICE,
    },
};
 
static void __init ez_x5_map_io(void)
{
    pxa_map_io();
    iotable_init(ez_x5_io_desc, ARRAY_SIZE(ez_x5_io_desc));
 
    // FF-UART
    pxa_gpio_mode(GPIO34_FFRXD_MD);
    pxa_gpio_mode(GPIO39_FFTXD_MD);
 
    // ST-UART
    pxa_gpio_mode(GPIO46_STRXD_MD);
    pxa_gpio_mode(GPIO47_STTXD_MD);
}
 
MACHINE_START(WJ_X5, "WJ-X5 Development Platform")
    .phys_io = 0x40000000,
    .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
    .boot_params = 0xa0000100,
    .map_io = ez_x5_map_io,
    .init_irq = ez_x5_init_irq,
    .timer = &pxa_timer,
    .init_machine = ez_x5_init,
MACHINE_END

앞서 만든 파일을 커널 빌드시 함께 컴파일되게 하기 위해 커널 옵션에 선택할 수 있도록 메뉴에 등록시켜야 한다.
arch/arm/mach-pxa/Kconfig 파일에 다음을 추가한다.

L26
...
config MACH_WJ_X5                                    // 추가
     bool "WJ_X5 Development Platform"          // 추가
     select PXA25x                                       // 추가
...

위 옵션을 선택했을 때, 컴파일 되도록 arch/arm/mach-pxa/Makefile 파일을 추가한다.

...
obj-$(CONFIG_MACH_WJ_X5)    += wj_x5.o      // 추가
...

이제 앞서 추가한 커널 옵션을 선택하여 커널 빌드 후에 부팅을 확인해보자.

System Type  --->  
    ARM system type (PXA2xx/PXA3xx-based)  --->                               
    Intel PXA2xx/PXA3xx Implementations  --->         
                                                                       [*] WJ_X5 Development Platform (NEW)        // 선택한다

부팅을 해보면, 마지막 커널 패닉이 발생했던 것과는 달리 ramdisk 를 찾지 못해 발생한 것을 알 수 있다.
이것으로보아 주변 디바이스들의 초기화는 무사히 통과한 것으로 봐도 되겠다.

Copy Kernel Image .....
Copy Ramdisk Image .....
Starting kernel [MARCH 1912]...
kernel command [EZBOOT mem=64M initrd=0xA0800000,5M root=/dev/ram ramdisk=16384 console=ttyS2,115200    ip0=1.1.1.2 mac=00:FA:07:78:65:05 netmask=255.255.255.0 gw=192.16]
Uncompressing Linux..................................................................................... done, booting the kernel.
Linux version 2.6.28.4 (root@fat81) (gcc version 3.4.3) #10 Fri Jan 11 17:53:25 KST 2013
CPU: XScale-PXA255 [69052d06] revision 6 (ARMv5TE), cr=0000397f
CPU: VIVT data cache, VIVT instruction cache
Machine: WJ_X5 Board
Memory policy: ECC disabled, Data cache writeback
Memory clock: 99.53MHz (*27)
Run Mode clock: 398.13MHz (*4)
Turbo Mode clock: 398.13MHz (*1.0, inactive)
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
Kernel command line: EZBOOT mem=64M initrd=0xA0800000,5M root=/dev/ram ramdisk=16384 console=ttyS2,115200    ip0=1.1.1.2 mac=00:FA:07:78:65:05 netmask=255.255.255.0 gw=1 
PID hash table entries: 256 (order: 8, 1024 bytes)
Console: colour dummy device 80x30
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 62176KB available (2416K code, 194K data, 84K init)
SLUB: Genslabs=12, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Calibrating delay loop... 397.31 BogoMIPS (lpj=1986560)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 288 bytes
NET: Registered protocol family 16
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
NET: Registered protocol family 1
NetWinder Floating Point Emulator V0.97 (double precision)
JFFS2 version 2.2. (NAND) �© 2001-2006 Red Hat, Inc.
msgmni has been set to 121
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
pxa2xx-uart.0: ttyS0 at MMIO 0x40100000 (irq = 22) is a FFUART
pxa2xx-uart.1: ttyS1 at MMIO 0x40200000 (irq = 21) is a BTUART
pxa2xx-uart.2: ttyS2 at MMIO 0x40700000 (irq = 20) is a STUART
console [ttyS2] enabled
pxa2xx-uart.3: ttyS3 at MMIO 0x41600000 (irq = 7) is a HWUART
pxa25x_udc: version 30-June-2007
mice: PS/2 mouse device common for all mice
TCP cubic registered
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
XScale DSP coprocessor detected.
VFS: Cannot open root device "ram" or unknown-block(1,0)
Please append a correct "root=" boot option; here are the available partitions:
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)

커널 옵션에서 ramdisk 관련 옵션을 enable 한다.

General Setup  --->
  [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support 
 
Device Drivers  --->
[*] Block devices  ---> 
    <*>   RAM block device support                                                                 
                    (16)    Default number of RAM disks                                                           
                    (16384) Default RAM disk size (kbytes)                             

위에서 램디스크 사이즈를 16384 kbyte 로 잡았는데, 이유는 나중 사용할 램디스크가 16 Mbyte 이기 때문이다(1 Mbyte = 1024 kbyte).

램디스크 만드는 방법은 여러가지가 있을 수 있는데, 여기서는 가장 간단한 방법을 사용한다. 부트로더 처럼 Falinux 에서 제공하는 램디스크를 사용할 것이다.
http://forum.falinux.com/_zdownload/toolchain/ramdisk-3.4.3.tar.gz 에서 다운받는다. 사용방법은 간단하다.

#tar xzf ramdisk-3.4.3.tar.gz -C /opt/
#cd /opt/ramdisk-3.4.3
#./acr          

실행이후 ramdisk-12M.gz 파일이 만들어진다. 앞서 커널 옵션 설정에서 16 Mbyte 짜리 램디스크를 사용한다고 했다. 현재는 12 Mbyte 크기의 램디스크가 만들어지기 때문에 수정이 필요하다. acr 파일을 아래처럼 수정한다.

...
rm -rf ramdisk.new.gz
dd if=/dev/zero of=t_ramdisk bs=1k count=16384                // 16384 로 수정
/sbin/losetup /dev/loop1 t_ramdisk
...

램디스크는 말 그대로 메모리를 디스크처럼 사용한다는 것이다. 램디스크에는 기본적으로 사용하는 명령어들이 들어있다. 그래서 커널 컴파일 시에 크로스 컴파일러 버전이 중요하듯이, 램디스크를 만들때 역시 크로스 컴파일러 버전이 중요하다. 자칫 커널 컴파일을 했던 컴파일러 버전과 램디스크를 만들었던 컴파일러 버전이 많은 차이가 있을 경우, 제대로 실행이 안될 수 있기 때문이다.
여기서 사용하는 크로스 컴파일러는 모두 앞서 언급한 대로 3.4.3 이고, 램디스크 또한 3.4.3 으로 만들어졌다.

앞서 단락에서 설명한대로 acr 파일을 수정하여 만든 램디스크를 다운로드해서 부팅해보자.

brd: module loaded
pxa25x_udc: version 30-June-2007
mice: PS/2 mouse device common for all mice
TCP cubic registered
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
XScale DSP coprocessor detected.
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 filesystem) readonly.
Freeing init memory: 108K
INIT: version 2.86 booting
INIT: Entering runlevel: 3
SIOCSIFADDR: No such device
SIOCSIFNETMASK: No such device
SIOCGIFFLAGS: No such device
SIOCADDRT: No such device
Starting system logger:  syslogd
Starting INET services:  inetd
...
INIT: Id "T0" respawning too fast: disabled for 5 minutes

위 상태에서 머물러 있다. 커널과 램디스크가 뭔가 맞지 않는 것이다.

Falinux 에서 제공하는 2.6 커널용 램디스크(ramdisk-1.11-16M.gz)를 사용한다. 이것을 그대로 사용할 수도 있지만, 아래와 같이 수정할 수도 있다.

#gzip -d ramdisk-1.11-16M.gz
#mount -t ext2 -o loop ramdisk-1.11-16M /mnt/
#cd /mnt
#rm -rf /opt/ramdisk-3.4.3/target_ramdiskroot/*
#cp -arf * /opt/ramdisk-3.4.3/target_ramdiskroot/                      // 추가하고 싶은 파일이 있으면 target_ramdiskroot 안에 넣으면 된다
#cd /opt/ramdisk-3.4.3
#./acr

확인해보자. 반가운 로그인 화면이 뜰 것이다.

  • computer/embedded/이지보드-x5_에_커널_포팅하기.txt
  • Last modified: 3 years ago
  • by likewind