根文件系统制作过程_linux开发板推荐

根文件系统制作过程_linux开发板推荐文件系统是对一个上的数据和元数据进行,这种机制有利于在Linux没有文件系统的话,用户和操作系统的交互也就断开了

目录

一、根文件系统介绍

二、根文件系统移植

1、buildroot下载

2、根文件系统制作

3、根文件系统移植

4、根文件系统加载

5、mmc设备问题分析

6、mmc功能开启

7、设备树编译与下载

三、参考内容


一、根文件系统介绍

文件系统是对一个存储设备上的数据和元数据进行组织的机制,这种机制有利于用户和操作系统的交互。在Linux没有文件系统的话,用户和操作系统的交互也就断开了。

Unix没有盘符的概念,要求自己的文件系统是单一的一棵树。直接挂载在整棵树根上的那个盘里面的文件系统,就是根文件系统。

文件系统不是指某一个文件系统类型,而是指任何可以将文件目录组织成特定系统所需结构的文件系统,然后把它挂载在系统的上。

Linux中的根文件系统像是一个文件夹管理系统,或者说像是一本书的目录,在某种意义上讲,根文件系统就是一个文件夹,只不过是这是一个特殊的文件夹,在这个目录里面会有很多的子目录,如下图所示。

根文件系统制作过程_linux开发板推荐

根文件系统制作过程_linux开发板推荐

下面是虚拟机中Ubuntu系统的根文件系统,根文件系统的目录名字为 ‘/’ ,也就是一个斜杠,各个目录的功能在下面的表格中做了详细介绍。

根文件系统制作过程_linux开发板推荐

Item Description
/ (root filesystem) 根文件系统是文件系统的最高级别目录。在其他文件系统被挂载之前,它必须包含启动Linux系统所需的所有文件。它必须包括启动其余文件系统所需的所有可执行文件和库。在系统启动后,所有其他文件系统都被挂载在标准的、定义明确的挂载点上,作为根文件系统的子目录。
/bin /bin目录包含用户可执行文件。
/boot 包含启动Linux计算机所需的静态引导程序和内核可执行文件以及配置文件。
/dev 这个目录包含了连接到系统的每个硬件设备的设备文件。这些不是设备驱动程序,而是代表计算机上每个设备的文件,并为访问这些设备提供便利。
/etc 包含主机的本地系统配置文件。
/home 用户文件的主目录存储。每个用户都有一个/home的子目录。
/lib 包含启动系统所需的共享库文件。
/media 一个安装外部可移动媒体设备的地方,如可能连接到主机的USB拇指驱动器。
/mnt 普通文件系统(如不是可移动媒体)的临时挂载点,可以在管理员修复或处理文件系统的时候使用。
/opt 可选的文件,如供应商提供的应用程序应位于这里。
/root 这不是根(/)文件系统。它是根用户的主目录。
/sbin 系统二进制文件。这些是用于系统管理的可执行文件。
/tmp 临时目录。由操作系统和许多程序用来存储临时文件。用户也可以在这里临时存储文件。请注意,存储在这里的文件可能在任何时候被删除,而无需事先通知。
/usr 这些是可共享的、只读的文件,包括可执行的二进制文件和库、人文件和其他类型的文件。
/var 可变的数据文件被存储在这里。这可以包括像日志文件、MySQL和其他数据库文件、网络服务器数据文件、电子邮件收件箱,以及更多的东西。

二、根文件系统移植

1、buildroot下载

我们使用buildroot制作根文件系统,之前imx6ull使用的busybox,这里换一下,哈哈,首先进入官网,下载根文件系统buildroot2018.2.11版本,与墨云保持一致,下载后放到Ubuntu中解压。https://buildroot.org/download.htmlhttps://buildroot.org/download.html

根文件系统制作过程_linux开发板推荐

这个网站比较友好,不需要魔法,buildroot体积较小,直接下载即可,下面是几个不同后缀的文件。

根文件系统制作过程_linux开发板推荐

 上面的四个选项,下载后是下面的文件,sign是什么文件我不清楚,嘿嘿,欢迎评论区指出,选择一个压缩包,到Ubuntu中解压

