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 (arm@localhost.localdomain) (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 (rgooch@atnf.csiro.au)

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文件中定义的,把里面的命令和相关命令注释掉,再按上面的方法。(为什么要注释掉,我想你不可能只想用一个内核吧!!这样做就可以在内核中随便修改参数了。。。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值