Linux2.6.14.1內核移植手記

開發環境:

gcc cross compiler version: 3.4.1

開發主機:at920

開發板:Friendly-arm 2440

 

1 內核移植過程

1.1 下載linux內核

從http://www.kernel.org/pub/linux/kernel/v2.6/linux2.6.14.1.

tar.bz2

下載linux2.6.14.1

內核至home/arm/dev_home/kernel.

[root@localhost ~]#su arm

[arm@localhost ~]#cd $KERNEL

[arm@localhost kernel]#tar xzvf

linux2.6.14.1.

tar.gz

[arm@localhost kernel]# pwd

/home/arm/dev_home/kernel

[arm@localhost kernel]# cd linux2.6.14

進入內核解壓後的目錄,以後示例中,只要是相對路徑全部是相對於

/home/arm/dev_home/kernel/linux2.6.14/

此目錄

1.2 修改Makefile

修改內核目錄樹根下的的Makefile,指明交叉編譯器

[arm@localhost linux2.6.14]#

vi Makefile

找到ARCH和CROSS_COMPILE,修改

ARCH ?= arm

CROSS_COMPILE ?= armlinux

然後設置你的PATH環境變量,使其可以找到你的交叉編譯工具鏈

[arm@localhost linux2.6.14]#

echo $PATH

/usr/local/arm/3.4.4/bin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/ly/bin

如果/usr/local/arm/3.4.4/bin搜索路徑, 加入下面語句在~/.bashrc中

[arm@localhost linux2.6.14]#

vi ~/.bashrc

export PATH=/usr/local/arm/3.4.4/bin:$PATH

再重新登陸.

[arm@localhost linux2.6.14]#

su arm

1.3 設置flash分區

此處一共要修改3個文件,分別是:

1.3.1指明分區信息

在arch/arm/machs3c2410/

devs.c文件中:

[arm@localhost linux2.6.14]$

vi arch/arm/machs3c2410/

devs.c

添加如下內容:

#i nclude <linux/mtd/partitions.h>

#i nclude <linux/mtd/nand.h>

#i nclude <asm/arch/nand.h>

...

/* NAND Controller */

1.建立Nand Flash分區表

/* 一個Nand Flash總共64MB, 按如下大小進行分區 */

static struct mtd_partition partition_info[] ={

{ /* 1MB */

name: "bootloader",

size: 0x00100000,

offset: 0x0,

},{ /* 3MB */

name: "kernel",

size: 0x00300000,

offset: 0x00100000,

}, { /* 40MB */

name: "root",

size: 0x02800000,

offset: 0x00400000,

}, { /* 20MB */

name: "user",

size: 0x00f00000,

offset: 0x02d00000,

}

};

name: 代表分區名字

size: 代表flash分區大小(單位:字節)

offset: 代表flash分區的起始地址(相對於0x0的偏移)

目標板計劃分4個區,分別存放bootloader, kernel, rootfs以及以便以後擴展使用的用戶文件系統空間。

各分區在Nand flash中起始地址. 分區大小. 記錄如下:

bootloader:

start: 0x00000000

len: 0x00100000

1MB

kernel:

start: 0x00100000

len: 0x00300000

3MB

rootfs:

start: 0x00400000

len: 0x02800000

40MB

User:

start: 0x02c00000

len: 0x01400000

20MB

2. 加入Nand Flash分區

struct s3c2410_nand_set nandset ={

nr_partitions: 4, /* the number of partitions */

partitions: partition_info, /* partition table */

};

nr_partitions: 指明partition_info中定義的分區數目

partitions: 分區信息表

3. 建立Nand Flash芯片支持

struct s3c2410_platform_nand superlpplatform={

tacls:0,

twrph0:30,

twrph1:0,

sets: &nandset,

nr_sets: 1,

};

tacls, twrph0, twrph1的意思見S3C2410手冊的63,

這3個值最後會被設置到NFCONF中,見S3C2410手冊66.

sets: 支持的分區集

nr_set:分區集的個數

4. 加入Nand Flash芯片支持到Nand Flash驅動

另外,還要修改此文件中的s3c_device_nand結構體變量,添加對dev成員的賦值

struct platform_device s3c_device_nand = {

.name = "s3c2410nand",

/* Device name */

.id = 1,

/* Device ID */

.num_resources = ARRAY_SIZE(s3c_nand_resource),

.resource = s3c_nand_resource, /* Nand Flash Controller Registers */

/* Add the Nand Flash device */

.dev = {

.platform_data = &superlpplatform

}

};

name: 設備名稱

id: 有效設備編號,如果只有唯一的一個設備爲1,

有多個設備從0開始計數.

num_resource: 有幾個寄存器區

resource: 寄存器區數組首地址

dev: 支持的Nand Flash設備

