S3C2440移植内核3.4

目录

 

一、内核框架介绍及简单修改

二、移植内核

修改分区并且制作根文件系统

修改内核支持yaffs文件系统

内核裁剪制作补丁

利用补丁直接使用新内核


一、内核框架介绍及简单修改

linux内核下载地址:https://www.kernel.org/,这里移植linux3.4.2版本,u-boot是bootloader最常用的一种,对于u-boot会先将内核拷贝到内存中,设置TAG参数,然后调用函数启动内核(函数的参数:R0=0 R1=机器ID R2=TAG参数地址),内核过程:

根据R1,判断能否支持该机器,调用机器相关的初始化函数
解析TAG参数
装载驱动程序(网卡、Flash等)
挂接根文件系统
启动应用程序

编译内核步骤

tar xjf linux-3.4.2.tar.bz2
在顶层makefile中修改ARCH
ARCH            ?= arm   //注意不能加空格 不然编译的时候会提示不认识
CROSS_COMPILE   ?= arm-linux-
配置文件在arch/arm/configs中其中有s3c2410_defconfig 
make s3c2410_defconfig   //会生成.config
make uImage

 建立一个source insight工程来查阅内核源码,建立步骤,过程如下

  1. 对于arch是各种CPU先整个去掉我们只关心里面的arm目录,在arm中boot至lib目录通用的就全部加进去(add tree),添加mach-s3c2410、2440、24xx;Mm到Oprofile目录看起来通用;还有plat-s3c24xx平台;plat-samsung;还有makefile
  2. 同步

首先在u-boot目录中bootm.c有以下语句,表示在启动参数中设置machid环境变量,内核首先会先判断该机器ID是否被内核支持,不然就会根据默认设置mach ID来启动内核

s = getenv("machid");

对于smdk2440,uboot的默认mach ID在smdk2410.c中,其宏定义为193

gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

这些机器ID在内核目录arch/arm中,首先设置环境变量机器ID为随机值,启动内核,内核提示支持的机器ID,其中包含有SMDK2440提示ID为16a,这里后续需要裁减内核,支持的多中机器会导致内核庞大,对于16a对应的文件为内核目录中mach-smdk2440.c,根据ID找到对应的结构体,然后调用里面的初始化函数,在u-boot设置机器ID为16a,同时设置波特率

set machid 16a   
bootargs=console=ttySAC0,115200 root=/dev/mtdblock3

用新内核启动发现依然乱码,最后原因是在内核根据机器ID调用各种初始化,其中时钟频率不对应,对于S3C2440,晶振是12M来说,修改arch\arm\mach-s3c24xx\mach-smdk2440.c

s3c24xx_init_clocks(16934400);
改为
s3c24xx_init_clocks(12000000);

二、移植内核

修改分区并且制作根文件系统

启动内核信息提示包含有八个分区,需要进一步修改代码,在内核源码中搜索grep "\"Boot\ Agent\""  * -nR(\:转义,用双引号和空格的本来含义),搜索到common-smdk.c,修改nand分区为之前u-boot分区好的大小u-boot分区好的大小参考移植新u-boot其中MTDPART_OFS_APPEND宏表示紧接着,MTDPART_SIZ_FULL宏表示剩下的

static struct mtd_partition smdk_default_nand_part[] = {
	[0] = {
		.name	= "bootloader",
		.size	= SZ_256K,
		.offset	= 0,
	},
	[1] = {
		.name	= "params",
		.offset = MTDPART_OFS_APPEND,
		.size	= SZ_128K,
	},
	[2] = {
		.name	= "kernel",
		.offset = MTDPART_OFS_APPEND,
		.size	= SZ_4M,
	},
	[3] = {
		.name	= "rootfs",
		.offset	= MTDPART_OFS_APPEND,
		.size	= MTDPART_SIZ_FULL,
	}
};

 用yaffs2文件系统进行挂接,在启动内核的信息中时候发现挂接失败,在配置文件.config中搜索YAFFS,发现没有支持yaffs,而搜索jffs2就有

