目录
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 制作补丁
2. 启动文件系统、裁剪内核与制作补丁
通过移植linux-3.4.2到JZ2440(上:uboot如何启动内核与创建单板)的配置,该内核已经可以去启动文件系统了。
2.1 启动文件系统
下面开始让内核启动构建根文件系统里制作的文件系统fs_mini.jffs2与fs_mini.yaffs2。
2.1.1 启动jffs2文件系统
2.1.1.1 烧写启动fs_mini.jffs2
使用uboot烧写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-3.4.2/
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-3.4.2 (将yaffs2文件系统补丁打到内核里)
下面再配置内核支持yaffs2,操作如下:
cd /work/tools/linux-3.4.2/
make menuconfig
进行如下选项:
File systems --->
[*] Miscellaneous filesystems --->
<*> yaffs2 file system support
保存退出后重新编译内核,发现有许多如下错误:
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_mtd_put_super':
fs/yaffs2/yaffs_vfs.c:2514: error: 'struct mtd_info' has no member named 'sync'
fs/yaffs2/yaffs_vfs.c:2515: error: 'struct mtd_info' has no member named 'sync'
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_internal_read_super':
fs/yaffs2/yaffs_vfs.c:2702: error: 'struct mtd_info' has no member named 'erase'
fs/yaffs2/yaffs_vfs.c:2703: error: 'struct mtd_info' has no member named 'read'
fs/yaffs2/yaffs_vfs.c:2704: error: 'struct mtd_info' has no member named 'write'
提示使用的mtd_info结构体没有定义一些成员,查找linux-3.4.2内核源码,发现mtd_info结构体定义如下(linux-3.4.2/include/linux/mtd/mtd.h文件中 ):
struct mtd_info {
... ...
int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, void **virt, resource_size_t *phys);
int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
unsigned long (*_get_unmapped_area) (struct mtd_info *mtd,
unsigned long len,
unsigned long offset,
unsigned long flags);
int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf);
int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf);
int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf);
int (*_read_oob) (struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops);
int (*_write_oob) (struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops);
int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
size_t len);
int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
size_t len, size_t *retlen, u_char *buf);
int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
size_t len);
int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
size_t len, size_t *retlen, u_char *buf);
int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
size_t len, size_t *retlen, u_char *buf);
int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
size_t len);
int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen);
void (*_sync) (struct mtd_info *mtd);
int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
... ...
}
可以看到操作函数名都带了“-”前缀,与新打的yaffs文件系统补丁后生成的linux-3.4.2/fs/yaffs2/yaffs_vfs.c文件里调用的函数名不同(由于使用的yaffs源码版本较高),所以报错,所以将该文件内的报错函数名都加上“-”前缀,再重新编译内核,输出如下:
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_internal_read_super':
fs/yaffs2/yaffs_vfs.c:2967: error: implicit declaration of function 'd_alloc_root'
fs/yaffs2/yaffs_vfs.c:2967: warning: assignment makes pointer from integer without a cast
make[2]: *** [fs/yaffs2/yaffs_vfs.o] Error 1
make[1]: *** [fs/yaffs2] Error 2
make: *** [fs] Error 2
提示yaffs_vfs.c文件使用了没有声明的函数d_alloc_root,找到该文件2967行如下代码:
在内核源码中搜索“s_root”,发现其他文件使用的是d_make_root函数,所以使用该函数替换d_alloc_root,再重新编译内核,输出如下:
fs/yaffs2/yaffs_mtdif.c: In function 'nandmtd_erase_block':
fs/yaffs2/yaffs_mtdif.c:42: error: 'struct mtd_info' has no member named 'erase'
make[2]: *** [fs/yaffs2/yaffs_mtdif.o] Error 1
make[1]: *** [fs/yaffs2] Error 2
make: *** [fs] Error 2
同理修改fs/yaffs2/yaffs_mtdif.c文件mtd_info结构体成员加上“-”前缀,重新编译内核,发现在fs/yaffs2/yaffs_mtdif1.c文件与fs/yaffs2/yaffs_mtdif2.c文件都有使用新的mtd_info结构体,同样修改报错变量加上“-”前缀,重新编译内核成功。
2.1.2.2 烧写启动fs_mini.yaffs2
使用uboot烧写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 裁剪内核
由于之前划分的MTD里的kernel分区只有2M空间,此时我们的内核有2.35MB,所以需要对内核裁剪到小于2MB大小(当然也可以直接修改MTD分区)。查看linux-3.4.2/.config文件,执行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
< > Ext3 journalling file system 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 --->
< > SCSI device support
Input device support --->
[ ] Provide legacy /dev/psaux device
[ ] 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 --->
< > Support for Silicon Motion SM501
< > Support for NXP PCF50633
[*] USB support --->
[ ] USB device filesystem (DEPRECATED)
[ ] The shared table of common (or usual) storage devices
< > USB Serial Converter support --->
重新编译内核如下:
可以看到内核已经裁剪到小于2MB大小了,可以直接将uImage直接烧写到NAND Flash里的kernel分区去,在uboot命令行输入如下命令:
tftp 30000000 uImage (下载内核到30000000地址)
nand erase.part kernel (擦除kernel分区)
nand write 30000000 kernel (将内核写入kernel分区)
2.3 制作补丁
在linux-3.4.2根目录执行如下命令:
cp .config config_ok (保存内核配置文件)
make distclean
cd ..
mv linux-3.4.2 linux-3.4.2_jz2440
tar xjf linux-3.4.2.tar.bz2
diff -urN linux-3.4.2 linux-3.4.2_jz2440 > linux-3.4.2_jz2440.patch
这样就制作好了linux-3.4.2内核的补丁文件linux-3.4.2_jz2440.patch,使用补丁方法如下:
1. 获取linux-3.4.2源码并解压
2. 将linux-3.4.2_jz2440.patch与linux-3.4.2放在同一个目录
3. 进入linux-3.4.2根目录执行“patch -p1 < ../linux-3.4.2_jz2440.patch”
4. 将config_ok另存为配置文件.config,执行“cp config_ok .config”
5. 执行“make uImage”编译生成uImage