linux kernel移植
1.kernel源码地址:
https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.3.6.tar.xz
2.移植
1.修改linux-5.3\arch\arm\mach-s3c24xx\common-smdk.c文件:
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "uboot",
.size = SZ_512K,
.offset = 0,
},
[1] = {
.name = "env",
.size = SZ_512K,
.offset = SZ_512K,
},
[2] = {
.name = "dtb",
.size = SZ_1M,
.offset = SZ_1M,
},
[3] = {
.name = "Linux Kernel",
.offset = SZ_2M,
.size = SZ_4M,
},
[4] = {
.name = "Root File System",
.offset = SZ_1M * 6,
.size = SZ_1M*32,
},
[5] = {
.name = "User Space",
.offset = SZ_1M * 38,
.size = MTDPART_SIZ_FULL,
}
2.修改makefile,添加ARM工具链
ARCH ?= arm
CROSS_COMPILE ?=/home/jiujun.di/arm2410/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-
3.编译SMDK2410
make smdk2410_defconfig
make menuconfig
make
kernel 移植中出现的问题
1.memory allocation error while creating partitions for “NAND”
Creating 6 MTD partitions on "NAND":
0x000000000000-0x000000080000 : "uboot"
0x000000080000-0x000000100000 : "env"
0x000000200000-0x000000a00000 : "Linux Kernel"
0x000000a00000-0x000001000000 : "Root File System"
memory allocation error while creating partitions for "NAND"
这是由于当时修改mtd partition的时候数组标号写错,改过来就正常了
2.Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
CPU: 0 PID: 1 Comm: swapper Not tainted 5.3.0 #4
Hardware name: SMDK2410
因为对应nand分区上没有rootfs文件,下面就进行rootfs的移植
3.uboot中加入 bootargs 环境变量后,kernel启动不了
跟写入的bootargs格式有关,仔细检查修改后解决。
Rootfs移植
下载busybox源码
https://busybox.net/downloads/busybox-1.31.0.tar.bz2
修改Makefile添加工具链并编译
工具链:toolchain/4.4.3/bin/arm-linux-
make 编译问题:
- nsenter.c:(.text.nsenter_main+0x1b0): undefined reference to `setns’
solution:
make menuconfig Linux System Utilities—>nsenter,去掉该选项,
2.sync.c:(.text.sync_main+0x7c): undefined reference to `syncfs’
solution:
make menuconfig
Coreutils—>sync选项去掉,重新make编译通过,生成了busybox可执行文件
制作rootfs
移植中问题
1.用mkyaffs2img 制作了rootfs并烧写到nand上,但linux还是报错
No filesystem could mount root, tried:
ext3
random: fast init done
ext4
ext2
cramfs
vfat
msdos
iso9660
romfs
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,4)
CPU: 0 PID: 1 Comm: swapper Not tainted 5.3.0 #6
Hardware name: SMDK2410
查看后发现是linux源码并没有对yaffs文件系统支持,若要使用,需要自己单独移植。
目前不是非得使用yaffs,所以决定先用cramfs代替。
2.rootfs mount成功后init失败
VFS: Mounted root (cramfs filesystem) readonly on device 31:4.
Freeing unused kernel memory: 212K
This architecture does not have kernel memory protection.
Run /linuxrc as init process
random: fast init done
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
CPU: 0 PID: 1 Comm: linuxrc Not tainted 5.3.0 #11
Hardware name: SMDK2410
Backtrace:
[<c000df10>] (dump_backtrace) from [<c000e1f8>] (show_stack+0x18/0x24)
r7:c181ff44 r6:c064e6a8 r5:00000000 r4:c0741060
[<c000e1e0>] (show_stack) from [<c0586ad4>] (dump_stack+0x20/0x30)
[<c0586ab4>] (dump_stack) from [<c001a55c>] (panic+0xe8/0x2e4)
[<c001a474>] (panic) from [<c001bf38>] (do_exit+0x9f0/0xa2c)
r3:c1821da0 r2:c1821dac r1:00000004 r0:c064e6a8
r7:c181ff44
[<c001b548>] (do_exit) from [<c001cb28>] (do_group_exit+0x44/0xbc)
r7:c181ff44
[<c001cae4>] (do_group_exit) from [<c0027c4c>] (get_signal+0x110/0x77c)
r5:ffffe000 r4:0830009f
[<c0027b3c>] (get_signal) from [<c000d6d8>] (do_work_pending+0x1b0/0x564)
r10:00000000 r9:c070f00c r8:c181ff44 r7:00000000 r6:c070f008 r5:c181ffb0
r4:ffffe000
[<c000d528>] (do_work_pending) from [<c0009068>] (slow_work_pending+0xc/0x20)
Exception stack(0xc181ffb0 to 0xc181fff8)
ffa0: 00000000 00000001 be88bf14 00000000
ffc0: 00000000 be88bf14 00000000 00000000 00000000 00000000 00000000 00000000
ffe0: 00000000 be88befc 0000fa3a 0011da38 40000030 ffffffff
r10:00000000 r9:c181e000 r8:00000000 r7:0000717f r6:ffffffff r5:40000030
r4:0011da38
---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004 ]---
经check,两种可能:
(1)跟制作的rootfs有问题有关,然后重新找了个工具链4.4.3去编译busybox制作rootfs后这个问题解决。
(2)重新配置内核支持EABI
$make menuconfig
Kernel Features —>
[*]Use arm EABI...
3.rcS初始化遇到read-only filesystem问题
random: fast init done
mount: mounting none on /dev/pts failed: No such file or directory
mount: mounting tmpfs on /dev/shm failed: No such file or directory
mkdir: can't create directory '/dev/pts': Read-only file system
mount: mounting devpts on /dev/pts failed: No such file or directory
/etc/init.d/rc.S: line 11: can't create /proc/sys/kernel/hotplug: nonexistent directory
mdev: /sys/dev: No such file or directory
mkdir: can't create directory '/var/lock': Read-only file system
RootCause:由于使用的是cramfs,其是只读的文件系统,需要提前在rootfs里面创建对应的文件夹,并需要对诸如/dev, /proc等诸如需要启动后写操作的文件夹进行mount,如下代码,改完后可正常生成设备文件。
etc/fstab
proc /proc proc defaults 0 0
none /tmp ramfs defaults 0 0
none /var ramfs defaults 0 0
mdev /dev ramfs defaults 0 0
sysfs /sys sysfs defaults 0 0
4.尝试使用yaffs2 来mount nand flash,但是失败,有如下打印:
root@nano2410#mount -t yaffs /dev/mtdblock5 /mnt/yaffs/
yaffs: dev is 32505861 name is "mtdblock5" rw
yaffs: passed flags ""
mount: mounting /dev/mtdblock5 on /mnt/yaffs/ failed: Invalid argument
yaffs: dev is 32505861 name is "mtdblock5" rw
yaffs: passed flags ""
yaffs: yaffs: Attempting MTD mount of 31.5,"mtdblock5"
yaffs: NAND geometry problems: chunk size 512, type is yaffs, inband_tags 1
经搜索,跟yaffs的源码有关,可参照
https://lists.yoctoproject.org/pipermail/linux-yocto/2013-December/001684.html
Yaffs will select Yaffs1 for deives with 512 byte writing size.
Moreover, it will enable inband_tags automatically for devices with
small oob.
However, Yaffs1 can not work with inband_tags. So move the
oob size checking before auto selecting Yaffs1.
fs/yaffs2/yaffs_vfs.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/yaffs2/yaffs_vfs.c b/fs/yaffs2/yaffs_vfs.c
index 568cef4..c3b7368 100644
--- a/fs/yaffs2/yaffs_vfs.c
+++ b/fs/yaffs2/yaffs_vfs.c
@@ -2708,17 +2708,17 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
yaffs_version = 2;
}
+ if (mtd->oobavail < sizeof(struct yaffs_packed_tags2) ||
+ options.inband_tags)
+ inband_tags = 1;
+
/* Added NCB 26/5/2006 for completeness */
- if (yaffs_version == 2 && !options.inband_tags
+ if (yaffs_version == 2 && !inband_tags
&& WRITE_SIZE(mtd) == 512) {
yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs1");
yaffs_version = 1;
}
- if (mtd->oobavail < sizeof(struct yaffs_packed_tags2) ||
- options.inband_tags)
- inband_tags = 1;
-
if(yaffs_verify_mtd(mtd, yaffs_version, inband_tags) < 0)
return NULL;
--
修改代码后问题解决。