1.3.2 指定啓動時初始化

kernel啓動時依據我們對分區的設置進行初始配置

修改arch/arm/machs3c2410/

machsmdk2410.

c文件

[arm@localhost linux2.6.14]$

vi arch/arm/machs3c2410/

machsmdk2410.

c

修改smdk2410_devices[].指明初始化時包括我們在前面所設置的flash分區信息

static struct platform_device *smdk2410_devices[] __initdata = {

&s3c_device_usb,

&s3c_device_lcd,

&s3c_device_wdt,

&s3c_device_i2c,

&s3c_device_iis,

/* 添加如下語句即可 */

&s3c_device_nand,

};

保存,退出。

1.3.3 禁止Flash ECC校驗

我們的內核都是通過UBOOT寫到Nand Flash的, UBOOT通過的軟件ECC算法產生ECC校驗碼, 這與內核

校驗的ECC碼不一樣, 內核中的ECC碼是由S3C2410中Nand Flash控制器產生的. 所以, 我們在這裏選擇禁止

內核ECC校驗.

修改drivers/mtd/nand/s3c2410.c 文件:

[arm@localhost linux2.6.14]$

vi drivers/mtd/nand/s3c2410.c

找到s3c2410_nand_init_chip()函數,在該函數體最後加上一條語句:

chip>

eccmode = NAND_ECC_NONE;

保存,退出。

OK.我們的關於flash分區的設置全部完工.

1.4 配置內核

1.4.1 支持啓動時掛載devfs

爲了我們的內核支持devfs以及在啓動時並在/sbin/init運行之前能自動掛載/dev爲devfs文件系統,修改

fs/Kconfig文件

[arm@localhost linux2.6.14]$

vi fs/Kconfig

找到menu "Pseudo filesystems"

添加如下語句:

config DEVFS_FS

bool "/dev file system support (OBSOLETE)"

default y

config DEVFS_MOUNT

bool "Automatically mount at boot"

default y

depends on DEVFS_FS

1.4.2配置內核產生.config文件

[arm@localhost linux2.6.14]$

cp arch/arm/configs/smdk2410_defconfig .config

[arm@localhost linux2.6.14]$

make menuconfig

在smdk2410_defconfig基礎上,我所增刪的內核配置項如下:

Loadable module support >

[*] Enable loadable module support

[*] Automatic kernel module loading

System Type >

[*] S3C2410 DMA support

Boot options >

Default kernel command string:

noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200

#說明:mtdblock2代表我的第3個flash分區,它是我的rootfs

# console=ttySAC0,115200使kernel啓動期間的信息全部輸出到串口0上.

# 2.6內核對於串口的命名改爲ttySAC0,但這不影響用戶空間的串口編程。

# 用戶空間的串口編程針對的仍是/dev/ttyS0等

Floating point emulation >

[*] NWFPE math emulation

This is necessary to run most binaries!!!

#接下來要做的是對內核MTD子系統的設置

Device Drivers >

Memory Technology Devices (MTD) >

[*] MTD partitioning support

#支持MTD分區,這樣我們在前面設置的分區纔有意義

[*] Command line partition table parsing

#支持從命令行設置flash分區信息,靈活

RAM/ROM/Flash chip drivers >

<*> Detect flash chips by Common Flash

Interface (CFI) probe

<*> Detect nonCFI

AMD/JEDECcompatible

flash chips

<*> Support for Intel/Sharp flash chips

<*> Support for AMD/Fujitsu flash chips

<*> Support for ROM chips in bus mapping

NAND Flash Device Drivers >

<*> NAND Device Support

<*> NAND Flash support for S3C2410/S3C2440 SoC

Character devices >

[*] Nonstandard

serial port support

[*] S3C2410 RTC Driver

#接下來做的是針對文件系統的設置,本人實驗時目標板上要上的文件系統是cramfs,故做如下配置

File systems >

<> Second extended fs support #去除對ext2的支持

Pseudo filesystems >

[*] /proc file system support

[*] Virtual memory file system support (former shm fs)

[*] /dev file system support (OBSOLETE)

[*] Automatically mount at boot (NEW)

#這裏會看到我們前先修改fs/Kconfig的成果,devfs已經被支持上了

Miscellaneous filesystems >

<*> Compressed ROM file system support (cramfs)

#支持cramfs

Network File Systems >

<*> NFS file system support

保存退出,產生.config文件.

.config文件能從提供的2.4.14.1的內核包中找到,文件名爲config.back.

1.4.3編譯內核

[arm@localhost linux2.6.14]$

make zImage

注意:若編譯內核出現如下情況

LD .tmp_vmlinux1

armlinuxld:

arch/arm/kernel/vmlinux.lds:1439: parse error

make: *** [.tmp_vmlinux1] Error 1