根文件系统制作过程_linux开发板推荐

2、根文件系统制作

 解压完成后进入根目录,清理工程后,进入图形界面配置:

make clean make menuconfig

图形配置界面如下图所示,使用方向键选择不同选项,空格进行选中,回车进行确认。

根文件系统制作过程_linux开发板推荐

Target options选项的配置如下图所示,每个选项的含义墨云解释过了,我就不造轮子了。  

根文件系统制作过程_linux开发板推荐

  • 第一个选项为架构选择,这里选择ARM架构小端模式,
  • 第二个为输出的二进制文件格式,这里选择EFL格式,
  • 第三个为架构体系,这里选择arm926t,因为F1C200S/F1C100S的架构就是这个架构,
  • 第四个为矢量浮点处理器,这里不勾选,因为对于F1C200S/F1C100S而言,其内部没有浮点运算单元,只能进行软浮点运算,也就是模拟浮点预运算。
  • 第五个为应用程序二进制接口,这里选择EABI,原因是该格式支持软件浮点和硬件实现浮点功能混用。
  • 第六个为浮点运算规则,这里使用软件浮点
  • 第七个选择指令集,这里选择ARM指令集,因为thumb主要针对Cortex M系列而言的,对于运行操作系统的A系列以及ARM9和ARM11而言,使用的都是32位的ARM指令集。

来自:小白自制Linux开发板 三. Linux内核与文件系统移植 – 淡墨青云 – 博客园

据说Toolchain按照下方配置(打开了一些功能)可以在开发板上直接编译程序。 

根文件系统制作过程_linux开发板推荐

登录的时候会显示 “Wecome to kashine linux system.” ,并且我们设置了root用户密码为“good luck!”。

根文件系统制作过程_linux开发板推荐

配置完成后,使用make命令进行编译,从下面可以看出,buildroot的编译需要网络支持,以通过网络配置我们选择的内容。 当然如果你的虚拟机无法连接网络,请看虚拟机ubuntu桥接怎么联网,或者是虚拟机net模式访问互联网。

根文件系统制作过程_linux开发板推荐

此处是漫长的等待……….,建议来一道力扣中等!复杂链表的复制!力扣https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/?envType=study-plan&id=lcof&plan=lcof&plan_progress=y16046r

这个下载速度真的是奇慢无比!如果下载依赖包或者软件速度非常慢,可以尝试(不要试了,我试过不管用,哈哈)Ubuntu20.04换源之后依旧慢?Ubuntu16.04找不到Software&Updates(软件更新),但我试了一下仍然很慢,这不科学呀!魔法也不管用。

根文件系统制作过程_linux开发板推荐

终于编译完成了!已经是第二天了,昨天搞到1:00还没有编译完,我就直接挂起虚拟机,今天早晨打开Ubuntu没大会,就已经编译完成了,大概两个多小时。编译完成后,在buildroot根目录的output/images目录下生成一个rootfs.rar文件这个就是我们心心念念的根文件系统。

根文件系统制作过程_linux开发板推荐

注意:第二次编译就会快很多,比如误删,别问我怎么知道的,唔哈哈哈。 

 3、根文件系统移植

将上面得到的rootfs.rar解压到TF卡的第二个分区,也就是rootfs分区,不要解压完成在复制过去,因为解压出来好多文件夹。两种选择,要么把压缩包复制到rootfs分区,解压后删除压缩包,要么直接解压到第二分区。使用如下命令将压缩包解压到rootfs分区后如下图所示:

sudo tar -vxf rootfs.tar -C /media/project01/rootfs/

根文件系统制作过程_linux开发板推荐

其中tar解压缩命令格式如下:

选项 含义
-x 对 tar 包做解打包操作。
-f 指定要解压的 tar 包的包名。
-t 只查看 tar 包中有哪些文件或目录,不对 tar 包做解打包操作。
-C 目录 指定解打包位置。
-v 显示解打包的具体过程。

4、根文件系统加载

