嵌入式系统移植三步曲
计算机与信息工程学院 09级嵌入式方向 刘文华
一、Bootloader的移植
二、Linux的移植
三、根文件系统的移植
第一步:
1、搭建arm-linux-gcc2.95.3交叉编译器
2、解压引导加载程序u-boot-1.1.4.tar.bz2
3、编辑u-boot根目录中的Makefile文件
将
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-
endif
改为
ifeq ($(ARCH),arm)
CROSS_COMPILE=/usr/local/arm/2.95.3/bin/arm-linux-
endif
在
smdk2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
后面添加
LWH2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t LWH2410 NULL s3c24x0
4、复制必要的文件,编辑OK2410.h头文件
将
#define CFG_PROMPT "SMDK2410 # " /* Monitor Command Prompt */
改为
#define CFG_PROMPT "OK2410 # " /* Monitor Command Prompt */
5、编辑board/OK2410/Makefile文件将
OBJS := smdk2410.o flash.o
改为
OBJS := ok2410.o flash.o
6、 配置、编译u-boot
[root@localhost u-boot-1.1.4]# make ok2410_config
Configuring for OK2410 board...
[root@localhost u-boot-1.1.4]# make
会出现错误
......
make -C examples all
make[1]: Entering directory `/root/Desktop/u-boot-1.1.4/examples'
/usr/local/arm/2.95.3/bin/arm-linux-gcc -g -Os -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float -D__KERNEL__ -DTEXT_BASE=0x33F80000 -I/root/Desktop/u-boot-1.1.4/include -fno-builtin -ffreestanding -nostdinc -isystem /usr/local/arm/2.95.3/lib/gcc-lib/arm-linux/2.95.3/include -pipe -DCONFIG_ARM -D__ARM__ -march=armv4 -mabi=apcs-gnu -Wall -Wstrict-prototypes -c -o hello_world.o hello_world.c
cc1: Invalid option `abi=apcs-gnu'
make[1]: *** [hello_world.o] 错误 1
make[1]: Leaving directory `/root/Desktop/u-boot-1.1.4/examples'
make: *** [examples] 错误 2
执行:[root@localhost u-boot-1.1.4]# gedit cpu/arm920t/config.mk
将
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
改成:
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,$(call cc-option,-mabi=apcs-gnu,))
可以解决上面的问题。
[root@localhost u-boot-1.1.4]# make
接着出现了如下的错误:
......
/usr/local/arm/2.95.3/bin/arm-linux-ar crv libstubs.a stubs.o
a - stubs.o
make[1]: *** 没有规则可以创建“all”需要的目标“hello_world.srec”。 停止。
make[1]: Leaving directory `/root/Desktop/u-boot-1.1.4/examples'
make: *** [examples] 错误 2
[root@localhost u-boot-1.1.4]# gedit examples/Makefile
将原文件的第58行开始的内容:
SREC = hello_world.srec
BIN = hello_world.bin hello_world
改为
SREC = hello_world.o
BIN = hello_world.o hello_world
即可重新编译,上面的问题就不会存在了。
7、编辑skyeye.conf文件,即将其放到u-boot-1.1.4这个文件夹中
# skyeye config file for S3C2410X
cpu: arm920t
mach: s3c2410x
# physical memory
mem_bank: map=M, type=RW, addr=0x00000000, size=0x00800000, file=./u-boot.bin ,boot=yes
mem_bank: map=M, type=RW, addr=0x30000000, size=0x00800000
mem_bank: map=M, type=RW, addr=0x30800000, size=0x00800000
mem_bank: map=M, type=RW, addr=0x31000000, size=0x03000000
# all peripherals I/O mapping area
mem_bank: map=I, type=RW, addr=0x48000000, size=0x20000000
mem_bank: map=I, type=RW, addr=0x19000300, size=0x00000020
net: type=cs8900a, base=0x19000300, size=0x20,int=9, mac=08:00:3E:26:0A:5B, ethmod=tuntap, hostip=10.0.0.1
nandflash: type=s3c2410x,name=K9F1208U0B,dump=./nand.dump
#lcd:type=s3c2410x, mod=gtk
dbct:state=on
8、执行skyeye1.2.6
In: serial
Out: serial
Err: serial
LWH2410 #
9、移植 NAND Flash
将从NOR Flash启动改成从NAND Flash启动,重新
编译u-boot,然后测试u-boot是否可以从nand启动
在编译时会出错,需要执行./mknandflashdump u-boot.bin nand.dump 0添加可执行命令将u-boot.bin烧写到nand flash中。并用chmod 666 nand.dump修改mknandflashdump命令生成的nand.dump文件的权限。
10、[root@localhost u-boot-1.1.4]# ./mknandflashdump u-boot.bin nand.dump 0
[root@localhost u-boot-1.1.4]# skyeye1.2.6
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
LWH2410 #
第二步:linux的移植
解压linux-2.6.14.7.tar.bz21、[root@localhost linux-2.6.14.7]# gedit Makefile
将
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
改为
ARCH ?= arm
CROSS_COMPILE ?= /usr/local/arm/3.4.1/bin/arm-linux- // linux2.6.14的交叉编译器为gcc-3.4.1
如果只修改这些编译的时候会出现错误:
把原文件中的321-329行修改成:
AS = /usr/local/arm/3.4.1/bin/arm-linux-as
LD = /usr/local/arm/3.4.1/bin/arm-linux-ld
CC = /usr/local/arm/3.4.1/bin/arm-linux-gcc
CPP = $(CC) -E
AR = /usr/local/arm/3.4.1/bin/arm-linux-ar
NM = /usr/local/arm/3.4.1/bin/arm-linux-nm
STRIP = /usr/local/arm/3.4.1/bin/arm-linux-strip
OBJCOPY = /usr/local/arm/3.4.1/bin/arm-linux-objcopy
OBJDUMP = /usr/local/arm/3.4.1/bin/arm-linux-objdump
编译时即可成成功。
2、在cs8900对其进行网上移植,
[root@localhost linux-2.6.14.7]# cp ../cs8900/cs8900.c drivers/net/arm/
[root@localhost linux-2.6.14.7]# cp ../cs8900/cs8900.h drivers/net/arm/
[root@localhost linux-2.6.14.7]# gedit drivers/net/arm/Kconfig
在最后添加:
config ARM_CS8900
tristate "CS8900 support"
depends on NET_ETHERNET && ARM && ARCH_SMDK2410
help
Support for CS8900A chipset based Ethernet cards. If you have a network
(Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available
from as well as .To compile this driver as a module, choose M here and read.
The module will be called cs8900.o.
修改drivers/net/arm/目录下的Makefile文件,[root@localhost linux-2.6.14.7]# gedit drivers/net/arm/Makefile
在最后添加:
obj-$(CONFIG_ARM_CS8900) += cs8900.o
3、设置Flash分区
在此要编辑3个文件:devs.c、mach-smdk2410.c、s3c2410.c。
(1)编辑devs.c文件,指明分区信息
[root@localhost linux-2.6.14.7]# gedit arch/arm/mach-s3c2410/devs.c
2)编辑mach-smdk2410.c文件,指定启动时初始化
kernel启动时依据对分区的设置进行初始化。
[root@localhost linux-2.6.14.7]# gedit arch/arm/mach-s3c2410/mach-smdk2410.c
(3)编辑s3c2410.c文件,禁止Flash ECC校验
内核通过UBOOT写到Nand Flash,UBOOT通过软件ECC算法产生ECC校验码, 这与内核校验的ECC码不一样, 内核的ECC码是由S3C2410中Nand Flash控制器产生的,所以,在这里要禁止Flash ECC校验。
[root@localhost linux-2.6.14.7]# gedit drivers/mtd/nand/s3c2410.c
4、配置内核
(1)支持启动时挂载devfs
(2)配置内核生成.config文件
然后重新编译内核:
5、执行skyeye1.2.6,通过u-boot-1.1.4引导linux-2.6.14.7会出现如下问题:
LWH2410 # setenv bootargs noinitrd mem=64M root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200
LWH2410 # tftp 0x31000000 uImage
TFTP from server 10.0.0.1; our IP address is 10.0.0.110
Filename 'uImage'.
Load address: 0x31000000
Loading: checksum bad
T T T T T T T T T T
Retry count exceeded; starting again
TFTP from server 10.0.0.1; our IP address is 10.0.0.110
Filename 'uImage'.
Load address: 0x31000000
Loading: T T T T T T T T T T
T表示在尝试连接
此时出现的问题是TFTP服务器没有搭建,需要重新搭建服务器,并修改chmod -R 777 /tftpboot,ptables -F清空防火墙。
[root@localhost u-boot-1.1.4]# skyeye1.2.6
LWH2410 # bootm 31000000
## Booting image at 31000000 ...
Image Name: linux-2.6.14.7
Created: 2009-05-10 14:48:03 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1009504 Bytes = 985.8 kB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ...OK
OK
Starting kernel ...
Uncompressing Linux.................................................................... done, booting the kernel.
Error: unrecognized/unsupported machine ID (r1 = 0x00000000). //出现错误
Available machine support:
ID (hex) NAME
000000c1 SMDK2410
Please check your kernel config and/or bootloader.
原因是:Linux内核启动时出现“unrecognized/unsupported machine ID”,原因大致是u-boot传递给内核的machine ID错误,可以手动在内核源代码中添加machine ID。
解决办法是:[root@localhost linux-2.6.14.7]# gedit arch/arm/kernel/head.S
ENTRY(stext)
/************ me add begin ************/
mov r0, #0
mov r1, #0xc1
ldr r2, =0x30000100
/************ me add end ************/
msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode
@ and irqs disabled
bl __loLWHup_processor_type @ r5=procinfo r9=cpuid
movs r10, r5 @ invalid processor (r5=0)?
beq __error_p @ yes, error 'p'
bl __loLWHup_machine_type @ r5=machinfo
movs r8, r5 @ invalid machine (r5=0)?
beq __error_a @ yes, error 'a'
bl __create_page_tables
[root@localhost u-boot-1.1.4]# skyeye1.2.6
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
TFTP from server 10.0.0.1; our IP address is 10.0.0.110
Filename 'uImage'.
Load address: 0x31000000
Loading: #################################################################
#################################################################
#################################################################
##################
done
Bytes transferred = 1087644 (10989c hex)
## Booting image at 31000000 ...
Image Name: linux-2.6.14.7
Created: 2011-06-11 10:19:19 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1087580 Bytes = 1 MB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
OK
Starting kernel ...
Uncompressing Linux..................................................................... done, booting the kernel.
省略信息
*说明:如果再出现其他的问题可以重新配置、编译内核。我在做题的过程中出现过其他的问题,重新配置过内核后,再执行就行了。
5.有时在启动的时候会出现如下情况:
PID hash table entries: 512 (order: 9, 8192 bytes)
timer tcon=00500000, tcnt a509, tcfg 00000200,00000000, usec 00001e4c
Console: colour dummy device 80x30
[root@localhost u-boot-1.1.4]#
此时由于nfs没有搭建,可以用命令查看
[root@localhost u-boot-1.1.4]# service nfs status
rpc.mountd 已停
nfsd 已停
rpc.rquotad 已停
[root@localhost u-boot-1.1.4]#
[root@localhost u-boot-1.1.4]# service nfs start
启动 NFS 服务: [确定]
关掉 NFS 配额: [确定]
启动 NFS 守护进程: [确定]
启动 NFS mountd: [确定]
[root@localhost u-boot-1.1.4]#
再重新执行skyeye1.2.6
完整的启动过程(u-boot、内核、文件系统)通过tftp将操作系统内核下载到开发板,内核引导时通过NFS挂载根文件系统
编辑tftp服务器,然后重启tftp;
6. 在启动过程中原本可以启动的却在重启计算机后启动不起来了,这时就需要将执行如下命令:
[root@localhost u-boot-1.1.4]# service xinetd restart
停止 xinetd: [确定]
启动 xinetd: [确定]
也有可能是防火墙的问题,需要执行如下命令:
[root@localhost u-boot-1.1.4]#service nfs start
[root@localhost u-boot-1.1.4]#iptables -F
第三步:根文件系统的移植
解压busybox-1.13.4.tar.bz2
1、修改相应的Makefile文件的内容。 2、进行默认配置[root@localhost busybox-1.13.4]# make defconfig //恢复默认配置
对配置信息进行修改
[root@localhost busybox-1.13.4]# make menuconfig
3、对BusyBox进行配置4、编译
[root@localhost busybox-1.13.4]# make
......
CC networking/inetd.o
CC networking/interface.o
networking/interface.c:818: error: `ARPHRD_INFINIBAND' undeclared here (not in a function)
networking/interface.c:818: error: initializer element is not constant
networking/interface.c:818: error: (near initialization for `ib_hwtype.type')
make[1]: *** [networking/interface.o] 错误 1
make: *** [networking] 错误 2
编译出错,此时要修改networking/interface.c文件。
修改networking/interface.c 818行改为 .type = -1
5.对配置信息进行修改(1)在/tmp/nfs中创建所需的目录
(2)复制文件到/tmp/nfs中
6. 创建配置文件(1)编写etc/inittab文件、修改其权限为755
(2)编写etc/init.d/rcS文件、修改其权限为755
(3)编写etc/fstab文件、修改其权限为755
(4)编写etc/proflie文件、修改其权限
(5)创建密码文件、修改其权限
(6)为mdev创建配置文件
(7)删除备份文件
7.复制常用的库文件编写脚本文件copy_lib.sh。
[root@localhost nfs]# gedit copy_lib.sh
至此,一个基本的根文件系统(通过NFS挂载)构建完成
[root@localhost u-boot-1.1.4]# skyeye1.2.6
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
LWH2410 # run bootcmd
TFTP from server 10.0.0.1; our IP address is 10.0.0.110
Filename 'uImage'.
Load address: 0x31000000
Loading: checksum bad
#################################################################
#################################################################
#################################################################
############################
done
Bytes transferred = 1137044 (115994 hex)
## Booting image at 31000000 ...
Image Name: linux-2.6.14.7
Created: 2011-06-15 0:56:31 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1136980 Bytes = 1.1 MB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
OK
省略信息
Mounted devfs on /dev
Freeing init memory: 96K
#mount all.......
******************************************************************
LWH 2410 Rootfs made by lwh,201106
******************************************************************
10.0.0.110 login: root
Password:
10.0.0.110 login:
此时密码不对无法登录。
当输入用户名之后,再输入密码发现密码不正确,那密码到底是什么呢?那就是我们自己的主机密码,可能在输入的主机密码之后还是不能登陆,那么我们就要对密码进行设置了
在文件系统里面etc/passwd里面第一行的:
root:x:0:0:root:/root:/bin/sh
把X删除,之后再重新登陆,此时登陆是不要密码的。在登录之后可以再对其密码进行重新设置,此时要加上X之后再对密码进行设置,也就是用passwd命令可以修改!
完整的启动过程(u-boot、内核、文件系统)
注意:在嵌入式系统开发的过程中,一般的做法是通过tftp将操作系统内核下载到开发板,内核引导时通过NFS挂载根文件系统,下面的操作过程既是如此。
1)编辑/etc/xinetd.d/tftp文件
[root@localhost 嵌入式实验]# gedit /etc/xinetd.d/tftp
(2)重启tftp服务器
[root@localhost Desktop]# service xinetd restart
(3)编辑/etc/exports文件
[root@localhost Desktop]# gedit /etc/exports
(4)重启NFS服务器
[root@localhost u-boot-1.1.4]# service nfs restart
[root@localhost u-boot-1.1.4]# exportfs -ra //重新扫描配置文件
(5)完整的启动过程(u-boot、内核、文件系统、用户程序),使用NFS文件系统
[root@localhost u-boot-1.1.4]# skyeye1.2.6
6)完整的启动过程(u-boot、内核、文件系统),使用/dev/mtdblock2中的文件系统
① 创建cramfs文件系统
② 复制ok2410.cramfs到tftp服务器根目录
③ 执行skyeye1.2.6,启动系统
[root@localhost u-boot-1.1.4]# skyeye1.2.6
http://blog.chinaunix.net/space.php?uid=14735472&do=blog&id=110947