解決方法:修改arch/arm/kernel/vmlinux.lds

[arm@localhost linux2.6.14]$

vi arch/arm/kernel/vmlinux.lds

將文件尾2條的ASSERT註釋掉(1439行)

/* ASSERT((__proc_info_end __

proc_info_begin), "missing CPU support") */

/* ASSERT((__arch_info_end __

arch_info_begin), "no machine record defined") */

然後重新make zImage即可

1.4.4 下載zImage到開發板

CRANE2410 # tftp 0x30008000 zImage

TFTP from server 192.168.1.6; our IP address is 192.168.1.5

Filename 'zImage'.

Load address: 0x30008000

Loading: #################################################################

#################################################################

#################################################################

#############################

done

Bytes transferred = 1142856 (117048 hex)

CRANE2410 # bootm 0x30008000

 

1.4.5 目標板啓動信息如下

U-Boot 1.1.6 (Mar  8 2007 - 14:47:53)                                                               

                                                                                                    

DRAM:  64 MB                                                                                         

Flash:  1 MB                                                                                        

*** Warning - bad CRC, using default environment                                                     

                                                                                                    

In:    serial                                                                                       

Out:   serial                                                                                        

Err:   serial                                                                                       

Hit any key to stop autoboot:  0                                                                     

[ ~ljh@GDLC ]# loady

## Ready for binary (ymodem) download to 0x33000000 at 115200 bps...                                

C0(STX)/0(CAN) packets, 6 retries

## Total Size      = 0x000f5ec4 = 1007300 Bytes

[ ~ljh@GDLC ]# bootm

## Booting image at 33000000 ...

   Image Name:   Linux-2.6.14

   Created:      2007-03-09   5:17:52 UTC

   Image Type:   ARM Linux Kernel Image (uncompressed)

   Data Size:    1007236 Bytes = 983.6 kB

   Load Address: 30008000

   Entry Point:  30008000

   Verifying Checksum ... OK

OK

 

Starting kernel ...

 

Uncompressing Linux.................................................................... done, booting the kernel.

Linux version 2.6.14 ([email protected]) (gcc version 3.3.2) #3 Fri Mar 9 10:52:49 CST 2007

CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)

Machine: SMDK2410

Memory policy: ECC disabled, Data cache writeback

CPU S3C2410 (id 0x32410000)

S3C2410: core 200.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz

S3C2410 Clocks, (c) 2004 Simtec Electronics

CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on

CPU0: D VIVT write-back cache

CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets

CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets

Built 1 zonelists

Kernel command line: console=ttySAC0 root=/dev/nfs nfsroot=10.1.8.246:/friendly-arm/rootfs_netserv ip=10.1.8.245:10.1.8.246:f

irq: clearing subpending status 00000002

PID hash table entries: 512 (order: 9, 8192 bytes)

timer tcon=00500000, tcnt a2c1, tcfg 00000200,00000000, usec 00001eb8

Console: colour dummy device 80x30

Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)

Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)

Memory: 64MB = 64MB total

Memory: 62592KB available (1694K code, 386K data, 96K init)

Mount-cache hash table entries: 512

CPU: Testing write buffer coherency: ok

softlockup thread 0 started up.

NET: Registered protocol family 16

S3C2410: Initialising architecture

S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics

DMA channel 0 at c4800000, irq 33

DMA channel 1 at c4800040, irq 34

DMA channel 2 at c4800080, irq 35

DMA channel 3 at c48000c0, irq 36

NetWinder Floating Point Emulator V0.97 (double precision)

devfs: 2004-01-31 Richard Gooch ([email protected])

devfs: boot_options: 0x1

Console: switching to colour frame buffer device 80x25

fb0: Virtual frame buffer device, using 1024K of video memory

S3C2410 RTC, (c) 2004 Simtec Electronics

s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410

s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410

s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410

io scheduler noop registered

io scheduler anticipatory registered

io scheduler deadline registered

io scheduler cfq registered

RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize

S3C24XX NAND Driver, (c) 2004 Simtec Electronics

s3c2410-nand: mapped registers at c4980000

s3c2410-nand: timing: Tacls 10ns, Twrph0 40ns, Twrph1 10ns

NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)

NAND_ECC_NONE selected by board driver. This is not recommended !!

Scanning device for bad blocks

Bad eraseblock 4080 at 0x03fc0000

Creating 4 MTD partitions on "NAND 64MiB 3,3V 8-bit":

0x00000000-0x00100000 : "bootloader"

0x00100000-0x00400000 : "kernel"

0x00400000-0x02c00000 : "root"

0x02d00000-0x03c00000 : "user"

mice: PS/2 mouse device common for all mice

NET: Registered protocol family 2

IP route cache hash table entries: 1024 (order: 0, 4096 bytes)

