一、准备编译环境和工具
系统:ubuntu16.04
源码:https://busybox.net/下载最新busybox-1.29.3.tar.bz2
二、制作根文件系统
1、解压 tar -xjf busybox-1.29.3.tar.bz2
2、make menuconfig, 这里我使用静态库的方式编译
Settings ===>Build Options ====>Build Busybox as a static binary(no shared libs)编为静态库
3、安装
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- CONFIG_PREFIX=$PWD/../tmp install
安装到指定目录位置,这里装到tmp目录底下,将出现bin sbin usr 目录和linuxrc文件
4、配置
创建etc lib proc tmp dev home mnt root sys
进入etc/目录:
创建inittab文件
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
创建fstab文件
#device mount-point type option 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文件
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
mount -a
echo /sbin/mdev>/proc/sys/kernel/hotplug
mdev -s
添加库文件
查找交叉编译工具中库文件位置,我的如下:
sudo cp /usr/lib/gcc-cross/arm-linux-gnueabi/5/*so* ./ -d 拷贝到文件系统lib目录
在dev中创建console 和null节点
sudo mknod console c 5 1
sudo mknod null c 1 3
创建mdev.conf
vim mdev.conf 。mdev是一个udev的简化版本,主要用来支持一些热插拔设备。我们可以通过文件mdev.conf自定义一些设备节点的名称或链接来满足特定的需要,但在此处让它为空。
5、制作yaffs2
获得源码
git clone git://www.aleph1.co.uk/yaffs2
进入utils目录,cd /home/flnet/kernel/yaffs2/yaffs2/utils make获得制作工具
将工具拷贝到设置好的环境变量中
sudo cp ./mkyaffs2image /usr/bin/
sudo cp ./mkyaffsimage /usr/bin/
制作根文件系统 mkyaffs2image tmp/ myyaffs.yaffs2
五、内核支持yaffs2文件系统
cd /home/flnet/kernel/yaffs2/yaffs2/
./patch-ker.sh c m linux-tree 比如 ./patch-ker.sh c m /home/flnet/kernel/linux-4.19.8
进入内核目录:make menuconfig 选择支持yaffs2
File systems ==>Miscellaneous filesystems (MISC_FILESYSTEMS [=y]) ==> yaffs2 file system support
make uImage
fs/yaffs2/yaffs_vfs.c: In function ‘yaffs_mknod’:
fs/yaffs2/yaffs_vfs.c:266:38: error: ‘CURRENT_TIME’ undeclared (first use in this function)
(dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
.
.
.
fs/yaffs2/yaffs_vfs.c:2203:8: error: ‘struct timer_list’ has no member named ‘data’
timer.data = (unsigned long)current;
^
fs/yaffs2/yaffs_vfs.c:2204:18: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
timer.function = yaffs_background_waker;
主要是由于yaffs2没有跟上内核的更新速度导致的。根据错误提示,查看内核修改相应函数即可。
diff -urN linux-4.19.8/fs/yaffs2/yportenv.h my_linux/fs/yaffs2/yportenv.h
--- linux-4.19.8/fs/yaffs2/yportenv.h 1969-12-31 16:00:00.000000000 -0800
+++ my_linux/fs/yaffs2/yportenv.h 2018-12-16 17:29:11.070568330 -0800
+extern struct timespec64 current_yaffs2_time(void);
+#define CURRENT_TIME (current_yaffs2_time())
diff -urN linux-4.19.8/fs/yaffs2/yaffs_vfs.c my_linux/fs/yaffs2/yaffs_vfs.c
--- linux-4.19.8/fs/yaffs2/yaffs_vfs.c 1969-12-31 16:00:00.000000000 -0800
+++ my_linux/fs/yaffs2/yaffs_vfs.c 2018-12-16 17:29:11.070568330 -0800
+struct timespec64 current_yaffs2_time(void)
+{
+ struct timespec ts;
+ struct timespec64 ret;
+ ts = current_kernel_time();
+
+ ret.tv_sec = ts.tv_sec;
+ ret.tv_nsec = ts.tv_nsec;
+ return ret;
+}
+
+unsigned long unknown_data;//ͭݓdataԉԱҤ
+
+void yaffs_background_waker(struct timer_list *data)
+{
+ wake_up_process((struct task_struct *)(unknown_data));
+}
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
+ Y_INIT_TIMER(&timer);
+ timer.expires = expires + 1;
+ timer.data = (unsigned long)current;
+ timer.function = yaffs_background_waker;
+#else
+ unknown_data = (unsigned long)current;
+ timer.expires = expires + 1;
+ timer_setup(&timer,yaffs_background_waker, 0);
+#endif
解决了这些错误,再次make uImage,通过。
三、调试
烧写文件系统:
nfs 30000000 192.168.1.120:/home/flnet/kernel/new_file/static_yaffs.yaffs2;nand erase.part rootfs;nand write.yaffs 30000000 460000 $filesize
设置uboot参数,这里采用韦东山写好的最新uboot
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=yaffs2 user_debug=1
启动内核:
nfs 30000000 192.168.1.120:/home/flnet/kernel/new_file/uImage;bootm 30000000
Run /sbin/init as init process
Run /etc/init as init process
Run /bin/init as init process
Run /bin/sh as init process
Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance.
CPU: 0 PID: 1 Comm: swapper Not tainted 4.19.8 #2
Hardware name: SMDK2440
[<c01100a4>] (unwind_backtrace) from [<c010dc44>] (show_stack+0x10/0x18)
[<c010dc44>] (show_stack) from [<c06254cc>] (dump_stack+0x18/0x24)
[<c06254cc>] (dump_stack) from [<c011985c>] (panic+0xc0/0x248)
[<c011985c>] (panic) from [<c063a800>] (kernel_init+0xcc/0xf4)
[<c063a800>] (kernel_init) from [<c01090e0>] (ret_from_fork+0x14/0x34)
Exception stack(0xc381ffb0 to 0xc381fff8)
ffa0: 00000000 00000000 00000000 00000000
ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ffe0: 00000000 00000000 00000000 00000000 00000013 00000000
---[ end Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance. ]---
random: crng init done
1、这里是由于yaffs2工具对于nand flash 支持的不好,修改yaffs2。我这里直接使用前辈们留下的工具。
https://download.csdn.net/download/ggxyx123/10855885
2、制作根文件系统 mkyaffs2image tmp/ myyaffs.yaffs2,烧写。
This architecture does not have kernel memory protection.
Run /sbin/init as init process
init (1): undefined instruction: pc=(ptrval)
CPU: 0 PID: 1 Comm: init Not tainted 4.19.8 #3
Hardware name: SMDK2440
PC is at 0x11af88
LR is at 0x226318
pc : [<0011af88>] lr : [<00226318>] psr: 20000010
sp : beda0dc8 ip : 00000001 fp : 00000000
r10: 00000000 r9 : 00000000 r8 : 00000000
r7 : 00000000 r6 : 00000000 r5 : 0011b664 r4 : 00000000
r3 : 00010034 r2 : 00010000 r1 : ffffffff r0 : beda0fd0
Flags: nzCv IRQs on FIQs on Mode USER_32 ISA ARM Segment user
Control: c000717f Table: 332bc000 DAC: 00000055
Code: e59f32b8 e59f22b8 e5933000 e3520000 (e16f3f13)
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
CPU: 0 PID: 1 Comm: init Not tainted 4.19.8 #3
Hardware name: SMDK2440
[<c0111660>] (unwind_backtrace) from [<c010e2e4>] (show_stack+0x10/0x18)
[<c010e2e4>] (show_stack) from [<c062760c>] (dump_stack+0x18/0x24)
[<c062760c>] (dump_stack) from [<c011ae1c>] (panic+0xc0/0x248)
[<c011ae1c>] (panic) from [<c011c654>] (do_exit+0x974/0x9cc)
[<c011c654>] (do_exit) from [<c011d2d4>] (do_group_exit+0x3c/0xb4)
[<c011d2d4>] (do_group_exit) from [<c0126d08>] (get_signal+0x198/0x4f0)
[<c0126d08>] (get_signal) from [<c010d8fc>] (do_signal+0x258/0x488)
[<c010d8fc>] (do_signal) from [<c010dd10>] (do_work_pending+0xcc/0xe8)
[<c010dd10>] (do_work_pending) from [<c0109068>] (slow_work_pending+0xc/0x20)
Exception stack(0xc381ffb0 to 0xc381fff8)
ffa0: beda0fd0 ffffffff 00010000 00010034
ffc0: 00000000 0011b664 00000000 00000000 00000000 00000000 00000000 00000000
ffe0: 00000001 beda0dc8 00226318 0011af88 20000010 ffffffff
到这里,已经表明文件系统挂载成功,分析错误原因:
1)、通过命令arm-linux-objdump -D -S busybox > tmp
111868: 1a0000f4 bne 0x111c40
11186c: e59d3020 ldr r3, [sp, #32]
111870: e3a06000 mov r6, #0
111874: e16f3f13 clz r3, r3
111878: e1a032a3 lsr r3, r3, #5
11187c: e1a07003 mov r7, r3
2)发现clz 指令出错
http://blog.chinaunix.net/uid-25756789-id-3420210.html //特别感谢作者
s3c2440这款芯片 相对来说,太陈旧了。我使用的arm交叉编译器已经不支持(S3C2440) 的armv4t 指令
重新安装arm-linux-gcc,4.4.3 ,重新编译编译busybox。
编译会报错,参考https://blog.csdn.net/tanjialiang_/article/details/79490653 即可解决
yaffs: dev is 32505859 name is "mtdblock3" rw
yaffs: passed flags ""
VFS: Mounted root (yaffs2 filesystem) on device 31:3.
Freeing unused kernel memory: 204K
This architecture does not have kernel memory protection.
Run /sbin/init as init process
Please press Enter to activate this console.