第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > Exynos4412 移植Linux Kernel 5.4过程记录(三)——根文件系统构建与SD卡挂载fs

Exynos4412 移植Linux Kernel 5.4过程记录(三)——根文件系统构建与SD卡挂载fs

时间:2021-01-09 13:07:09

相关推荐

Exynos4412 移植Linux Kernel 5.4过程记录(三)——根文件系统构建与SD卡挂载fs

Exynos4412 移植Linux Kernel 5.4过程记录(三)——根文件系统构建与SD卡挂载

Exynos4412 移植Linux Kernel 5.4过程记录系列一、嵌入式Linux文件系统基础知识1、嵌入式Linux文件系统的构建方案2、根文件系统的两种格式(1)镜像格式的根文件系统(2)文件夹格式的根文件系统3、文件系统目录标准二、Linux 根文件系统构建1、下载BusyBox源代码2、编译busybox并安装3、制作根文件系统目录4、添加库文件5、制作hosts主机静态域名文件6、制作mdev.conf文件7、创建dev目录的设备节点8、填充etc目录9、在sbin/目录下添加hotplug.sh10、制作ext4格式的SD卡根文件系统分区三、启动exynos4412

Exynos4412 移植Linux Kernel 5.4过程记录系列

Exynos4412 Linux Kernel 5.15移植过程记录(一)——解决编译内核出现mpc.h: gmp.h: No such file or director问题Exynos4412 移植Linux Kernel 5.15过程记录(二)——解决U-Boot卡在Starting kernel的问题,DM9000网卡驱动(设备树)

以上2篇博文一直移植的是Linux Kernel5.15,但是总有问题。所以,本文移植Linux Kernel5.4了。

一、嵌入式Linux文件系统基础知识

1、嵌入式Linux文件系统的构建方案

Linux文件系统不仅仅是根文件系统Cramfs,还有用户YAFFS2文件系统和临时文件系统。

Cramfs根文件系统:是内核启动挂载的第一个文件系统,是只读不可写的,所占存储空间小,适用于不需要经常修改的场合。YAFFS2文件系统:适合Nand Flash设备,用了存储用户读写数据。Ramfs/Tempfs文件系统:把所有文件都放在RAM中,读写速度快,减少对Flash的读写损坏。但是掉电后数据丢失。

2、根文件系统的两种格式

镜像格式的根文件系统文件夹格式的根文件系统1

(1)镜像格式的根文件系统

镜像文件系统的扩张名为.img,它具有一定的格式,格式是内化的,跟文件名后缀是无关,而是在制作时决定的。镜像形式的根文件系统是由文件夹格式的根文件系统通过特定的工具(mke2fs)制作得到的,主要用来烧写到Nand Flash或者SD卡上,用于内核启动后挂载。

(2)文件夹格式的根文件系统

简单来说,文件夹格式的根文件系统其实就是我们开发主机下的一个文件夹而已,不同之处在于这个文件夹里面包含了我们根文件系统所需的内容(包括etc目录下的运行时配置文件、/bin等目录下的可执行程序、/lib目录下的库文件等···)。文件夹格式的根文件系统是没有格式的。保存根文件系统的介质(SD卡、NAND FLASH等),需要格式化。

3、文件系统目录标准

参考文献:

嵌入式 Linux根文件系统移植(二)——根文件系统简介2

二、Linux 根文件系统构建

1、下载BusyBox源代码

从官网/downloads/下载BusyBox源代码。目前最新版本是busybox-1.35.0.tar.bz2。我下载的是busybox-1.34.1.tar.bz2。

新建工作目录~/rootfs/

mkdir ~/rootfs

复制BusyBox源码到该目录下,并解压

tar vxf busybox-1.34.1.tar.bz2

2、编译busybox并安装

(1)添加交叉工具链

编辑顶层目录下的Makefile文件。

cd ./busybox-1.34.1/gedit Makefile

在Makefile中添加交叉工具链。

ARCH ?= armCROSS_COMPILE ?= arm-none-linux-gnueabihf-

(2)配置busybox。修改Makefile的编译选项如下:

make distcleanmake defconfigmake menuconfig

按照如下文档配置menuconfig即可。

