十一、移植linux-4.15内核到JZ2440

11. 移植linux-4.15内核到JZ2440

11. 1 实验环境

开发板: JZ2440开发板
u-boot : u-boot-2016.03      编译器: arm-linux-gcc-4.3.2
busybox: busybox-1.20.0     编译器: arm-linux-gcc-4.3.2
linux: linux-4.15             编译器: arm-linux-gnueabi-gcc-4.9.4
注:对于为什么使用不同的两个不同的编译器,因为使用uboot使用 arm-linux-gnueabi-gcc-4.9.4 编译出来的u-boot.bin烧写到开发板不能启动,arm-linux-gcc-4.3.2 编译linux-4.15会出错, arm-linux-gnueabi-gcc-4.9.4 编译出来的busybox在内核启动时出现错误:Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b。

11.2 获取源码

(1) busybox-1.20.0源码的下载地址:https://busybox.net/downloads/
(2) linux-4.15 源码的下载地址:https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.15.tar.gz

11.3 linux-4.15内核移植

(1) 把从官网下载的linux-4.15.tar.gz内核源码拷贝到Ubuntu服务器解压内核:

tar xzf linux-4.15.tar.gz

(2) 进入linux-4.15目录,并修改顶层目录Makefile指定CPU架构和交叉编译器,把

ARCH       ?= $(SUBARCH)
CROSS_COMPILE  ?= $(CONFIG_CROSS_COMPILE:"%"=%)

修改为:

ARCH          ?= arm
CROSS_COMPILE ?= arm-linux-gnueabi-

(3) 配置linux-4.15内核,编译:

make s3c2410_defconfig
make menuconfig
make uImage -j4   

注:make menuconfig 是需要选择使用EABI接口,依次选择:
Kernel Features —>
[*] Use the ARM EABI to compile the kernel

如下图所示:
在这里插入图片描述
编译之后把uImage烧写到开发板,启动内核,移植卡在 Starting kernel …

(4) 根据之前移植linux-3.4.2的经验,应该是串口波特率的问题,需要修改晶振频率:把arch/arm/mach-s3c24xx/mach-smdk2440.c的167行:

s3c24xx_init_clocks(16934400);

修改为:

s3c2440_init_clocks(12000000);

同时需要修改uboot的环境变量:(设置ID,修改启动参数)

setenv machid 16a     // smdk2440 mach-smdk2440.c
setenv bootargs console=ttySAC0,115200 root=dev/mtdblock3

(5) 修改mtd 分区:在arch/arm/mach-s3c24xx/common-smdk.c有如下代码:

/* NAND parititon from 2.4.18-swl5 */

static struct mtd_partition smdk_default_nand_part[] = {
    
    
    [0] = {
    
    
        .name   = "Boot Agent",
        .size   = SZ_16K,
        .offset = 0,
    },
    [1] = {
    
    
        .name   = "S3C2410 flash partition 1",
        .offset = 0,
        .size   = SZ_2M,
    },
    [2] = {
    
    
        .name   = "S3C2410 flash partition 2",
        .offset = SZ_4M,
        .size   = SZ_4M,
    },
    [3] = {
    
    
        .name   = "S3C2410 flash partition 3",
        .offset = SZ_8M,
        .size   = SZ_2M,
    },
    [4] = {
    
    
        .name   = "S3C2410 flash partition 4",
        .offset = SZ_1M * 10,
        .size   = SZ_4M,
    },
    [5] = {
    
    
        .name   = "S3C2410 flash partition 5",
        .offset = SZ_1M * 14,
        .size   = SZ_1M * 10,
    },
    [6] = {
    
    
        .name   = "S3C2410 flash partition 6",
        .offset = SZ_1M * 24,
        .size   = SZ_1M * 24,
    },
    [7] = {
    
    
        .name   = "S3C2410 flash partition 7",
        .offset = SZ_1M * 48,
        .size   = MTDPART_SIZ_FULL,
    }
};

修改为:

/* NAND parititon from 2.4.18-swl5 */

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

上面的mtd分区要跟uboot的mtdparts相对应,由于新的kernel比较大,原先的2M不够,故这里修改为4M;同时也要把uboot的mtd分区的kernel分区修改为4M (在include/configs/jz2440.h里修改)
(6) 重新编译内核,烧写内核进行测试:
a. 设置uboot启动参数:

setenv bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2

b.首先我们把之前制作好的jffs文件系统烧写到开发板NAND Flash 的 rootfs分区,命令如下:

nfs 30000000 192.168.0.101:/home/book/works/first_fs/rootfs.jffs2 //使用nfs下载rootfs.jffs2文件系统到30000000地址
nand erase.part rootfs    //擦除rootfs分区
nand write.jffs2 30000000 rootfs $filesize //使用nand write.jffs2将30000000地址的大小为filesize的文件写到rootfs分区

c.烧写内核测试

nfs 32000000 192.168.0.101:/home/book/works/first_fs/uImage
bootm 32000000

内核启动成功,如下图所示,内核成功挂载了文件系统。
在这里插入图片描述

11.4 制作根文件系统

(1) 解压 busybox 源码:

tar xjf busybox-1.20.0.tar.bz2

(2) 配置 busybox,设置交叉编译器:

make menuconfig

