定制6410开发板的linux最小内核/文件系统

故事的背景

本学期俺老孙学习嵌入式操作系统(),最终课程项目是定制内核与开发一个视频播放程序:

1.定制和移植6410开发板上的嵌入式linux最小内核与最小文件系统
2.在最小系统的基础上加入利用6410平台视频硬编码的视频播放器

我手上拥有的硬件:Tiny6410开发板一个(屏幕型号是H43)。
目标:最短时间内最高效地完成任务。

交叉编译环境搭建

安装虚拟机

上头给的开发系统是Fedora 9(32位),有点老,安装时需要注意一些问题。

问题1

我的虚拟机是VM 11,安装Fedora 9时需将处理器数量设为1,每处理器核心设为2,如果不这样做您就会卡在安装界面,如下图:
![卡住的界面][1]

正常的安装界面是这样的:
![正常的安装界面][2]

问题2

设置磁盘大小时,最好设置为20G,太小可能出问题,到时需要重装(编译内核需要占用极大的空间)。

问题3

启动Fedora 9虚拟机时,VM11提示VMware Workstation cannot connect to the virtual machine

对付此问题,只需打开控制面板——管理工具——服务,找到VMware Authorization Service服务,右键设置启动类型为自动,再右键启动。

问题4

安装完,开机后直接进入黑乎乎的字符界面,尝试用startx命令进入图形界面时,被告知no screen found

这是由于您使用了VM11的简便安装模式,它会默认跳过图形界面的安装,只安装服务器必须的软件,默认安装只828个包,实际上需要一千多个才有图形界面:
![][3]

解决方法:在创建虚拟机时选择稍后安装操作系统,创建完毕再添加镜像文件,启动后就是自定义安装了。

问题5

一切装置完了之后,再次卡住,卡在Starting udev
![][4]

这个有点复杂,估计是硬件不兼容之类的问题,持续等待几分钟后再次提示“Wait timeout. Will continue in the background.”

于是俺百度谷歌了一番,有人说是fedora识别方面有些BUG需要修改fedora的一些文件,但我进不了系统,也就没法从这里入手解决;有人说是CPU数量大于1的关系,我将CPU数量设为1,核心数量也设为1,依旧不行。

这时我想起来,按照VM11的简便模式安装后可以进入登录界面,而自定义安装加上图形界面就无法初始化硬件,莫非,是屏幕显示器的问题?

于是我修改虚拟机的屏幕,改“将主机设置用于监视器”“制定监视器设置”,并指定分辨率为1024 * 768(我的显示器是27寸1080P,可能fedora9带不起),然后,就能成功进入设置界面了。
![][5]

注意以上问题,虚拟机很容易就安装完毕了。

交叉编译工具

准备工具包

crosstool-0.43.tar.gz
binutils-2.16.1.tar.bz2
gcc-4.0.2.tar.gz
glibc-2.3.6.tar.gz glibc-linuxthreads-2.3.6.tar.gz linux-2.6.26.tar.gz linux-libc-headers-2.6.12.0.tar.bz

使用非root用户登录

建立存放工具包源码的cross目录

1
mkdir /home/qiuyongchen/cross
将 crosstool-0.43.tar.gz 复制到 cross 目录并解压
将其它工具包复制到cross目录
进入crosstool-0.43 目录对相关文件进行修改

【1】修改 arm.dat

1
2
3
KERNELCONFIG=`pwd`/arm.config  
TARGET=arm-linux
TARGET_CFLAGS="-O"

【2】修改 demo-arm.sh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/bin/sh  
# This script has one line for each known working toolchain
# for this architecture. Uncomment the one you want.
# Generated by generate-demo.pl from buildlogs/all.dats.txt

TARBALLS_DIR=/home/lit/cross(修改这里) #下载的源码包存放的路径
RESULT_TOP=/home/qiuyongchen/crosstool(修改这里)#交叉编译工具链安装的路径
export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES="c,c++"
export GCC_LANGUAGES

# Really, you should do the mkdir before running this,
# and chown /opt/crosstool to yourself so you don't need to run as root.
mkdir -p $RESULT_TOP