Busybox Settings--->Build Options--->[ ]Build BusyBox as a static binary(no shared libs)Busybox Library Tuning--->[*]vi-style line editing commands[*]Fancy shell promptsInstallation Options ("make install" behavior) --->(/home/exynos4412/rootfs/rootfs) BusyBox installation prefix// 编译生成文件的存放路径Linux Module Utilities--->[ ]Simplified modutils[*]insmod[*]rmmod[*]lsmod

其他都保持默认。编译BusyBox:

make -j 4

(3)安装BusyBox

make install

进入安装目录/home/exynos4412/rootfs/rootfs会发现bin linuxrc sbin usr这几个文件。说明安装成功。

3、制作根文件系统目录

进入安装目录,创建所需文件夹(根据FHS标准)

mkdir dev etc home lib proc sys tmp var mntmkdir var/log

4、添加库文件

先用arm-none-linux-gnueabihf-readelf查看必需的库文件。

arm-none-linux-gnueabihf-readelf -a ./rootfs/bin/busybox | grep "program interpreter"[Requesting program interpreter: /lib/ld-linux-armhf.so.3]arm-none-linux-gnueabihf-readelf -a ./rootfs/bin/busybox | grep "Shared library"0x00000001 (NEEDED) Shared library: [libm.so.6]0x00000001 (NEEDED) Shared library: [libresolv.so.2]0x00000001 (NEEDED) Shared library: [libc.so.6]

现在需要把这些链接库文件拷贝到根文件系统的/lib目录下。注意,这些是符号连接文件,你需要把它们连接的真正的库文件一起复制。

arm-none-linux-gnueabihf-gcc -print-sysroot查看交叉编译工具链所在路径。

将交叉编译工具链的/lib中的库文件复制到安装目录下的/Iib子目录,命令如下。