出现下面的界面:
在这里插入图片描述
设置交叉编译器:
选择:
Busybox Settings —>
Build Options —>
Cross Compiler prefix (NEW)
然后会出现可以输入的横条,在里面输入我们的编译器的前缀:
在这里插入图片描述
配置好后,退出保存保存配置。
然后直接编译:make
编译完成后,把它安装到 rootfs ,新建目录:

mkdir rootfs

切换到busybox目录下进行安装:

make install CONFIG_PREFIX=../rootfs

安装完成后,rootfs目录下的文件如下图所示:
在这里插入图片描述
第一步已经完成,busybox已经安装好,下一步是安装库。
(3) 安装库
查看工具链的路径:echo $PATH
可知工具链的路径是:/work/tools/arm-linux-gcc-4.3.2/bin
进入/work/tools/arm-linux-gcc-4.3.2/目录:cd /work/tools/arm-linux-gcc-4.3.2/
输入:find -name lib
找到很多库如下:在这里插入图片描述
用到的库只有这两个:

./arm-none-linux-gnueabi/libc/armv4t/usr/lib
./arm-none-linux-gnueabi/libc/armv4t/lib

① 把/work/tools/arm-linux-gcc-4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib目录下的所有.so文件拷贝到rootfs/lib目录下:(注:rootfs目录下的lib目录需要新建)

cp /work/tools/arm-linux-gcc-4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib/*so*  /home/book/works/busybox/rootfs/lib -d (-d代表原来是链接文件,拷贝过来之后还是链接文件)

② 把/work/tools/arm-linux-gcc-4.3.2/arm-none-linux-gnueabi/libc/armv4t/usr/lib目录下的所有.so文件拷贝到rootfs/usr/lib目录:(注:usr 下的lib目录需要新建)

cp /work/tools/arm-linux-gcc-4.3.2/arm-none-linux-gnueabi/libc/armv4t/usr/lib/*so* /home/book/works/busybox/rootfs/usr/lib -d

(4) 构造etc目录
① 创建etc/inittab文件:在rootfs目录下创建etc目录,在etc目录下创建inittab文件,内容如下:

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

② 创建etc/init.d/rcS文件

#!/bin/sh
ifconfig eth0 192.168.0.200
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

同时为该文件添加可执行权限:chmod +x etc/init.d/rcS

③ 创建etc/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

(5) 构造dev目录
mdev是通过init进程来启动的,在使用mdev构造/dev目录之前,init进程至少要用到的设备文件为/dev/console和/dev/null,所以要建立这两个文件:

mkdir dev
cd dev
sudo mknod console c 5 1
sudo mknod null c 1 3

(6) 构建其他目录

mkdir proc mnt sys root tmp

(7) 制作jffs2映像文件:进入rootfs所在的目录,输入以下命令:

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

上面-n 表示不要在每个擦除块上都加上清除标志,-s 2048 表示我们的NAND Flash的一页的大小为2048字节,-e 128KiB 表示一个擦除快大小为128KiB ,-d 表示根文件系统的目录,-o表示输出的文件。
(8) 测试制作好的文件系统

 nfs 30000000 192.168.0.101:/home/book/works/busybox/rootfs.jffs2
 nand erase.part rootfs
 nand write.jffs2 30000000 rootfs $filesize
 setenv bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
 nfs 32000000 192.168.0.101:/home/book/works/first_fs/uImage
 bootm 32000000

启动内核后,打印信息如下,可见整个linux系统跑起来了。
在这里插入图片描述

11.5 修改内核代码支持YAFFS文件系统

(1) 获取yaffs源码
获取源码yaffs源码的方式有很多种,这里我是直接从Jz2440开发板光盘资料中获取的yaffs源码。把它拷贝到Ubuntu服务器下并解压。
(2) 给linux内核打补丁
进入到yaffs2源码目录,使用下面的命令进行打补丁:

./patch-ker.sh c m /home/book/works/linux-4.15 //后面这个是我的linux内核源码目录

打完补丁后,就会在内核的fs/yaffs2目录下加入了yaffs的源码
(3) 配置内核支持YAFFS
在linux源码顶层目录下输入:

make menuconfig

依次选择:

File systems  ---> 
     Miscellaneous filesystems  ---> 
        <*>   yaffs2 file system support 

然后保存配置,重新编译内核:

make uImage -j4

编译成功。
(4) 制作yaffs2文件系统系统映像
进入rootfs所在的目录,输入以下命令:

mkyaffs2image rootfs rootfs.yaffs2

(5) 测试制作好的文件系统

 nfs 30000000 192.168.0.101:/home/book/works/busybox/rootfs.yaffs2
 nand erase.part rootfs
 nand write.yaffs 30000000 rootfs $filesize  //烧写文件系统
 setenv bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=yaffs2
 nfs 32000000 192.168.0.101:/home/book/works/first_fs/uImage
 bootm 32000000

如下图所示,yaffs文件系统成功挂载,linux启动成功,整个系统运行正常。
在这里插入图片描述

11.6 制作内核补丁

进入内核的顶层目录:

cp .config config_ok
make distclean
/*退出内核目录,重命名*/
mv linux-4.15 linux-4.15_jz2440
tar xzf linux-4.15.tar.gz
diff -urN linux-4.15 linux-4.15_jz2440 > linux-4.15_jz2440.patch

进入linux-4.15顶层目录打补丁:

patch -p1 < ../linux-4.15_jz2440.patch
cp config_ok .config
make uImage

猜你喜欢

转载自blog.csdn.net/qq_35031421/article/details/104719737