Transplant linux kernel,rootfs to FriendlyARM nano2410

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 编译问题:

  1. 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;
 
-- 

修改代码后问题解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java代码实现在一颗三叉链表表示的二叉树中删除二叉树中的一个结点的示例: ```java public class ThreeLinkBinaryTree { private TreeNode root; public class TreeNode { int data; TreeNode left; TreeNode right; TreeNode parent; public TreeNode(int data) { this.data = data; this.left = null; this.right = null; this.parent = null; } } public ThreeLinkBinaryTree() { root = null; } public void insert(int data) { TreeNode newNode = new TreeNode(data); if (root == null) { root = newNode; } else { TreeNode current = root; while (true) { if (data < current.data) { if (current.left == null) { current.left = newNode; newNode.parent = current; break; } else { current = current.left; } } else { if (current.right == null) { current.right = newNode; newNode.parent = current; break; } else { current = current.right; } } } } } public boolean delete(int data) { TreeNode current = findNode(data); if (current == null) { return false; } if (current.right == null) { transplant(current, current.left); } else if (current.left == null) { transplant(current, current.right); } else { TreeNode successor = minimum(current.right); if (successor.parent != current) { transplant(successor, successor.right); successor.right = current.right; successor.right.parent = successor; } transplant(current, successor); successor.left = current.left; successor.left.parent = successor; } return true; } private TreeNode findNode(int data) { TreeNode current = root; while (current != null && current.data != data) { if (data < current.data) { current = current.left; } else { current = current.right; } } return current; } private void transplant(TreeNode u, TreeNode v) { if (u.parent == null) { root = v; } else if (u == u.parent.left) { u.parent.left = v; } else { u.parent.right = v; } if (v != null) { v.parent = u.parent; } } private TreeNode minimum(TreeNode node) { while (node.left != null) { node = node.left; } return node; } } ``` 在上述代码中,我们通过 `findNode` 方法来查找需要删除的节点。如果需要删除的节点没有左孩子或右孩子,我们可以直接用它的左孩子或右孩子来替换它。如果需要删除的节点有左孩子和右孩子,我们需要找到它的后继节点,并用后继节点来替换它。然后,我们将需要删除的节点的左子树和右子树连接到后继节点上。最后,我们要注意更新它们的父节点关系。 需要注意的是,在这个三叉链表表示的二叉树中,每个节点都有一个指向其父节点的指针,这样我们就可以方便地进行删除操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值