高版本内核对于2440平台开发板支持已经相当到位,对于板级的设备已经完美支持无需修改,比如 Norflash nandflash 等等,对于 LCD 等“特殊”设备还需要移植。本文重点在于配置3.4.2内核使其支持 yaffs2 文件系统以及yaffs2 jffs2 文件系统的制作和注意事项。
开发板 :2440
编译器 :4.3.2 arm-linux-gcc-4.3.2.tar.bz2
内核 :linux3.4.2 linux-3.4.2.tar.bz2
busybox:busybox-1.22.1 busybox-1.22.1.tar.bz2
一 简单配置内核
1、修改makefile指定架构和编译器
2、查看默认配置 find -name "*defconfig"
3、make mini2440_defconfig
4、make uImage
二 使内核支持yaffs2文件系统
1 下载yaffs补丁
git clone git://www.aleph1.co.uk/yaffs2
2 打补丁
cd yaffs2
./patch-ker.sh c m linux-tree 比如 ./patch-ker.sh c m /work/system/linux-3.4.2
3 重新配置内核
make menuconfig
File Systems->
Miscellaneous filesystems->
<*>yaffs file system support
4 编译 make uImage
编译过程中出现大量错误,请参考:http://blog.csdn.net/flfihpv259/article/details/52102050
三 制作文件系统
1 挂载文件系统流程简单分析
static int __init init_setup(char *str)
{
unsigned int i;
execute_command = str;
/*
* In case LILO is going to boot us with default command line,
* it prepends "auto" before the whole cmdline which makes
* the shell think it should execute a script with such name.
* So we ignore all arguments entered _before_ init=... [MJ]
*/
for (i = 1; i < MAX_INIT_ARGS; i++)
argv_init[i] = NULL;
return 1;
}
__setup("init=", init_setup);
bootargs 传入的参数中含有 init=/linuxrc ,就会调用 init_setup("/linuxrc");execute_command = "execute_command";
static noinline int init_post(void)
__releases(kernel_lock)
{
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
free_initmem();
unlock_kernel();
mark_rodata_ro();
system_state = SYSTEM_RUNNING;
numa_default_policy();
// 内核打开的第一个设备是 /dev/console 所以文件系统里必须有它
if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
printk(KERN_WARNING "Warning: unable to open an initial console.\n");
// 将文件描述符0 赋值给文件描述符1、2,所以标准输入、输出、错误都对应用于 console
(void) sys_dup(0);
(void) sys_dup(0);
current->signal->flags |= SIGNAL_UNKILLABLE;
// 如果 bootargs 中有 rdinit= xxx 的话 会调用它 ,没有不执行
if (ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %s\n",
ramdisk_execute_command);
}
// 如果 bootargs 中有 init=xxx 的话,调用它,没有不执行
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
run_init_process("/sbin/init"); //启动第一个进程
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
panic("No init found. Try passing init= option to kernel.");
}
启动 init 进程后,如果存在/etc/initab busybox init程序会解析它,然后按照它的指示创建各种子进程,如果不存在,则使用默认的配置创建子进程。/etc/inittab 文件中的每一个条目用来定义一个子进程,并确定它的启动方法,格式如下:
---------------------------------------------------------------------------------------
<id>:<runlevels>:<action>:<process> 例如:ttySAC0::askfirst:-/bin/sh
<id> : 表示这个子进程要使用的控制台,如果省略则使用和init进程一样的控制台
<runlevels>: 对于 busybox init 程序,这个字段没有意义,可以省略
<action> : 表示 init 进程如何控制这个子进程,取值如下
sysinit : 系统启动后最先执行 ,只执行一次,init 进程等待它结束才继续执行其它动作
wait : 系统执行完sysinit进程后,只执行一次,init 进程等待它结束后才继续执行其它动作
once : 系统执行完 wait 进程后,只执行一次,init 进程不等待它结束
respawn : 启动完once 进程后,init 发现子进程退出时,重新启动它
shutdown : 当系统关机时,重启或关闭系统命令时
restart : busybox 配置了 CONFIG_FEATURE_USE_INITTAB ,并且init进程收到 SIGHUP时,先重新读取解析inittab文件,在执行 restart 程序
ctrlatdel : 按下 Ctr+ALT+DEL组合键时
<process> : 要执行的程序,它可以是可执行程序,也可以是脚本,如果<process>字段前有“-”字符,这个程序被称为“交互的”。
---------------------------------------------------------------------------------------
如果根文件系统中没有/etc/inittab文件,Busybox init 程序将使用如下默认的 inittab 条目
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restrt:/sbin/init
---------------------------------------------------------------------------------------
仿照/etc/inittab ,创建一个 自己的inittab 文件中
# /etc/inittab
# 启动脚本/etc/init.d/rcS
::sysinit:/etc/init.d/rcS
# 启动 shell
::askfirst:-/bin/sh
# 重启关机前 卸载文件系统
::ctrlatdel:/bin/umount -a -r
---------------------------------------------------------------------------------------
2 编译安装 busybox
2.1 配置
make menuconfig
Busybox Settings ->
general configuration ->
[*] don't use /usr//选中它 否则会破坏虚拟机
build options->
cross comliler prefix = arm-linux-//选择交叉编译工具
installtion options->
busybox installation prefix = /work/my_rootfs//指定安装路径
2.2 安装
make
make install
2.3 安装库文件
mkdir -p /home/work/hardware/my_rootfs/lib
mkdir -p /home/work/hardware/my_rootfs/usr/lib
cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib/*.so*
/home/work/hardware/my_rootfs/lib -d
cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/usr/lib/*.so*
/home/work/hardware/my_rootfs/usr/lib -d
2.4 创建 /etc/inittab
# 启动脚本/etc/init.d/rcS
::sysinit:/etc/init.d/rcS
# 启动 shell
::askfirst:-/bin/sh
# 重启关机前 卸载文件系统
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
2.5 创建 /etc/init.d/rcS
# 这是一个脚本文件,用/bin/sh解析
#!/bin/sh
# 挂载文件系统
mount -a
# 使用内存文件系统
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
# 设置IP
/sbin/ifconfig eth0 192.168.1.17
# 挂载 /etc/fstab 中的文件系统
mount -a
chmod +x rcS //设置 rcS可执行
2.6 创建/etc/fstab
---------------------------------------------------------------------------------------
# device mount-point type options dumpfsckorder
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
---------------------------------------------------------------------------------------
2.7 构建 /dev 目录
mknod console c 5 1
mknod null c 1 3
2.8 创建其它目录
mkdir proc mnt tmp sys root
四、制作 yaffs2 文件系统
4.1 制作 yaffs2 文件系统
4.1.1 制作工具
使用 yaffs_source_util_larger_small_page_nand.tar.bz2
tar jxvf yaffs_source_util_larger_small_page_nand.tar.bz2
cd Development_util_ok/yaffs2/utils
make
得到 mkyaffs2image mkyaffsimage
4.1.2 生成yaffs2文件系统
mkyaffs2image my_rootfs my_rootfs.yaffs2
五、制作 jffs2 文件系统
使用 mtd-utils-05.07.23.tar.bz2
5.1 安装 zlib
sudo apt-get install ruby
sudo apt-get install zlib1g-dev
5.2 安装工具
tar jxvf mtd-utils-05.07.23.tar.bz2
cd mtd-utils-05.07.23/util
make
sudo make install
5.3 生成jffs2文件系统
mkfs.jffs2 -n -s 2048 -e 128KiB -d my_rootfs -o my_rootfs.jffs2