nfs 30000000 192.168.0.106:/work/nfs_root/fs_mini_mdev.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 260000 $filesize //烧写的时候文件的大小会存放在filesize这个环境变量中对于之前的u-boot需要加上括号,新版u-boot不需要加括号
nfs 32000000 192.168.0.106:/work/nfs_root/uImage_new; bootm 32000000
----------------------------------------------------------------------------------------------------------------------
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,3)
Backtrace:

 因此我们尝试用jffs2文件系统来挂接,在内核启动信息中提示没有找到init进程,内核最终目的是去启动应用程序,对于内核启动后只会去启动t第一个应用程序,然后这个应用程序会根据配置文件来启动哪个应用程序

nfs 30000000 192.168.0.106:/work/nfs_root/fs_mini_mdev_new.jffs2; nand erase.part rootfs; nand write.jffs2 30000000 260000  $filesize
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
nfs 32000000 192.168.0.106:/work/nfs_root/uImage_new; bootm 32000000
-----------------------------------------------------------------------------------------
Kernel panic - not syncing: No init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.

自己来构建linux根文件系统

首先安装busybox-1.20.0,在README中解释了用CONFIG_PREFIX来指定安装目录

tar xjf busybox-1.20.0.tar.bz2
cd busybox-1.20.0/
make menuconfig
在编译选项中加上交叉编译的前缀:arm-linux-
Busybox Settings->Build Options->Cross compiler prefix   
使用默认的配置make

make install CONFIG_PREFIX=/work/nfs_root/fs_mini_mdev_new

添加C库,从gcc编译器中添加到fs_mini_mdev_new