#eval `cat arm.dat gcc-2.95.3-glibc-2.1.3.dat` sh all.sh --notest
#eval `cat arm.dat gcc-2.95.3-glibc-2.2.2.dat` sh all.sh --notest
#eval `cat arm.dat gcc-2.95.3-glibc-2.2.5.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.2.3-glibc-2.2.5.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.2.3-glibc-2.3.2.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.2.3-glibc-2.3.2-tls.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.3.6-glibc-2.2.2.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.3.6-glibc-2.2.5.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.3.6-glibc-2.3.2.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.3.6-glibc-2.3.2-tls.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.4.5-glibc-2.2.2.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.4.5-glibc-2.2.5.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.4.5-glibc-2.3.2.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.4.5-glibc-2.3.2-tls.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.4.5-glibc-2.3.5.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.4.5-glibc-2.3.5-tls.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh --notest
#eval `cat arm.dat gcc-3.4.5-glibc-2.3.6-tls.dat` sh all.sh --notest
#eval `cat arm.dat gcc-4.0.2-glibc-2.2.2.dat` sh all.sh --notest
#eval `cat arm.dat gcc-4.0.2-glibc-2.3.2.dat` sh all.sh --notest
#eval `cat arm.dat gcc-4.0.2-glibc-2.3.2-tls.dat` sh all.sh --notest
#eval `cat arm.dat gcc-4.0.2-glibc-2.3.5.dat` sh all.sh --notest
#eval `cat arm.dat gcc-4.0.2-glibc-2.3.5-tls.dat` sh all.sh --notest
#eval `cat arm.dat gcc-4.0.2-glibc-2.3.6.dat` sh all.sh --notest
#eval `cat arm.dat gcc-4.0.2-glibc-2.3.6-tls.dat` sh all.sh --notest
#eval `cat arm.dat gcc-4.1.0-glibc-2.2.2.dat` sh all.sh --notest
#eval `cat arm.dat gcc-4.1.0-glibc-2.3.2.dat` sh all.sh --notest

#eval `cat arm.dat gcc-4.1.0-glibc-2.3.2-tls.dat` sh all.sh --notest #注释掉这行
eval `cat arm.dat gcc-4.0.2-glibc-2.3.6.dat` sh all.sh --notestt #添加此行

echo Done.

【3】修改 gcc-4.0.2-glibc-2.3.6.dat

1
2
3
4
5
BINUTILS_DIR=binutils-2.16.1  
GCC_DIR=gcc-4.0.2
GLIBC_DIR=glibc-2.3.6
LINUX_DIR=linux-2.6.26 (修改这里) LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.6
执行./demo-arm.sh

进行编译,等差不多一个小时就编译出交叉编译工具了,至此呢,编译工具就弄到手了。

值得注意:交叉编译工具对版本的要求很严格,各个版本之间的兼容性较差,所以尽可能都下载到上述对应版本的工具包。

定制最小内核

准备

第一步 得到默认的内核配置

拷贝6410光盘文件A下Linux文件夹中的linux-2.6.28.6-20111212.tar.gz到虚拟机中,并解压。

进入解压后的目录,执行命令

1
mv config_mini6410_h43 .config

此命令会使用已经配置好的供h43屏幕的开发板使用

第二步 找到交叉编译环境

在Terminal中执行cd命令回到你的主目录,编辑你的个人脚本配置:

1
gedit .bashrc

在最后面加上这两行:

1
2
export PRE=/home/qiuyongchen/crosstool/gcc-4.0.2-glibc-2.3.6/arm-linux/bin
export PATH=$PRE:$PATH

(保存该文件,关闭Terminal,重开一个Terminal,输入arm-再点击tab键,此时系统会弹出类似arm-linux-gcc之类的选项,这证明系统已经可以找到交叉编译器)

这是为了让你在下一步执行make命令时,系统能找到交叉编译器。

开始编译

执行make命令,如果没有错的话,应该会报错:

1
invalid option `abi=aapcs-linux'

之所以会出错,是因为配置内核时使用了OABI的选项,你需要去掉它:
执行make menuconfig打开内核配置的界面,找到Kernel Features ---->Use the ARM EABIto compile the kernel选项,不选该项。

修改一遍再执行make命令,你就可以看到编译的过程了(一行行命令快速地刷过去)。

到了这里,我们就可以正常地编译内核了,但上头的要求是:尽可能地小,所以我们需要特殊地定制一个内核。

定制的详细过程

模板

定制前,我使用了源码包中针对h43屏幕已经调好的配置(config_mini6410_h43),在它的基础上进行修改。

在修改之前,我使用make zImage命令编译一个可以用的内核,发现其大小为3M,我的目标是删减到2M:
![][6]

开始定制

执行make menuconfig进入图形化配置界面

【1】 General setup
在此选项下,我去除了Automatically append version information to the version string,其余的保留

【2】Enable loadable module support
只选择Module unloading,以便后面以模块形式加载卸载。

【3】System Type
ARM system type下选择Samsung S3C64XX,其余也保留不变

【4】Bus support / Kernel Features
均保持不变

【5】Floating point emulation
去掉NWFPE math emulationVFP-format floating point maths选项。后面可能要播放视频需要用到浮点数运算,这里先不管。

【6】Networking suppot
直接去掉这个大选项,毕竟是不用联网的

【7】Device Drivers
这个有点麻烦,我全部去掉了SCSI device support下的全部支持,不需要与外部设备链接。
而在Input device support下,我去掉了Event interface与Touchscreens的支持,不需要事件也不需要触摸屏。
Character devices下,我去掉了模块示例和Buzzer的驱动。
去掉
USB supportMMC/SD/SDIO card support**。

其余的暂且不变(包括文件系统的配置)

定制结果

重新编译生成zImage,我发现其大小为2M,符合预期目标:
![][7]

至此呢,您就得到了一个大小约为2M的内核zImage文件,可以进一步处理烧写进开发板了。

定制最小文件系统

编译BusyBox

准备

将busybox-1.14.2.tar.gz复制到虚拟机中,解压。

这里会遇到一些权限不足的问题cannot mknod operation not permitted,解决方法:在命令行中输入su,然后输入root密码,进入超级管理员权限,之后再进行解压。

在安装包中已经有别人编译好的文件,所以先执行make clean清除掉。

调整busybox配置

执行make menuconfig进入编译前的配置。

进入busybox setting -> Build Options -> prefix,修改编译的前缀为**/home/qiuyongchen/crosstool/gcc-4.0.2-glibc-2.3.6/arm-linux/bin/arm-linux-**,如下图:
![][8]

第一次编译

先退出配置界面,执行make命令,尝试编译一遍(先不管定制),可以编译!

完了之后,执行make install

在子目录_instll下面会生成3个目录bin/sbin/linuxsrc,进入各个目录,我发现虽然有很多链接,实际上只有一个busybox文件,大小为1M

建立文件系统

建立基本框架

在_install 下建立etc 目录;
在此etc 下分别建立rc,inittab,motd 三个文件;
进入刚新建的etc,在其下用”vi rc”命令建立rc 文件:

1
2
3
#!/bin/sh
mount -t proc proc /proc
cat /etc/motd

保存后退出,用chmod 命令改变rc 文件属性 :

1
[root@localhost etc]$chmod 755 rc

在etc 下新建一个inittab 文件,内容如下 :

1
2
3
4
5
6
7
8
9
10
11
# /etc/inittab init(8) configuration for BusyBox
#
# Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
#
#
::sysinit:/etc/rc.d/rcS
::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a

继续在etc 下建立motd 文件,其内容随意。

在etc 下建立init.d 目录,而后在init.d 目录下建立rc 文件的符号连接文件rcS:

1
[root@localhost init.d]$ ln -s ../rc rcS

在_install 下建立dev 目录,创建设备文件:

1
2
#mknod console c 5 1
#mknod mdblock3 b 31 3

至此呢,基本的框架就有了,也就是上头所需的最小文件系统了:
![][9]

封装基本框架

我使用了光盘中的mkubimage-mlc2工具(光盘A的linux目录下有个mktools-20110720.tar.gz文件,内部有该打包软件)

【1】安装mkubimage-mlc2
先解压mktools-20110720.tar.gz,用如下命令:

1
tar -vxzf mktools-20110720.tar.gz -C /

上述命令将所有的打包软件全部解压到/usr/sbin/目录

【2】打包busybox
进入busybox目录,执行命令:

1
/usr/sbin/mkubimage-mlc2 _install rootfs_my.ubi

执行完后就得到了rootfs_my.ubi文件系统镜像,利用上课时说的方法将它放到SD卡中就能刷进开发板了。

执行上述命令时系统会报错:mkubimage-mlc2: error while loading shared libraries: liblzo2.so.2: cannot open shared object file: No such file or directory

原因是缺少了liblzo2.so.2,用yum安装上即可(先执行su进入root)

1
2
yum update(fedora太老,必须先更新软件库的列表)
yum install liblzo2.so.2

![][10]

至此,我们就得到了一个“最小文件系统”。先烧入开发板看一下
烧录配置:
![][11]

刚烧录进去时,没有任何响应,需要配置内核,让内核支持ubi格式才行:

1
2
3
4
5
Device Drivers   --->
Memory Technology Device(MTD) support --->
UBI - Unsorted block images --->
<*> Enable UBI
<*> MTD devices emulation driver(gluebi)(NEW)

配置mtd支持UBI接口

1
2
3
File systems   --->
Miscellaneous filesystems --->
<*> UBIFS file system support

开机效果图:![][12]
是可以开机的。

按键驱动

加入视频播放器