移植Linux-3.4.2过程学习笔记2——无法挂载根文件系统

此时内核已经可以打印串口信息了,目前的问题是无法挂载根文件系统。
搜索分区名,查看是在哪里定义的:

grep "\"Boot\ Agent\"" * -nR

得到结果:
arch/arm/mach-s3c24xx/common-smdk.c:113: .name = "Boot Agent",
查看arch/arm/mach-s3c24xx/common-smdk.c文件的113行,发现nand分区设置:

/* NAND parititon from 2.4.18-swl5 */

static struct mtd_partition smdk_default_nand_part[] = {
    [0] = {
        .name   = "Boot Agent",
        .size   = SZ_16K,
        .offset = 0,
    },
    [1] = {
        .name   = "S3C2410 flash partition 1",
        .offset = 0,
        .size   = SZ_2M,
    },
    [2] = {
        .name   = "S3C2410 flash partition 2",
        .offset = SZ_4M,
        .size   = SZ_4M,
    },
    [3] = {
        .name   = "S3C2410 flash partition 3",
        .offset = SZ_8M,
        .size   = SZ_2M,
    },
    [4] = {
        .name   = "S3C2410 flash partition 4",
        .offset = SZ_1M * 10,
        .size   = SZ_4M,
    },
    [5] = {
        .name   = "S3C2410 flash partition 5",
        .offset = SZ_1M * 14,
        .size   = SZ_1M * 10,
    },
    [6] = {
        .name   = "S3C2410 flash partition 6",
        .offset = SZ_1M * 24,
        .size   = SZ_1M * 24,
    },
    [7] = {
        .name   = "S3C2410 flash partition 7",
        .offset = SZ_1M * 48,
        .size   = MTDPART_SIZ_FULL,
    }
};

将分区修改为:

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_2M,
    },
    [3] = {
        .name   = "rootfs",
        .offset = MTDPART_OFS_APPEND,
        .size   = MTDPART_SIZ_FULL,
    },
};

重新make uImage,并烧写到开发板,启动内核。
提示“No filesystem could mount root,tried: ext3 ext2 ……”,原因是没有烧写文件系统,查询配置文件.config,此时无法支持yaffs格式,已经支持JFFS2格式,开始烧写文件系统,进入uboot界面后:

nfs 30000000 192.168.1.16:/work/nfs_root/fs_mini_mdev.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 260000 $filesize    /* 老版本的uboot需要$(filesize)如此引用 */

该文件系统是在linux-2.6.22.6内核下编译出来的文件系统,不一定适用于当前内核。
设置启动参数:

set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2

下载内核并启动:

nfs 32000000 192.168.1.16:/work/nfs_root/uImage_new
bootm 32000000

提示文件系统已经挂载成功,但找不到“No init found.”,找不到init进程,init进程是由内核启动的第一个(也是唯一的一个)用户进程,它根据配置文件决定启动哪些程序,它是所有后续进程的发起者。


Mark:
任何一个单板,在uboot阶段设置机器id,启动uImage,都可以根据提示信息在内核根目录下找到提示信息所对应的分区结构体,修改分区结构,保证uboot与内核的分区名字、大小一一对应,即可成功挂载。


由于缺少init进程,所以开始着手制作一个最小文件系统,所谓的制作根文件系统,就是创建各种目录,并且在里面创建各种文件。
此时先配置、编译一个busybox,选择busybox创建最小的根文件系统,只需要在/dev目录下创建必要的设备节点、在/etc目录下创建一些配置文件就可以,如果busybox使用动态连接还要在/lib目录下包含库函数。

tar -xjf busybox-1.7.0.tar.bz2          /* 这个不是最新的busybox */
cd busybox-1.7.0
vi Makefile                    /* 设置交叉编译工具与环境 */
make menuconfig
make

由于是通过nfs的启动方式,所以新建一个文件目录:

cd /work/nfs_root/
mkdir fs_mini_mdev_new

将编译好的busybox安装到该目录下:

make install CONFIG_PREFIX=/work/nfs_root/fs_mini_mdev_new

安装完成后,就可以在该目下看到相应的文件目录:

cd /work/nfs_root/fs_mini_mdev_new
ls
bin  linuxrc  sbin  usr

开始安装glibc库,先查看当前交叉编译工具链位置:

echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/arm/4.3.2/bin

我使用的交叉编译工具链在/usr/local/arm/4.3.2/bin中,退到4.3.2目录下,搜索lib:

find -name lib
./arm-none-linux-gnueabi/libc/thumb2/lib
./arm-none-linux-gnueabi/libc/thumb2/usr/lib
./arm-none-linux-gnueabi/libc/armv4t/lib        /* 使用这个库 */
./arm-none-linux-gnueabi/libc/armv4t/usr/lib    /* 使用这个库 */
./arm-none-linux-gnueabi/libc/lib
./arm-none-linux-gnueabi/libc/usr/lib
./arm-none-linux-gnueabi/lib
./lib

Mark:
find:在一个目录(及子目录)中搜索文件,你可以指定一些匹配条件,如按文件名、文件类型、用户甚至是时间戳查找文件。

grep:grep (global search regular expression_r(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。


找到要使用的库,在新建的文件系统目录下新建一个lib目录,并将该库下的所有so文件拷贝到新建的lib目录下:

mkdir /work/nfs_root/fs_mini_mdev_new/lib
mkdir /work/nfs_root/fs_mini_mdev_new/usr/lib -p   /* -p表示递归创建,如果没有usr目录,就先创建usr目录,再继续创建lib目录 */

cp arm-none-linux-gnueabi/libc/armv4t/lib/*so* /work/nfs_root/fs_mini_mdev_new/lib -d
cp arm-none-linux-gnueabi/libc/armv4t/usr/lib/*so* /work/nfs_root/fs_mini_mdev_new/usr/lib -d

此时已经安装了busybox、C库,建立了bin/、sbin/、usr/bin、usr/sbin、lib/等目录,最小根文件系统的大部分目录、文件已经建好,继续建立/etc目录,该目录下需要三个文件:/etc/inittab,/etc/init.d/rcS,/etc/fstab。

init进程会根据/etc/inittab文件来创建其他子进程,创建inittab,内容是:

# /etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r

创建/etc/init.d/rcS,这是一个脚本文件,可以在里面添加想自动执行的命令,下面的内容配置IP地址,挂接/etc/fstab指定的文件系统。内容是:

#mount -t proc none /proc
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

最后需要修改权限,使它能够执行:chmod +x etc/init.d/rcS

最后创建/etc/fstab,内容是:

# device   mount-point  type   options  dump  fsck   order
proc       /proc        proc   defaults  0    0
sysfs      /sys         sysfs  defaults  0    0
tmpfs      /dev         tmpfs  defaults  0    0

该文件被用来定义文件系统的“静态信息”,这些信息被用来控制mount命令的行为。文件中各字段意义如下:
1.device:要挂接的设备;
2.mount-point:挂接点;
3.type:文件系统类型;
4.options:挂接参数,以逗号隔开;
5.dump和fsck order:用来决定控制dump、fsck程序的行为。
/etc/fstab的作用不仅仅是用来控制“mount -a”的行为,即使是一般的mount的命令也受它控制。

紧接着要构建dev目录,先查看一下设备节点/dev/console和/dev/null的主次设备号:

ls -l /dev/console /dev/null
crw------- 1 root root 5, 1 2018-09-07 03:45 /dev/console
crw-rw-rw- 1 root root 1, 3 2018-09-07 03:22 /dev/null

因此,在fs_mini_mdev_new目录下创建dev目录,并创建设备节点:

mkdir dev
sudo mknod dev/console c 5 1
sudo mknod dev/null c 1 3

最后在fs_mini_mdev_new目录下创建其他目录:

mkdir proc mnt tmp sys root 

至此,fs_mini_mdev_new就是非常小的根文件系统了,此时开发板可以把它作为网络根文件系统直接启动,如果要烧入开发板,还需要把它制作成一个文件,称为映象文件,由于这时内核还不支持yaffs格式文件,所以我们制作成一个jffs2格式文件:

mkfs.jffs2 -n -s 2048 -e 128KiB -d fs_mini_mdev_new -o fs_mini_mdev_new.jffs2 

制作成功,重启、下载文件映像,擦除nand flash,烧写nand flash,下载新内核,启动:

nfs 30000000 192.168.1.16:/work/nfs_root/fs_mini_mdev_new.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 260000 $filesize
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
nfs 32000000 192.168.1.16:/work/nfs_root/uImage_new
bootm 32000000

启动后发现:挂接上了文件系统,也找到了init进程,但是提示exitcode=0x00000004,在内核代码中搜索:“exitcode”,得到错误宏SIGILL,表示illegal instruction,解决方法:
重新配置内核支持EABI,

make uImage

拷贝到nfs目录下,用nfs下载内核文件,启动。

set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
nfs 32000000 192.168.1.16:/work/nfs_root/uImage_eabi
bootm 32000000

成功

猜你喜欢

转载自blog.csdn.net/weixin_41354745/article/details/82497653