目录
2. 启动文件系统、裁剪内核与制作补丁
2.1 启动文件系统
2.1.1 启动jffs2文件系统
2.1.1.1 烧写启动fs_mini.jffs2
2.1.1.2 重新配置内核支持EABI
2.1.2 启动yaffs2文件系统
2.1.2.1 修改内核使支持yaffs2文件系统
2.1.2.2 烧写启动fs_mini.yaffs2
2.2 裁剪内核
2.3 修改MTD分区
2.3.1 修改内核分区
2.3.2 修改uboot分区
2.3.3 测试
2.4 制作补丁
2. 启动文件系统、裁剪内核与制作补丁
通过移植linux-4.12到JZ2440(上:uboot如何启动内核与创建单板)的配置,该内核已经可以去启动文件系统了。
2.1 启动文件系统
下面开始让内核启动构建根文件系统里制作的文件系统fs_mini.jffs2与fs_mini.yaffs2(与编译内核的编译器版本必须一样!)。
2.1.1 启动jffs2文件系统
2.1.1.1 烧写启动fs_mini.jffs2
使用之前制作的uboot-2016.11烧写fs_mini.jffs2到rootfs分区并启动,执行如下命令:
tftp 30000000 fs_mini.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 rootfs $(filesize)
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
save
tftp 30000000 uImage
bootm 30000000
内核启动后有如下输出:
在内核中搜索exitcode,找到0x00000004对应的宏定义是SIGILL,表示非法指令。这是因为本人使用的编译器arm-linux-gcc-4.4.3是EABI接口,内核由于未配置,所以出现非法。
2.1.1.2 重新配置内核支持EABI
配置内核支持EABI操作如下:
cd /work/tools/linux-4.12/
make menuconfig
输入"/"搜索"EABI"查找到该配置接口位置如下:
Kernel Features --->
Use the ARM EABI to compile the kernel (y选择)
重新make uImage编译内核,重新下载启动新内核(tftp 30000000 uImage;bootm 30000000)后文件系统运行成功,如下:
2.1.2 启动yaffs2文件系统
内核不支持yaffs2文件系统,需要我们去修改。
2.1.2.1 修改内核使支持yaffs2文件系统
首先从官网获取yaffs2源码:git clone git://www.aleph1.co.uk/yaffs2
在服务器解压后进入目录,执行如下命令为内核打补丁:
cd /work/tools/yaffs2/
sudo chmod +x patch-ker.sh
./patch-ker.sh c m /work/tools/linux-4.12 (将yaffs2文件系统补丁打到内核里)
打完补丁后在linux-4.12/fs/目录下就会生成yaffs2目录,该目录就有yaffs2文件系统相关文件,同时会更新linux-4.12/fs/目录下的Kconfig文件与Makefile文件。下面再配置内核支持yaffs2,操作如下:
cd /work/tools/linux-4.12/
make menuconfig
进行如下选项:
File systems --->
[*] Miscellaneous filesystems --->
<*> yaffs2 file system support
保存退出后重新编译内核,发现有许多如下错误:
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_mknod':
fs/yaffs2/yaffs_vfs.c:1399: error: 'CURRENT_TIME' undeclared (first use in this function)
fs/yaffs2/yaffs_vfs.c:1399: error: (Each undeclared identifier is reported only once
fs/yaffs2/yaffs_vfs.c:1399: error: for each function it appears in.)
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_link':
fs/yaffs2/yaffs_vfs.c:1525: error: 'CURRENT_TIME' undeclared (first use in this function)
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_symlink':
fs/yaffs2/yaffs_vfs.c:1562: error: 'CURRENT_TIME' undeclared (first use in this function)
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_rename':
fs/yaffs2/yaffs_vfs.c:1619: error: 'CURRENT_TIME' undeclared (first use in this function)
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_unlink':
fs/yaffs2/yaffs_vfs.c:1651: error: 'CURRENT_TIME' undeclared (first use in this function)
make[2]: *** [fs/yaffs2/yaffs_vfs.o] Error 1
make[1]: *** [fs/yaffs2] Error 2
make: *** [fs] Error 2
查看第一条错误,提示没有定义“CURRENT_TIME”,查看较早版本的内核源码例如linux-3.4.2,发现有如下定义(linux-3.4.2/include/linux/time.h文件中):
#define CURRENT_TIME (current_kernel_time())
linux-4.12版本的内核已经不使用宏CURRENT_TIME来代表current_kernel_time()函数了,但是本人使用的yaffs2源码版本较老,还有使用该宏的地方,在linux-4.12/fs/yaffs2中搜索哪些文件使用了宏CURRENT_TIME:
直接在linux-4.12/fs/yaffs2/yportenv.h文件中添加宏定义#define CURRENT_TIME (current_kernel_time())即可。此时重新编译内核,编译成功。
2.1.2.2 烧写启动fs_mini.yaffs2
使用之前制作的uboot-2016.11烧写fs_mini.yaffs2到rootfs分区并启动新内核,执行如下命令:
tftp 30000000 fs_mini.yaffs2
nand erase.part rootfs
nand write.yaffs2 30000000 rootfs $(filesize)
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=yaffs2
save
tftp 30000000 uImage
bootm 30000000
内核启动后有如下输出:
2.2 裁剪内核
此时我们的内核有3.2MB,执行make menuconfig命令去掉想要裁剪的内容:
System Type->
SAMSUNG S3C24XX SoCs Support->
[ ] SAMSUNG S3C2410
[ ] SAMSUNG S3C2412
[ ] SAMSUNG S3C2416/S3C2450
[ ] SAMSUNG S3 C2442
[ ] SAMSUNG S3C2443
[ ] Simtec Electronics ANUBIS
[ ] Avantech AT2440EVB development board
[ ] NexVision NEXCODER 2440 Light Board
[ ] Simtec IM2440D20 (OSIRIS) module
[ ] HP iPAQ rx3715
File systems --->
< > Second extended fs support
CD-ROM/DVD Filesystems --->
< > ISO 9660 CDROM file system support
DOS/FAT/NT Filesystems --->
< > MSDOS fs support
< > VFAT (Windows-95) fs support
[*] Miscellaneous filesystems --->
< > Compressed ROM file system support (cramfs)
[ ] Include support for ZLIB compressed file systems
< > ROM file system support
Device Drivers --->
SCSI device support --->
[ ] legacy /proc/scsi/ support
< > SCSI disk support
< > SCSI CDROM support
< > SCSI generic support
[ ] Verbose SCSI error reporting (kernel size += 36K)
[ ] Asynchronous SCSI scanning
[ ] SCSI low-level drivers ----
Input device support --->
< > Export input device LEDs in sysfs
[ ] Mice --->
[ ] Keyboards --->
[ ] Joysticks/Gamepads --->
[*] Touchscreens --->
<*> Samsung S3C2410/generic touchscreen input driver
< > USB Touchscreen Driver
<*> Sound card support --->
<*> Advanced Linux Sound Architecture --->
[ ] USB sound devices --->
Multifunction device drivers --->
< > NXP PCF50633
< > Support for Silicon Motion SM501
[*] USB support --->
< > USB Serial Converter support --->
保存退出后重新编译内核如下:
可以看到内核还是很大,超过了上一节1.3.5 修改MTD分区中设置的分区,可以继续裁剪或者直接修改分区。下面我直接修改分区。
2.3 修改MTD分区
2.3.1 修改内核分区
修改上一节1.3.5.2 修改分区的内容,也就是修改smdk_default_nand_part[]数组如下(arch/arm/mach-s3c24xx/common-smdk.c文件中):
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,
}
};
这里将内核kernel分区设置为4M大小。重新编译后tftp下载新内核启动:
tftp 30000000 uImage
bootm 30000000
分区修改成功。此时的uImage还不能下载到NAND Flash的kernel分区中,因为移植u-boot-2016.11到JZ2440里制作的uboot的分区kernel的大小为2M,后面紧跟文件系统,直接下载到kernel分区会破坏文件系统,所以下面修改移植u-boot-2016.11到JZ2440里制作的uboot的分区。
2.3.2 修改uboot分区
修改6.2.1 修改源码设置分区里设置的分区,也就是修改u-boot-2016.11/include/configs/jz2440.h如下部分内容:
/*
* mtdparts
*/
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define MTDIDS_DEFAULT "nand0=jz2440-0" /* 哪一个设备 */
#define MTDPARTS_DEFAULT "mtdparts=jz2440-0:256k(u-boot)," \
"128k(params)," \
"4m(kernel)," \
"-(rootfs)" \
也将分区设置为4M大小。
2.3.3 测试
重新编译uboot下载到开发板,启动新uboot输入nand erase.part params擦除以前设置的参数,重新设置:
set ipaddr 192.168.1.17
set ethaddr 00:0c:29:f2:9f:38
set serverip 192.168.1.12
set machid 16a
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=yaffs2
set bootcmd 'nand read 30000000 kernel;bootm 30000000'
save
重启后执行print如下:
新uboot的分区也已经修改成功,重新烧写fs_mini.yaffs2文件系统到到新rootfs分区:
tftp 30000000 fs_mini.yaffs2
nand erase.part rootfs
nand write.yaffs2 30000000 rootfs $(filesize)
然后将uImage直接烧写到NAND Flash里的kernel分区去,在uboot命令行输入如下命令:
tftp 30000000 uImage (下载内核到30000000地址)
nand erase.part kernel (擦除kernel分区)
nand write 30000000 kernel (将内核写入kernel分区)
重新启动如下:
2.4 制作补丁
在linux-4.12根目录执行如下命令:
cp .config config_ok (保存内核配置文件)
make distclean
cd ..
mv linux-4.12 linux-4.12_jz2440
tar xzf linux-4.12.tar.gz
diff -urN linux-4.12 linux-4.12_jz2440 > linux-4.12_jz2440.patch
这样就制作好了linux-4.12内核的补丁文件linux-4.12_jz2440.patch,下载地址:https://pan.baidu.com/s/1_uyLxOIgwVGCJPip5RcFNQ
使用补丁方法如下:
1. 获取linux-4.12源码并解压
2. 将linux-4.12_jz2440.patch与linux-4.12放在同一个目录
3. 进入linux-4.12根目录执行“patch -p1 < ../linux-4.12_jz2440.patch”
4. 将config_ok另存为配置文件.config,执行“cp config_ok .config”
5. 执行“make uImage”编译生成uImage