TF卡第二个分区内已经放置了我们制作好的根文件系统,将TF卡插到开发板上并上电启动,打开串口调试助手,设置波特率,可以看到下面的内容,uboot和内核启动成功。

根文件系统制作过程_linux开发板推荐

但是并没有启动Linux的根文件系统,我们看最后打印出的提示代码为: Waiting for root device /dev/mmcblk0p2…,看来是mmcblk0p2表示mmc设备(MultiMedia Card,多媒体存储卡)没有被内核启动成功,mmcblk0是我们的TF卡,p2代表第二个分区,我们最终确定是mmc设备出了问题。

根文件系统制作过程_linux开发板推荐

 5、mmc设备问题分析

我们先来分析一下出现这个问题的原因,如果说mmcblk0p2设备出现问题,那么为什么在启动Linux内核的时候没有出错的,内核文件和设备树文件存放在mmcblk0p1中,如果是mmcblk0p2加载出错,也就表示TF卡的设备树或者是驱动出了问题,那么mmcblk0p1不应该也是错的吗?那Linux内核不应该能够启动才对的?

小朋友,你是否有很多问号?好的,现在来说一下我对上面问题的理解。其实上面的问题有点不太对,不知道大家是否有相同的疑问,所以我对上面也进行了保留。下面分析:首先是uboot的启动,在TF卡的8k处,我们硬件没有问题,也就是说TF卡接在F1C200s的指定引脚,bootROM启动的时候一定会读取TF卡的8k位置,成功启动uboot,而在uboot启动后,进入倒计时,倒计时结束后,执行bootcmd命令,bootcmd命令如下所示:

load mmc 0:1 0x zImage;load mmc 0:1 0x80c08000 suniv-f1c100s-licheepi-nano.dtb;bootz 0x - 0x80c08000;

该命令的主要作用是将zImage和设备树从mmc的第一个分区拷贝到内存中执行,这个应该好理解哈,Linux内核启动成功了,说明uboot能够将两个文件拷贝到内存中执行,进一步说明uboot的TF卡驱动是没有问题的,拷贝结束后,uboot生命周期结束,Linux内核启动,但是Linux内核TF卡启动出错,导致无法加载TF卡第二分区中的根文件系统。

至此,我们大致分析出导致无法启动Linux根文件系统的原因是:TF卡设备树或者驱动出错。对于设备树来讲,我们只需要提供对应的硬件信息,即可在不同的开发板可以使用相同的驱动。形象一点讲就是:对某个LED点灯程序(驱动),我宏定义了一个LED管脚(设备树),程序是官方给的,也就是说确定这个程序可以点灯,现在我们将这套程序放到另一个相同主控的开发板上运行,出问题的话就很可能是我们的宏定义出错了,也就是说,很可能是设备树出错。

通过上面的分析,我们怀疑很可能是设备树出了问题那下面我们对设备树进行检查。首先介绍一下设备树相关文件,打开/arch/arm/boot/dts可以看到我们我们前面拷贝到TF卡KERNEL分区的设备树文件,其中.dtsi文件为“头文件”,储存一个主控芯片的共同信息,供针对相同主控芯片不同开发板的设备树源文件.dts文件调用,编译后生成设备树文件.dtb。

根文件系统制作过程_linux开发板推荐

打开/arch/arm/boot/dts目录下的suniv-f1c100s-licheepi-nano.dts、suniv-f1c100s.dtsi,在dtsi文件中并没有发现mmc的内容,也就是如orange2c所说,是因为我们使用的主线Linux内核源码,而主线Linux设备树中并没有开启mmc。

6、mmc功能开启

参考荔枝派设备树源码,进行以下修改。首先添加头文件:

#include <dt-bindings/clock/suniv-ccu-f1c100s.h> #include <dt-bindings/reset/suniv-ccu-f1c100s.h>

然后在soc结点下的pio添加如下代码,其中PF0、PF1、PF2、PF3、PF4、PF5为TF卡相关引脚,详见(四)根文件系统–从零开始自制linux掌上电脑(F1C200S)<嵌入式项目>。

