全部博文(776)
分类: LINUX
2010-12-07 08:29:42
一. 移植环境
主机:虚拟机 9
目标机:友善之臂 QQ2440开发板
交叉编译器:arm-linux-3.4.1
二. 移植linux-2.6.32.2内核到QQ2440开发板
1.获得内核:
2.解压内核: tar –jxvf linux-2.6.32.2.tar.bz2
3.修改参数:
3.1 进入内核目录,修改makefile
ARCH ?=arm
CROSS_COMPILE ?=arm-linux-
然后执行如下的命令,使用arch/arm/configs/s3c2410_defconfig文件来配置内核,它生成.config配置文件,以后就可以直接使用”make menuconfig”修改配置了。
make s3c2410_defconfig
最后是编译生成内核,执行”make”命令将在顶层目录下生成内核映像文件vmlinux;执行”make uImage”除生成vmlinux外,还在arch/arm/boot目录下生成U-Boot格式的内核映像文件uImage;执行”make zImage”除生成vmlinux外,还在arch/arm/boot目录下生成vivi引导的内核映像文件zImage。
3.2 修改平台输入时钟由于QQ2440板子 系统时钟源为 12M 无源晶振
找到内核源码arch/arm/mach-s3c2440/mach-smdk2440.c文件,
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(12000000);//原来是16934400
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}
3.3 修改MTD分区信息
修改文件arch/arm/plat-s3c24xx/common-smdk.c。
第一,修改分区信息(64M):
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "bootloader",
.offset = 0x00000000,
.size = 0x00030000,
},
[1] = {
.name = "kernel",
.offset = 0x00050000,
.size = 0x00200000,
},
[2] = {
.name = "root",
.offset = 0x00250000,
.size = 0x03dac000,
}
};
3.4 修改S3C2440 的机器号
由于Bootloader 传递给Linux 内核的机器号为782(根据实际的情况)
修改 arch/arm/tools/mach-types 文件
s3c2440 ARCH_S3C2440 S3C2440 782
3.5 给内核打yaffs2文件系统的补丁
从http:/获取源代码文件cvs-root.tar,解压源码目录并进入目录
cd /…/…/cvs/yaffs2
./patch-ker.sh c /
上面命令完成下面三件事情:
(1) 修改内核fs/Kconfig
增加一行:source "fs/yaffs2/Kconfig"
(2) 修改内核fs/Kconfig
增加一行:ojb-$(CONFIG_YAFFS_FS) +=yaffs2/
(3) 在内核fs/目录下创建yaffs2 目录
将yaffs2 源码目录下面的Makefile.kernel 文件复制为fs/yaffs2/Makefie;
将yaffs2 源码目录的Kconfig 文件复制到内核fs/yaffs2 目录下;
将yaffs2 源码目录下的*.c *.h 文件复制到内核fs/yaffs2 目录下.
3.6 内核配置
1> 进入Linux-2.6.32.2内核主目录,通过以下命令将2410的默认配置文件写到当前目录下的.config。S3C2410的配置和S3C2440差不多,,在这基础上进行修改。
make s3c2410_defconfig (也可以上面就做)
2> 配置内核模块的功能,有几种方式可以进行界面选择:
make menuconfig(文本选单的配置方式,在有字符终端下才能使用)
make xconfig(图形窗口模式的配置方式,图形窗口的配置比较直观,必须支持Xwindow下才能使用)
make oldconfig(文本配置方式,在原内核配置的基础修改时使用)
这里使用make menuconfig命令。
3> [*]Enable loadable module support--->
[*]Forced module loading
[*]Module unloading
4> System Type--->
S3C2410 Machines--->
[*]SMDK2410/A9M2410选上 其余不选
S3C2440 Machines--->
[*]SMDK2440
[*]SMDK2440 with S3C2440 CPU module,其余不选
其余的Machines下选项全部不选(如2400,2412,2442,2443)
5> Kernel Features--->
[ ]Use the ARM EABI to compile the kernel
注:如果所使用的的交叉编译arm-linux-gcc-4.3.2是符合EABI标准交叉编译器,对于浮点运行会预设硬浮点运算FPA(Float Point Architecture),而没有FPA的CPU,比如SAMSUNG S3C2410/S3C2440,会使用FPE(Float Point Emulation 即软浮点),这样在速度上就会遇到极大的限制,使用EABI(Embedded Application Binary Interface)则可以对此改善处理,ARM EABI有许多革新之处,其中最突出的改进就是Float Point Performance,它使用Vector Float Point(矢量浮点),因此可以极大提高涉及到浮点运算的程序。
6> Boot options-?
noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0
7> Userspace binary formats--->
[*]Kernel support for ELF binaries
其它的可以全部不选。
8> 选择支持yaffs2文件系统
Filesystem--->
Miscellaneous filesystems--->
<*>YAFFS2 file system support
[*] Lets Yaffs do its own ECC
Native language support
<*> Codepage 437 (United States,Canada)
<*>Simplified Chinese charset(GB2312)
<*>Traditional Chinese charset(Big5)
<*>NLS ISO 8859-1(Latin1:Western European Languages)
<*>NLS UTF-8
配置完成以后,我们就可以通过以上的命令生成我们需要的uImage或者zImage镜像文件了,然后通过uboot或者supervivi烧写内核。我们通过supervivi的USB工具下载的内核启动情况如下:
Copy linux kernel from 0x00050000 to 0x30008000, size = 0x00200000 ... done
zImage magic = 0x016f2818
Setup linux parameters at 0x30000100
linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySA
C0"
MACH_TYPE = 782
NOW, Booting Linux......
Uncompressing Linux.............................................................
....................................... done, booting the kernel.
Linux version 2.6.32.2 (root@localhost.localdomain) (gcc version 3.4.1) #1 Fri M
ay 7 16:57:01 CST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
Machine: SMDK2440
。。。。。。。。。
Failed to execute /linuxrc. Attempting defaults...
Kernel panic - not syncing: No init found. Try passing init= option to kernel.
从以上的启动信息可知还需要文件系统才能启动。
下一步我们将建立yaffs根文件系统。
前一篇文章我们已将Linux-2.6.32.2的内核移植好了,当然了驱动我们还没有添加上去,今天我们先建立一个yaffs文件系统,待我们的内核能够挂载我们的文件系统以后,我们再去进一步的完善内核,这样,嵌入式linux系统就算是构建成功了。
1、 下载busybox
在home/kele888目录下建立rootfs文件夹,并把busybox压缩文件解压到home/kele888目录下我下载的是busybox-1.13.0的版本。
[root@localhost kele888]# ls
busybox-1.13.0 ....
[root@localhost kele888]#
2、 进入busybox目录开始编译
修改Makefile文件
# vim Makefile
164行 CROSS_COMPILE ?= arm-linux-
190行 ARCH ?= arm
保存推出
配置busybox
# make menuconfig(可以根据需要适当选择,改一下其他默认就行了)
BusyBox Settings --->
Build Options ---> (采用静态编译)
[*] Build BusyBox as a static binary (no shared libs)
Install optin-->
[*] Don't use /usr //可以不选,选了则没有/usr文件夹
Busybox Library Tuning --->
(2) MD5: Trade Bytes for Speed
[*] Faster /proc scanning code (+100 bytes)
[*] Support for /etc/networks
[*] Command line editing
[*] Additional editing keys
[*] vi-style line editing commands
[*] History saving
[*] Tab completion
[*] Username completion
[*] Fancy shell prompts
Linux Module Utilities --->
[ ] Support version 2.2.x to 2.4.x Linux kernels
[*] Support version 2.6.x Linux kernels
Linux System Utilities --->
[*] Support for the old /etc/mtab file
Miscellaneous Utilities --->
[*] devfs(obsolete)
[*] Use devfs names for all device(obsolete)
Shell --->
Choose your default shell(ash)-->
---ash
编译安装busybox
make CONFIG_PREFIX=/home/kele888/rootfs install
注:编译“networking/interface.c”文件时可能会出现以下错误:
CC networking/interface.o
networking/interface.c:818: error: 'ARPHRD_INFINIBAND' undeclared here (not in a function)
make[1]: *** [networking/interface.o] Error 1
make: *** [networking] Error 2
通过查看内核源代码目录中的“include/linux/ifarp.h”文件可得知“ARPHRDINFINIBAND”的值为“32”,然后修改“networking/interface.c”文件,在其中添加:
#define ARPHRD_INFINIBAND 32
完成以后将会在rootfs文件下生成如下的文件:
bin linuxrc sbin usr
修改_install/bin/busybox 的属性。为+x
chmod +x ./_install/bin/busybox
必须要修改属性,否则在busybox 中很多命令会受限
然后在rootfs中建立其它目录
mkdir dev etc home lib mnt proc sys tmp root var
下面我们看一下由busybox生成以及自己mkdir的文件里面的一些内容(当然有些是不必要的):
“dev”目录
下面的内容在内核挂载完毕文件系统后,系统会使用mdev 自动建立。
不过mdev 是调用init 进程来启动的,在使用mdev 构建“dev”目录前,init 进程需要用到“/dev/console”和“/dev/null”这两个设备文件,所以,我们需要在制作文件系统时静态创建这两个设备文件,方法如下:
#mknod console c 5 1
#mknod null c 1 3
如果不创建这两个设备文件,在文件系统启动时会出现错误信息.大概是不能初始化控制台。
“etc”目录
用来存放系统的配置文件。
在“etc”目录下面有如下常用的文件:
fstab:指明需要挂载的文件系统;
group:用户组;
inittab:init 进程的配置文件;
passwd:密码文件;
profile:用户环境配置文件;
mdev.conf:因为2.6.18 版本开始linux 放弃使用devfs 而采用udev(mdev 是udev 的简化版本),这里的
mdev.conf 文件可以是空,也可以按照一定规则来编写,这里我采用了为空;
resolv.conf:存放DNS 信息的文件,访问外网时需要DNS 的信息。
常用的目录有:
init.d 目录:启动文件目录,该目录下面有个“rcS”的文件,里面存放了系统启动时配置以及自启动加载
的进程等;
sysconfig 目录:在我们的文件系统里面,该目录下面存放了名为“HOSTNAME”的文件,该文件内容为:
Kele,这句话就是我们在文件系统里面看到那个“[root@ Kele/]” rc.d 目录:在我们的文件系统里面用来存放一些自启动所要调用的脚步等;
-----------------------/lib文件--------------------------------
/lib的库其实就是进行busybox编译的库,即交叉编译器的库,我们这里使用的是3.4.1(位置/usr/local/arm/3.4.1)。
# cd /usr/local/arm/3.4.1/arm-linux/lib
# for file in libc libcrypt libdl libm libpthread libresolv libutil
> do
> cp $file-*.so rootfs/lib (复制到你做的文件系统的/lib目录下)
> cp -d $file.so.[*0-9] rootfs/lib
> done
# cp -d ld*.so* rootfs/lib
-----------------系统配置文件的建立---------------------
--========/etc目录============
(1) fstab文件
# device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
(2)inittab文件
# /etc/inittab
::sysinit:/etc/init.d/rcS
s3c2410_serial0::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
(3)创建/etc/init.d文件夹和rcS,在rcS中添加
#!/bin/sh
ifconfig eth0 192.168.1.17
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
(4)host文件
Kele
(5)创建mdev.conf文件 (空文件)
(6)复制主机/etc/下面的文件passwd, group, shadow 文件到/etc
# cp /etc/group .
# cp /etc/passwd .
# cp /etc/shadow .
修改passwd中用户使用的shell名称。FC6上默认的为bash,而vivi只支持ash。
root:x:0:0:root:/root:/bin/bash -->root:x:0:0:root:/root:/bin/ash
(7)修改各文件和文件夹的权限
# chmod 755 /rootfs/etc/init.d/rcS
# chmod 755 /rootfs/etc/host