book:/work/nfs_root/fs_mini_mdev_new$ mkdir lib
book:/work/nfs_root/fs_mini_mdev_new$ mkdir /work/nfs_root/fs_mini_mdev_new/usr/lib -p  //这里加上-p选项,usr/lib两个目录一起创建
book:/usr/local/arm/4.3.2$ cd /work/system/busybox-1.20.0/
book:/work/system/busybox-1.20.0$ echo $PATH
/home/book/bin:/home/book/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/arm/4.3.2/bin:/snap/bin
book:/work/system/busybox-1.20.0$ cd /usr/local/arm/4.3.2/bin
book:/usr/local/arm/4.3.2/bin$ cd ..
book:/usr/local/arm/4.3.2$ find -name lib
./lib
./arm-none-linux-gnueabi/libc/usr/lib
./arm-none-linux-gnueabi/libc/thumb2/usr/lib
./arm-none-linux-gnueabi/libc/thumb2/lib
./arm-none-linux-gnueabi/libc/lib
./arm-none-linux-gnueabi/libc/armv4t/usr/lib
./arm-none-linux-gnueabi/libc/armv4t/lib
./arm-none-linux-gnueabi/lib
book:/usr/local/arm/4.3.2$ cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib/*so*  /work/nfs_root/fs_mini_mdev_new/lib -d
book:/usr/local/arm/4.3.2$ cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/usr/lib/*so*  /work/nfs_root/fs_mini_mdev_new/usr/lib -d

添加etc目录,内核启动的第一个进程会先打开etc/inittab,根据inittab会执行/etc/init.d/rcS脚本,在rcS脚本中有句mount -a,会根据/etc/fstab的内容来挂接各种根文件系统,而mdev -s会自动创建dev中的内容

book@www.100ask.org:/work/nfs_root/fs_mini_mdev_new/etc$ cat inittab 

#/etc/inittab
console::askfirst:-/bin/sh
::sysinit:/etc/init.d/rcS
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r

book@www.100ask.org:/work/nfs_root/fs_mini_mdev_new/etc$ cat init.d/rcS 
#mount -t proc none /proc
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
if [ | -e /etc/pointercal ]
then
/bin/ts_cal.sh
fi
#/bin/qpe.sh &
book@www.100ask.org:/work/nfs_root/fs_mini_mdev_new/etc$ cat fstab 
#device   mount-point  type  options  dump  fsck  order
proc      /proc        proc  defaults  0    0  
sysfs     /sys         sysfs defaults  0    0
tmpfs     /dev         tmpfs defaults  0    0

创建dev目录,首先需要创建console和null节点,并且创建其他目录

book:/work/nfs_root/fs_mini_mdev_new/dev$ sudo mknod console c 5 1
book:/work/nfs_root/fs_mini_mdev_new/dev$ sudo mknod null c 1 3

book:/work/nfs_root/fs_mini_mdev_new$ mkdir proc tmp mnt sys root

制作为jffs文件系统

mkfs.jffs2 -n -s 2048 -e 128KiB -d fs_mini_mdev_new -o fs_mini_mdev_new.jffs2 

利用新的jffs文件系统,新的uImage启动,在内核信息中提示init进程被杀死

烧写:
nfs 30000000 192.168.0.106:/work/nfs_root/fs_mini_mdev_new.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 260000  $filesize
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2 
nfs 32000000 192.168.0.106:/work/nfs_root/uImage_new
bootm 32000000
-------------------------------------------------------------
内核启动信息
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004

 对于arm-linux-gcc的版本中支持eabi接口,对于内核需要配置支持eabi接口,在配置内核中搜索EABI,将其编译进入内核,利用新内核启动就没问题了

修改内核支持yaffs文件系统

yaffs比jffs2更适合nand flash,获得yaffs源码,在git上获得源码,如果没有git,需要先下载git

sudo apt-get install git
git clone git://www.aleph1.co.uk/yaffs2 

获得源码后README-linux中有介绍怎么打补丁

cd yaffs-dir
./patch-ker.sh  c m linux-tree

 在内核目录下打补丁

book:yaffs2$ ./patch-ker.sh c m /work/system/linux-3.4.2
Updating /work/system/linux-3.4.2/fs/Kconfig
Updating /work/system/linux-3.4.2/fs/Makefile

然后再内核中配置yaffs 

用mkyaffs2image工具制作之前制作的根文件系统为yaffs2格式的文件系统,在此之前还需要修改u-boot的bug,在u-boot目录drivers/mtd/nand/nand_util.c下修改为以下

518         if (!need_skip && !(flags & WITH_DROP_FFS) && !(flags & WITH_YAFFS_OOB)) {
519                 rval = nand_write (nand, offset, length, buffer);
520                 if (rval == 0)
521                         return 0;
522 

内核裁剪制作补丁

一开始有说到内核中有支持很多单板,我们可以根据配置文件.config,在配置内核总取消器编译进内核,还有其他功能的需求,看个人需要是否编译进内核

制作补丁,.config复制为config_ok

make distclean
mv linux-3.4.2 linux-3.4.2_100ask
tar xjf linux-3.4.2.tar.bz2

利用diff工具来生成补丁文件

diff -urN linux-3.4.2 linux-3.4.2_100ask > linux-3.4.2_100ask.patc

利用补丁直接使用新内核

patch -p1 < ../linux-3.4.2_100ask.patch 
cp config_ok .config
make uImage

制作了u-boot_new.bin, uImage_new, fs_mini_mdev_new.yaffs,重烧整个系统,使用jtag工具烧u-boot_new.bin或使用uboot来更新自己

tftp 30000000 u-boot_new.bin; nand erase.part u-boot; nand write 30000000 u-boot

启动uboot,用它来烧写内核、FS

tftp 30000000 uImage_new; nand erase.part kernel; nand write 30000000 kernel
tftp 30000000 fs_mini_mdev_new.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 260000  $filesize

设置参数

set 'nand read 30000000 kernel;bootm 30000000'
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 //可能出现挂接失败就加上rootfstype=yaffs
set machid 16a
save
boot

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值