mmc0_pins: mmc0-pins { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; function = "mmc0"; };

在soc结点下添加如下代码,使用pinctrl子系统初始化引脚,其中compatible变量保存着mmc对应的驱动。其他时钟总线之类的我就不详细解释了,因为我也不懂,哈哈。但是一定要注意,.dtsi文件里面是默认关闭mm功能的(可以看到下面的status是disabled状态),需要在.dts里面使能。

mmc0: mmc@1c0f000 { compatible = "allwinner,suniv-f1c100s-mmc", "allwinner,sun7i-a20-mmc"; reg = <0x01c0f000 0x1000>; clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>, <&ccu CLK_MMC0_OUTPUT>, <&ccu CLK_MMC0_SAMPLE>; clock-names = "ahb", "mmc", "output", "sample"; resets = <&ccu RST_BUS_MMC0>; reset-names = "ahb"; interrupts = <23>; pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; };

 .dtsi文件修改完成后如下所示:

// SPDX-License-Identifier: (GPL-2.0+ OR X11) /* * Copyright 2018 Icenowy Zheng <icenowy@aosc.io> * Copyright 2018 Mesih Kilinc <mesihkilinc@gmail.com> */ // modify by kashine #include <dt-bindings/clock/suniv-ccu-f1c100s.h> #include <dt-bindings/reset/suniv-ccu-f1c100s.h> / { #address-cells = <1>; #size-cells = <1>; interrupt-parent = <&intc>; clocks { osc24M: clk-24M { #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <>; clock-output-names = "osc24M"; }; osc32k: clk-32k { #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <32768>; clock-output-names = "osc32k"; }; }; cpus { cpu { compatible = "arm,arm926ej-s"; device_type = "cpu"; }; }; soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; sram-controller@1c00000 { compatible = "allwinner,suniv-f1c100s-system-control", "allwinner,sun4i-a10-system-control"; reg = <0x01c00000 0x30>; #address-cells = <1>; #size-cells = <1>; ranges; sram_d: sram@10000 { compatible = "mmio-sram"; reg = <0x00010000 0x1000>; #address-cells = <1>; #size-cells = <1>; ranges = <0 0x00010000 0x1000>; otg_sram: sram-section@0 { compatible = "allwinner,suniv-f1c100s-sram-d", "allwinner,sun4i-a10-sram-d"; reg = <0x0000 0x1000>; status = "disabled"; }; }; }; ccu: clock@1c20000 { compatible = "allwinner,suniv-f1c100s-ccu"; reg = <0x01c20000 0x400>; clocks = <&osc24M>, <&osc32k>; clock-names = "hosc", "losc"; #clock-cells = <1>; #reset-cells = <1>; }; intc: interrupt-controller@1c20400 { compatible = "allwinner,suniv-f1c100s-ic"; reg = <0x01c20400 0x400>; interrupt-controller; #interrupt-cells = <1>; }; pio: pinctrl@1c20800 { compatible = "allwinner,suniv-f1c100s-pinctrl"; reg = <0x01c20800 0x400>; interrupts = <38>, <39>, <40>; clocks = <&ccu 37>, <&osc24M>, <&osc32k>; clock-names = "apb", "hosc", "losc"; gpio-controller; interrupt-controller; #interrupt-cells = <3>; #gpio-cells = <3>; uart0_pe_pins: uart0-pe-pins { pins = "PE0", "PE1"; function = "uart0"; }; // modify by kashine mmc0_pins: mmc0-pins { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; function = "mmc0"; }; }; timer@1c20c00 { compatible = "allwinner,suniv-f1c100s-timer"; reg = <0x01c20c00 0x90>; interrupts = <13>; clocks = <&osc24M>; }; wdt: watchdog@1c20ca0 { compatible = "allwinner,suniv-f1c100s-wdt", "allwinner,sun4i-a10-wdt"; reg = <0x01c20ca0 0x20>; }; uart0: serial@1c25000 { compatible = "snps,dw-apb-uart"; reg = <0x01c25000 0x400>; interrupts = <1>; reg-shift = <2>; reg-io-width = <4>; clocks = <&ccu 38>; resets = <&ccu 24>; status = "disabled"; }; uart1: serial@1c25400 { compatible = "snps,dw-apb-uart"; reg = <0x01c25400 0x400>; interrupts = <2>; reg-shift = <2>; reg-io-width = <4>; clocks = <&ccu 39>; resets = <&ccu 25>; status = "disabled"; }; uart2: serial@1c25800 { compatible = "snps,dw-apb-uart"; reg = <0x01c25800 0x400>; interrupts = <3>; reg-shift = <2>; reg-io-width = <4>; clocks = <&ccu 40>; resets = <&ccu 26>; status = "disabled"; }; // modify by kashine mmc0: mmc@1c0f000 { compatible = "allwinner,suniv-f1c100s-mmc", "allwinner,sun7i-a20-mmc"; reg = <0x01c0f000 0x1000>; clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>, <&ccu CLK_MMC0_OUTPUT>, <&ccu CLK_MMC0_SAMPLE>; clock-names = "ahb", "mmc", "output", "sample"; resets = <&ccu RST_BUS_MMC0>; reset-names = "ahb"; interrupts = <23>; pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; }; }; }; 

 在.dts文件里面进行以下修改,首先使能mmc:

&mmc0 { vmmc-supply = <&reg_vcc3v3>; bus-width = <4>; broken-cd; status = "okay"; };

然后这个是墨云在根节点下添加的一个结点,他并没有说明为什么添加,我百度了一下,这是一个电源管理相关的结点,使用regulator-fixed来实现使用GPIO控制某个电源开关 ,希望在开机时尽快输出高低电平来控制电源。详见。Rockchip RK3588 kernel dts解析之regulator-fixed。

reg_vcc3v3: vcc3v3 { compatible = "regulator-fixed"; regulator-name = "vcc3v3"; regulator-min-microvolt = <>; regulator-max-microvolt = <>; };

.dts文件修改完成之后下所示:

// SPDX-License-Identifier: (GPL-2.0+ OR X11) /* * Copyright 2018 Icenowy Zheng <icenowy@aosc.io> */ /dts-v1/; #include "suniv-f1c100s.dtsi" / { model = "Lichee Pi Nano"; compatible = "licheepi,licheepi-nano", "allwinner,suniv-f1c100s"; aliases { serial0 = &uart0; }; chosen { stdout-path = "serial0:n8"; }; // modify by kashine reg_vcc3v3: vcc3v3 { compatible = "regulator-fixed"; regulator-name = "vcc3v3"; regulator-min-microvolt = <>; regulator-max-microvolt = <>; }; }; &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pe_pins>; status = "okay"; }; // modify by kashine &mmc0 { vmmc-supply = <&reg_vcc3v3>; bus-width = <4>; broken-cd; status = "okay"; }; 

7、设备树编译与下载

在Linux内核根目录下,使用以下命令重新编译设备树,内核无需重新编译。

make dtbs

在内核源码根目录使用make dtbs编译变成后生成设备树文件,如下图所示。

根文件系统制作过程_linux开发板推荐

编译完成后,将新的设备树文件(.dtb)拷贝到TF卡的第二分区,zImage无需修改,打开串口调试助手,上电复位,成功启动根文件系统!!!,成功打印出“Welcome to kashine linux system.”,root为管理员用户名,密码为前面设置的“good luck!”,将路径切换到根目录之后,查看根目录的文件夹,如下图所示。

根文件系统制作过程_linux开发板推荐

 在上电成功启动根文件系统之后,不要直接拔掉USB断电,可能造成根文件系统损坏,使用poweroff命令关闭根文件系统后断电。

根文件系统制作过程_linux开发板推荐


三、参考内容

1. 墨云uboot移植;

2. 正点原子《嵌入式Linux驱动开发指南》      


根文件系统制作过程_linux开发板推荐

今天的文章
根文件系统制作过程_linux开发板推荐分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/80679.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注