内核的移植一般没有多少事情可做的,因为你选定一块开发板之后,厂家会给你一个能用的内核,至少能够跑起来的内核。
(1)
1.1 指定交叉编译器 ,一般把交叉编译器放在/usr/local/arm下,修改环境变量
1.2 修改Makefile
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
1.3 指定默认配置
默认的配置文件一般存放在arch/arm/configs/目录里面,指定默认配置文件用哪一个配置文件的命令是
make s3c2410_defconfig
如果要查看默认的配置选型,执行vi .config命令,.config就是默认的配置文件
注意:即使是同一块处理器,也会有多个不同的开发板,所以还需要在BootLoader里面配置支持对应开发板的机器ID,
1.4 现在就可以进行编译了 make uImage
内核在启动时需要支持的machine ID,一个uImage能支持一个或多个machine ID,如果设置uboot的machine ID错误,内核就会打印出该uImage所支持的所有的machine ID,每一个machine ID对应一个初始化硬件的文件,如果一块开发板的machine ID设置错误,则会启动不匹配的初始化硬件的代码,导致系统崩溃。
要点:如何确定machine ID与启动文件的对应关系?
16a mach-smdk2440.c 机器ID与对应启动文件
7cf mach-mini2440.c
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
grep "\"Agent\ Boot\"" * -nR "\"是转义作用,这儿表示搜索的字符串是"Agent Boot",这是带""的。
设置nandflash分区的信息在common-smdk.c里面,看文件名字应该是一个通用的文件。
结构体定义处一般都定义了一些宏,做为填充结构体成员之用。设置完成后会在内核启动时打印出分区信息,如下
Creating 4 MTD partitions on "NAND":
0x000000000000-0x000000040000 : "syl_bootloader"
0x000000040000-0x000000060000 : "syl_params"
0x000000060000-0x000000260000 : "syl_kernel"
0x000000260000-0x000010000000 : "syl_rootfs"
烧写文件系统 fs_mini_mdev.yaffs2
nfs 30000000 192.168.31.183:/work/nfs_root/fs_mini_mdev.yaffs2;
nand erase.part rootfs;
nand write.yaffs 30000000 260000 889bc0; (booloader 256K+parame 128K +root 2M = 260000)
也可以使用宏来代替文件大小,如
nand write.yaffs 30000000 260000 $filesize
nfs 32000000 192.168.31.183:/work/nfs_root/uImage;
文件系统烧写到nandflash后下载内核启动,系统崩溃,打印出下面一句话
No filesystem could mount root, tried: ext3 ext2 cramfs vfat msdos iso9660 romfs
表示无法挂载文件系统,并尝试了ext3 ext2 cramfs vfat msdos iso9660这几种文件系统,这表明我们的内核还不支持yaffs文件系统的挂载。
vi .config发现搜索不到yaffs字符串,但是可以搜索到jffs字符串,这就表明内核暂时只支持jffs文件系统,不支持yaffs文件系统。
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2;
2. 制作根文件系统
2.1
进入busybox目录 cd busybox-1.2.0/
make menuconfig
busybox Settings------>
Build Options-------->
[*]Do you want to build busybox with a Cross compiler?
选择这一项是指定交叉编译器,选择这一栏会进入输入交叉编译前缀,填写arm-linux-;
然后make,
2.2 安装bosybox到我们制作文件系统的文件夹下
可以查案README看看怎么安装,这里安装到指定文件夹下的命令是
make install CONFIG_PREFIX=/work/nfs_root/fs_mini_mdev_syl
该/work/nfs_root/fs_mini_mdev_syl目录下就生产了四个文件夹bin linuxrc sbin usr,用于存放命令的文件,
2.3 制作根文件系统还需要一些交叉编译工具链里面的库,因为用交叉编译器编译的应用程序需要这些库,所以要拷贝一些交叉编译器里的库文件,在我的项目里需要的库文件在
./arm-none-linux-gnueabi/libc/armv4t/lib
./arm-none-linux-gnueabi/libc/armv4t/usr/lib这两个目录里面,在其他跟文件系统制作时可以自己去试验,如果编译的可执行文件能够运行,则说明所需要的库放进去了,否则就没有放进去。
拷贝库文件
cp ./arm-none-linux-gnueabi/libc/armv4t/lib/*so* /work/nfs_root/fs_mini_mdev_syl/lib -d
cp ./arm-none-linux-gnueabi/libc/armv4t/usr/lib/*so* /work/nfs_root/fs_mini_mdev_syl/usr/lib -d
加上-d原来是链接文件的话也以链接文件的形式拷贝过去,否则会造成库非常的庞大。
2.4 这儿为了简单,直接把以前的根文件系统的/etc/目录拷贝进去/work/nfs_root/fs_mini_mdev_syl/。
我们的etc目录下有以下几个文件fstab init.d inittab,我们的内核会根据inittab里的内容去执行操作,
inittab的内容是
# /etc/inittab
::sysinit:/etc/init.d/rcS
s3c2410_serial0::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
要将s3c2410_serial0改为console,因为新内核里的串口的名字一般都是console。
由此可见,内核会启动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
其中mount -a的作用是根据fstab的内容去挂接各种根文件系统。我们查看一下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
内核执行完rcS后会启动shell,shell从哪里得到输入呢?s3c2410_serial0::askfirst:-/bin/sh,shell会从
s3c2410_serial0得到输入。
在rcS里面会执行mdev -s,实现我们的创建mdev里面的内容,首先我们都需要创建者这两个设备节点,
ls -l /dev/console /dev/null
crw------- 1 root root 5, 1 2017-03-01 21:04 /dev/console
crw-rw-rw- 1 root root 1, 3 2017-03-01 21:04 /dev/null
在dev目录里
sudo mknod console c 5 1
sudo mknod null c 1 3
2.5 创建其他的目录 mkdir proc tmp mnt sys root
2.6 制作映像文件命令
mkfs.jffs2 -n -s 2048 -e 128KiB -d fs_mini_mdev_syl -o fs_mini_mdev_syl.jffs2
-s 表示nandflsh扇区的大小,我们的是2048
-e 表示可擦除快的的大小
-d 表示目录制作根文件系统的目录
-o 表示输出文件
到此,我们制作根文件系统就完成了,制作的根文件系统名是fs_mini_mdev_syl.jffs2,现在就可以用来烧写了。
2.7 烧写jffs2文件系统
nfs 30000000 192.168.31.183:/work/nfs_root/fs_mini_mdev_syl.jffs2;
nand erase.part rootfs;
nand write.jffs2 30000000 260000 $filesize
启动系统,崩溃并打印如下内容,红色字体部分表示该文件系统已经挂载在nandflash设备上,但是却企图杀死init进程。
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
ALSA device list:
No soundcards found.
VFS: Mounted root (jffs2 filesystem) on device 31:3.
Freeing init memory: 172K
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
Backtrace:
[] (dump_backtrace+0x0/0x10c) from [] (dump_stack+0x18/0x1c)
r6:c3819d60 r5:c058eb14 r4:c058eb14
[] (dump_stack+0x0/0x1c) from [] (panic+0x7c/0x1d0)
[] (panic+0x0/0x1d0) from [] (do_exit+0x644/0x76c)
根据Attempted to kill init! exitcode=0x00000004这些打印信息,可以发现这是退出代码中定义的一种情况,退出值等于4,是属于SIGILL宏表示的,在Google查询该SIGILL,可以知道这是一种非法指令,这是由于交叉编译器使用的是eabi接口,如/arm-none-linux-gnueabi/bin,所以内核也要支持eabi接口。在make menuconfig里面搜素EABI,搜素的方法是按"/",可以看界面上的提示。
选上 -> Kernel Features
-->use the arm EABI to compile the kernel.就可以解决内核崩溃的问题。
至此,启动内核,发现内核可以正常启动了。