TCP established hash table entries: 4096 (order: 2, 16384 bytes)

TCP bind hash table entries: 4096 (order: 2, 16384 bytes)

TCP: Hash tables configured (established 4096 bind 4096)

TCP reno registered

TCP bic registered

NET: Registered protocol family 1

IP-Config: Device `eth0' not found.

Looking up port of RPC 100003/2 on 10.1.8.246

RPC: sendmsg returned error 101

portmap: RPC call returned error 101

Root-NFS: Unable to get nfsd port number from server, using default

Looking up port of RPC 100005/1 on 10.1.8.246

RPC: sendmsg returned error 101

portmap: RPC call returned error 101

Root-NFS: Unable to get mountd port number from server, using default

RPC: sendmsg returned error 101

Root-NFS: Server returned error -101 while mounting /friendly-arm/rootfs_netserv

VFS: Unable to mount root fs via NFS, trying floppy.

VFS: Cannot open root device "nfs" or unknown-block(2,0)

Please append a correct "root=" boot option

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)

 

2 創建uImage

2.1 相關技術背景介紹

前面已經介紹了內核編譯後,生成zImage的內核鏡像文件。該鏡像文件可以通過UBOOT

提供的go命令,

跳轉執行,引導內核。同時在uboot1.1.4

的tools目錄下,提供了生成uImage的工具mkimage命令,在生成

uboot

的二進制鏡像文件的同時,mkimage命令會同時編譯生成,無需另外編譯。通過mkimage命令,在

zImage中加入頭文件(鏡像頭長0x40,真正的內核入口向後偏移了0x40大小),生成uImage鏡像文件,該文

件就是執行bootm所需的內核鏡像文件。

2.2 在內核中創建uImage的方法

2.2.1 獲取mkimage工具

2.6內核樹的Makefile提供了創建uImage的方法,但需要我們提供相應的mkimage命令。

所以首先拷貝uboot

中tools目錄下編譯後生成的mkimage到/usr/bin/下,然後便可以在內核根目錄下通過

make uImage

來創建uImage文件。該文件生成在arch/arm/boot/下。

 

常見問題及解決方法:

1. Linux內核啓動時出現:bad machine ID,原因大致是u-boot傳遞給內核的machine ID錯誤,可以手動在內核源代碼中添加machine ID.

解決方法:

在U-boot命令行中輸入

bdinfo

查看板卡信息,我的輸出如下:

[ ~ljh@GDLC ]# bdinfo

arch_number = 0x000000C1

env_t       = 0x00000000

boot_params = 0x30000100

DRAM bank   = 0x00000000

-> start    = 0x30000000

-> size     = 0x04000000

ethaddr     = 08:00:3E:26:0A:5B

ip_addr     = 10.1.8.245

baudrate    = 115200 bps

可以看出arch_number爲0xC1, 接着編輯內核中的arch/arm/boot/compressed/head.S文件,修改

1:    mov    r7, r1        @save architecture ID

  改爲(arch/arm/tools/mach-types,您所使用的machine type)

   1:    mov    r7, 0xC1      @save architecture ID

從新編譯內核即可

 

移植到開發板,啓動。

PS:可能會遇到Uncompressing Linux................................................................ done, booting the kernel.就不動了的錯誤。原因很簡單,命令行的console參數錯了,應該爲console=ttySAC0,不是console=ttyS0。

因爲2.6對2410的串口支持已經很好了,使用默認配置的話就不要去懷疑串口驅動了,問題出在命令行上。有人說我將默認的命令行改成了console=ttySAC0也還是不行。這隻能說明改動了默認的命令行,只有在bootloader沒有傳遞命令行參數給內核的時候才起作用。如果你的bootloader傳遞命令行參數給內核了,則在bootloader中將命令行改了就行了。例如:“console=ttySAC0,115200 root=/dev/ram init=/linuxrc rw initrd=0x30008000,0x320000 ”。

    因爲燒寫bootloader麻煩,時間長,調試階段不建議修改bootloader。我將內核中的arch/arm/kernel/setup.c文件中的parse_tag_cmdline()函數中的內容註釋掉,並且配置正確的CONFIG_CMDLINE參數,即可運行。以後每當改變內核參數只要改變CONFIG_CMDLINE就可以了。(CONFIG_CMDLINE這個值可以在make menuconfig中配置,2.6.11版本和2.6.14版本配置位置有所不同,請注意)。

也許你按上面的方法還是不行,那你就得改bootloader了,一般在BIOS的SRC/NAND.C文件中定義的,把裏面的命令和相關命令註釋掉,再按上面的方法。(爲什麼要註釋掉,我想你不可能只想用一個內核吧!!這樣做就可以在內核中隨便修改參數了。。。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章