arm-none-linux-gnueabihf-gcc -print-sysroot/opt/gcc-arm-10.3-.07-x86_64-arm-none-linux-gnueabihf/bin/../arm-none-linux-gnueabihf/libcsudo cp /opt/gcc-arm-10.3-.07-x86_64-arm-none-linux-gnueabihf/bin/../arm-none-linux-gnueabihf/libc/lib/* /home/exynos4412/rootfs/rootfs/lib/ -a

删除静态库和共享库文件中的符号表,命令如下。

sudo rm lib/*.a

删除调试等信息,使文件变小,命令如下。

arm-none-linux-gnueabi-strip lib/*.so

删除不需要的库,确保库的大小不超过4MB,然后用以下命令检查lib目录的大小。

du-mh lib/

5、制作hosts主机静态域名文件

在etc目录下创建hosts文件,并填充内容如下:

#by sprife for static ip127.0.0.1 localhost192.168.1.230 CBT4412

6、制作mdev.conf文件

把busybox源码目录下的mdev.conf文件复制到根文件系统的etc目录下,并修改为:

## Syntax:# [-]devicename_regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...]# [-]$ENVVAR=regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...]# [-]@maj,min[-min2] user:group mode [=path]|[>path]|[!] [@|$|*cmd args...]## [-]: do not stop on this match, continue reading mdev.conf# =: move, >: move and create a symlink# !: do not create device node# @|$|*: run@cmd if $ACTION=add, $cmd if $ACTION=remove, *cmd in all casesnull0:0 666zero0:0 666urandom0:0 444kmem0:9 000mem0:9 640port0:9 640console0:5 600ptmx0:5 660tty[0-9]*0:5 660ttyS[0-9]*0:20 640fd[0-9]*0:11 660hd[a-z]*0:6 660hw_random0:0 600 =hwrngsd[a-z][0-9]0:0 666 @(/etc/hotplug/insert.sh $MDEV $SUBSYSTEM)sd[a-z] 0:0 666 $(/etc/hotplug/remove.sh $MDEV $SUBSYSTEM)ub[a-z][0-9]0:0 666 @(/etc/hotplug/insert.sh $MDEV $SUBSYSTEM)ub[a-z] 0:0 666 $(/etc/hotplug/remove.sh $MDEV $SUBSYSTEM)mmcblk[0-9]p[0-9] 0:0 666 @(/etc/hotplug/insert.sh $MDEV $SUBSYSTEM)mmcblk[0-9] 0:0 666 $(/etc/hotplug/remove.sh $MDEV $SUBSYSTEM)

7、创建dev目录的设备节点

mkmod命令的格式是:

mknod 设备名 设备类型(字符:c,块:b) 主设备号 从设备号

可以在根文件系统目录下,制作脚本文件,如下:

#!/bin/bash mkdir dev/tty dev/tty0 dev/ttyS0 dev/console dev/urandom dev/ptmx dev/null dev/port dev/random dev/coresudo mknod -m 666 dev/tty c 5 0sudo mknod -m 620 dev/tty0 c 4 0sudo mknod -m 660 dev/ttyS0 c 4 64sudo mknod -m 600 dev/console c 5 1sudo mknod -m 666 dev/zero c 1 5sudo mknod -m 666 dev/urandom c 1 9 sudo mknod -m 666 dev/ptmx c 5 2sudo mknod -m 666 dev/null c 1 3sudo mknod -m 666 dev/full c 1 7sudo mknod -m 640 dev/port c 1 4sudo mknod -m 666 dev/random c 1 8ln -s /proc/kcore dev/corechmod 1777 tmp varmkdir mnt/etc mnt/jiffs2 mnt/yaffs mnt/udisk mnt/sdcard mnt/nfsmkdir var/lib var/lock var/log var/run var/tmpchmod 1777 var/tmp

mdev的用法可以参考busybox-1.9.2/docs/mdev.txt,它的两个用途:初始化/dev目录、动态更新。要在内核启动时,自动运行mdev,这需要修改etc/fstab、etc/init.d/rcS加入要自动运行的命令。

8、填充etc目录

(1)添加模板文件内容。

将Busybox源码目录中的etc目录模板内容复制到前面制作的文件系统目录的etc目录下:

这样前面制作的etc目录下就有了相应内容,默认的文件还需要手动修改才可。

cp busybox-1.34.1/examples/bootfloppy/etc/* ~/rootfs/rootfs/etc -a

(2)修改rcS文件,内容如下:

sudo gedit etc/init.d/rcS

#!/bin/shPATH=/sbin:/bin:/usr/sbin:/usr/binrunlevel=Sprevlevel=Numask 022export PATH runlevel prevlevelmount -aecho /sbin/mdev > /proc/sys/kernel/hotplugmdev -s/bin/hostname -F /etc/sysconfig/HOSTNAME/bin/mount -t proc none /proc/bin/mount -t sysfs sysfs /sys/bin/echo > /dev/mdev.seqifconfig eth0 192.168.1.230 netmask 255.255.255.0 up

为rcS文件添加可执行权限:

chmod +x init.d/rcS

(3)修改fstab文件,内容如下:

sudo gedit etc/fstab

# /etc/fstab: static file system information.## Use 'vol_id --uuid' to print the universally unique identifier for a# device; this may be used with UUID= as a more robust way to name devices# that works even if disks are added and removed. See fstab(5).## <file system> <mount point> <type> <options> <dump> <pass>proc /proc proc defaults 0 0sysfs /sys sysfs defaults 0 0tmpfs /var tmpfs defaults 0 0tmpfs /tmp tmpfs defaults 0 0tmpfs /dev tmpfs defaults 0 0mdev /dev ramfs defaults 0 0/dev/mtdblock3/mnt/yaffsyaffsdefaults1 1

(4)修改profile文件内容

在启动脚本etc/init.d/rcS执行完后将在终端启动一个shell。Shell启动过程中会根据文件/etc/profile配置登陆环境。

sudo gedit etc/profile

# /etc/profile: system-wide .profile file for the Bourne shells# Ash profile# vim: syntax=sh# No core files by defaultulimit -S -c 0 > /dev/null 2>&1USER="`id -un`"LOGNAME=$USERPS1='[\u@\h \W]\# 'PATH=$PATHHOSTNAME=`/bin/hostname`export USER LOGNAME PS1 PATH

(5)查看etc/inittab文件内容,把tty2::askfirst:-/bin/sh修改成console::askfirst:-/bin/sh

否则会无限报错:can't open /dev/tty2: No such file or directory

sudo gedit etc/inittab

#first:run the system script file::sysinit:/etc/init.d/rcS::askfirst:-/bin/sh::ctrlaltdel:-/sbin/reboot#umount all filesystem::shutdown:/bin/umount -a -r#restart init process::restart:/sbin/init

(6)在/etc下建立hotplug文件夹,并在该文件夹下建立两个文件

insert.sh:

if [ -n "$1" ]; thenif [ -b /dev/$1 ]; thenif [ ! -d /media ]; thenmkdir -p /mediafiif [ ! -d /media/$1 ]; thenmkdir -p /media/$1fimount /dev/$1 /media/$1if [ $? -ne 0 ]; thenrm -rf /media/$1fififi

remove.sh:

MOUNTS=$(mount | grep $1 | cut -d' ' -f3)umount $MOUNTSrm -rf $MOUNTS

————————————————

版权声明:本文为CSDN博主「EmSoftEn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

给文件添加可执行权限:

sudo chmod +x insert.sh remove.sh

9、在sbin/目录下添加hotplug.sh

文件内容如下:

#! /bin/shecho "lqj auto mount sd"if [ "$1" == "" ]; thenecho "parameter is none" > /tmp/error.txtexit 1fiMNT=$1if echo "$1" | grep mmcblk; thenif echo "$1" | grep p[25]; thenMNT=sdcard2elseMNT=sdcardfielseif echo "$1" | grep sd; thenif echo "$1" | grep [25]; thenMNT=nandcard2elseMNT=nandcardfififimounted=`mount | grep $1 | wc -l`#echo "par=$1,mounted=$mounted,MNT=$MNT" > /dev/console# mounted, assume we umountif [ $mounted -ge 1 ]; thenecho "R/mnt/$1" >> /tmp/usbmnt.logecho "R/mnt/$1" > /tmp/fifo.1if ! umount -l "/mnt/$1"; thenexit 1elserm -f "/mnt/$MNT"echo "[Umount FS]: /dev/$1 -X-> /mnt/$MNT" > /dev/consolefiif ! rmdir "/mnt/$1"; thenexit 1fi# not mounted, lets mount under /mntelseif ! mkdir -p "/mnt/$1"; thenexit 1fi#try jffs2 firstif ! mount -t jffs2 "/dev/$1" "/mnt/$1"; then#try vfatif ! mount -t vfat -o noatime,shortname=mixed,utf8 "/dev/$1" "/mnt/$1"; then# failed to mount, clean up mountpointif ! rmdir "/mnt/$1"; thenexit 1fiexit 1elseln -s /mnt/$1 /mnt/$MNTecho "[Mount VFAT]: /dev/$1 --> /mnt/$MNT" > /dev/consoleecho "A/mnt/$1" >> /tmp/usbmnt.logecho "A/mnt/$1" > /tmp/fifo.1fielseecho "[Mount JFFS2]: /dev/$1 --> /mnt/$MNT" > /dev/consoleecho "A/mnt/$1" >> /tmp/usbmnt.logecho "A/mnt/$1" > /tmp/fifo.1fifi

————————————————

版权声明:本文为CSDN博主「linqiongjun86」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

给文件添加可执行权限:

sudo chmod +x hotplug.sh

10、制作ext4格式的SD卡根文件系统分区

思路是:把SD卡挂载在宿主机Ubuntu系统中,用fdisk命令将SD卡进行分区,将该分区格式化为ext4格式。然后把~/rootfs/rootfs/目录中的所有文件复制到该分区里。那么该分区就可以作为内核启动时挂载的根文件系统。

具体步骤如下:

(1)SD卡分区:请参考

SD卡烧写Linux kernel——SD卡分区,并烧写uboot,kernel,DTB及filesystem(2)烧写u-boot:本质上用dd命令烧写。我是用Samsung提供的烧写脚本,自动烧写的。不会影响其他分区里的文件。原理请参考以下博文:

Ubuntu18.04烧录U-Boot时格式化SD卡的文件类型(RAW 格式)(3)复制根文件系统:思路是在/mnt目录下新建2个文件夹/mnt/sd1,然后挂载SD卡分区。先查看SD卡分区的设备名称,然后挂载,再复制,最后解挂。

我用的是读卡器插入TF卡。对SD卡做了3个分区,用cat /proc/partitions,可以看到三个sdb,分别是/dev/sdb,/dev/sdb1,/dev/sdb2,/dev/sdb3。看官根据自己的实际情况,也可能是/dev/sdc、/dev/sdd等。

sudo mount -t /dev/sdb3 /mnt/sd1sudo cp ~/rootfs/rootfs/* -a /mnt/sd1ls /mnt/sd1cd sudo umount /mnt/sd1

ls /mnt/sd1就可以看到根文件系统中的目录了。

三、启动exynos4412

把SD卡插入exyno4412开发板,设置启动引脚为SD卡启动。上电以后,就可以启动u-boot。通过cuteCom串口助手,输入u-boot命令,设置u-boot的环境变量,然后tftp下载Linux内核和设备树,bootm命令启动内核从SD卡挂载根文件系统。

setenv bootargs root=/dev/mmcblk0p3 rootfstype=ext4 init=/linuxrc console=ttySAC0,115200n8 earlyprintktftp 50000000 uImage;tftp 52000000 exynos4412-cbt4412.dtb;bootm 50000000 - 52000000

启动信息如下:

[11:04:26:842] CBT4412 #setenv bootargs root=/dev/mmcblk0p3 rootfstype=ext4 init=/linuxrc console=ttySAC0,115200n8 earlyprintk␍␊[11:04:43:363] CBT4412 #bootm 50000000 - 52000000␍␊[11:04:48:154] ## Booting kernel from Legacy Image at 50000000 ...␍␊[11:04:48:162] Image Name: Linux-5.4.174␍␊[11:04:48:162] Image Type: ARM Linux Kernel Image (uncompressed)␍␊[11:04:48:170] Data Size: 6783744 Bytes = 6.5 MiB␍␊[11:04:48:186] Load Address: 40008000␍␊[11:04:48:186] Entry Point: 40008000␍␊[11:04:48:186] Verifying Checksum ... OK␍␊[11:04:49:032] ## Flattened Device Tree blob at 52000000␍␊[11:04:49:048] Booting using the fdt blob at 0x52000000␍␊[11:04:49:048] Loading Kernel Image␍␊[11:04:49:215] Loading Device Tree to 7ae83000, end 7ae91a72 ... OK␍␊[11:04:49:254] ␍␊[11:04:49:254] Starting kernel ...␍␊[11:04:49:254] ␍␊[11:04:49:667] [ 0.000000][ T0] Booting Linux on physical CPU 0xa00␍␊[11:04:49:671] [ 0.000000][ T0] Linux version 5.4.174 (exynos4412@exynos4412) (gcc version 10.3.1 0621 (GNU Toolchain for the A-profile Architecture 10.3-.07 (arm-10.29))) #1 SMP PREEMPT Sat Jan 29 08:02:13 CST ␍␊[11:04:49:691] [ 0.000000][ T0] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=10c5387d␍␊[11:04:49:710] [ 0.000000][ T0] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache␍␊[11:04:49:710] [ 0.000000][ T0] OF: fdt: Machine model: CBt4412 board based on Exynos4412␍␊[11:04:49:723] [ 0.000000][ T0] printk: bootconsole [earlycon0] enabled␍␊[11:04:49:723] [ 0.000000][ T0] Memory policy: Data cache writealloc␍␊[11:04:49:723] [ 0.000000][ T0] Reserved memory: created DMA memory pool at 0x7f800000, size 8 MiB␍␊[11:04:49:737] [ 0.000000][ T0] OF: reserved mem: initialized node region_mfc_right, compatible id shared-dma-pool␍␊[11:04:49:745] [ 0.000000][ T0] Reserved memory: created DMA memory pool at 0x7d400000, size 36 MiB␍␊[11:04:49:758] [ 0.000000][ T0] OF: reserved mem: initialized node region_mfc_left, compatible id shared-dma-pool␍␊[11:04:49:768] [ 0.000000][ T0] cma: Reserved 96 MiB at 0x74c00000␍␊[11:04:49:768] [ 0.000000][ T0] Samsung CPU ID: 0xe441␍␊[11:04:49:792] [ 0.000000][ T0] percpu: Embedded 20 pages/cpu s51048 r8192 d22680 u81920␍␊[11:04:49:798] [ 0.000000][ T0] Built 1 zonelists, mobility grouping on. Total pages: 249344␍␊[11:04:49:808] [ 0.000000][ T0] Kernel command line: root=/dev/mmcblk0p3 rootfstype=ext4 init=/linuxrc console=ttySAC0,115200n8 earlyprintk␍␊# 省略部分信息[11:04:50:114] [ 0.000000][ T0] random: get_random_bytes called from start_kernel+0x32c/0x4d8 with crng_init=0␍␊[11:04:50:124] [ 0.000000][ T0] Exynos4x12 clocks: sclk_apll = 1400000000, sclk_mpll = 800000000␍␊[11:04:50:144] [ 0.000000][ T0] ⇥sclk_epll = 416000000, sclk_vpll = 440062500, arm_clk = 1400000000␍␊# 省略[11:04:52:010] [ 1.826910][ T1] mmc_host mmc1: card is polling.␍␊[11:04:52:010] [ 1.843988][ T1] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 400000Hz, actual 396825HZ div = 63)␍␊[11:04:52:024] [ 1.866196][ T32] mmc0: new high speed SD card at address 0002␍␊[11:04:52:034] [ 1.875090][ T32] mmcblk0: mmc0:0002 968 MiB ␍␊[11:04:52:047] [ 1.882917][ T32] mmcblk0: p1 p2 p3␍␊# 省略[11:04:52:358] [ 2.41][ T1] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null)␍␊[11:04:52:367] [ 2.33][ T1] VFS: Mounted root (ext4 filesystem) readonly on device 179:3.␍␊[11:04:52:376] [ 2.203322][ T1] devtmpfs: mounted␍␊[11:04:52:388] [ 2.204978][ T1] Freeing unused kernel memory: 1024K␍␊[11:04:52:397] [ 2.239574][ T1] Run /linuxrc as init process␍␊[11:04:52:610] ␍can't run '/etc/init.d/rcS': No such file or directory␍␊[11:04:52:613] ␍␊[11:04:52:613] Please press Enter to activate this console.

从启动信息中我们可以看到SD卡的分区是mmcblk0p3。各位看官根据自己的实际情况修改bootargs参数中的root=/dev/mmcblk0p3

最后,记录一下制作ext2格式的ramdisk文件映像的方法。以下内容也可以不看。

(1)制作一个大小为8MB的映像文件,命令如下。

sudo dd if=/dev/zero of=ramdisk bs=1k count=10240

此时可生成一个名为ramdisk的文件,文件大小为10MB。

(2)格式化文件成ext2文件格式,命令如下。

sudo mkfs ext2 -F ramdisk

(3)在mnt目录下创建initrd目录作为挂载点,并将ramdisk文件挂载上,命令如下。

sudo mkdir /mnt/initrdsudo mount -t ext2 -o loop ramdisk /mnt/initrd

(4)将根文件系统里的内容全部复制到/mnt/initrd目录下,命令如下。

cp _install/* /mnt/initrd -a

(5)卸载挂载点initrd,命令如下。

sudo umount /mnt/initrd

(6)用管理员权限压缩ramdisk为ramdisk.gz,命令如下。

sudo su -sudo gzip --best -c ramdisk > ramdisk.gz

(7)格式化为Uboot识别的格式,命令如下。

sudo mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip -a 0x41000000 -e 0x41000000 -d ramdisk.gz ramdisk.img

此时生成了一个名为ramdisk.img的文件,这个文件就是根文件系统映像文件。

Image Name: ramdiskCreated:Wed Jan 26 09:49:41 Image Type: ARM Linux RAMDisk Image (gzip compressed)Data Size: 3047940 Bytes = 2976.50 KiB = 2.91 MiBLoad Address: 41000000Entry Point: 41000000

如果提示错误:mkimage: Can't open ramdisk.: No such file or directory,那么先安装u-boot-tools。

sudo apt-get install u-boot-tools

根文件系统的两种格式 ↩︎

嵌入式 Linux根文件系统移植(二)——根文件系统简介 ↩︎

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。