root_fs文件系统结构分析和内核加载流程
目录
概述
1 根文件系统下目录介绍
2 文件系统内容分析
2.1 etc/inittab代码分析
2.2 /etc/init.d/rcS 代码分析
2.3 /etc/mdev.conf代码分析
2.3.1 功能概述
2.3.2 /etc/mdev.conf的详细代码
2.4 /etc/init.d/rcS的源代码文件
3 分析内核中加载root_fs的流程
3.1 调用入口一:vfs_caches_init
3.1.1 init_rootfs
3.1.2 init_mount_tree
3.1.2.1 vfs_kern_mount
3.1.2.2 配置root path
3.2 调用入口二: rest_init函数
3.2.1 函数调用关系
3.2.2 kernel_init函数
概述
本文主要详细分析了root_fs文件系统结构,对该文件目录下的每个类型的文件做了详细的介绍,并讲述各个文件的作用,其在内核中主要实现了什么功能,还介绍了内核加载root_fs的过程,详细跟踪了整个的加载流程,介绍每一个函数的调用关系。
1 根文件系统下目录介绍
嵌入式 Linux 中都需要构建根文件系统,构建根文件系统的规则在 FHS(Filesystem Hierarchy Standard)文档中,下面是根文件系统顶层目录。
目录名称 | 内容 |
---|---|
bin | 所有用户都可以使用的、基本的命令。 |
sbin | 基本的系统命令,它们用于启动系统、修复系统等。 |
usr | 共享、只读的程序和数据。 |
proc | 这是个空目录,常作为 proc 文件系统的挂载点。 |
dev | 该目录存放设备文件和其它特殊文件。 |
etc | 系统配置文件,包括启动文件。 |
lib | 存放共享库和可加载块(即驱动程序),共享库用于启动系统、运行根文件系统中的可执行程序。 |
boot | 引导加载程序使用的静态文件 |
home | 用户主目录,包括供服务账号锁使用的主目录,如 FTP |
mnt | 临时挂接某个文件系统的挂接点,通常是空目录。也可以在里面创建空的子目 录。 |
opt | 给主机额外安装软件所摆放的目录 |
root | root 用户的主目录 |
tmp | 存放临时文件,通常是空目录。 |
var | 存放可变的数据。 |
2 文件系统内容分析
默认的内核命令行上有 init=/linuxrc, 因此,在文件系统被挂载后,运行的第一个程序是根目录下的 linuxrc。 这是一个指向/bin/busybox 的链接,也就是说,系统起来后运行的第一个程序也就是 busybox 本身。
busybox首先将试图解析/etc/inittab 来获取进一步的初始化配置信息(参考 busybox 源代码 init/init.c 中)parse_inittab()函数。而事实上, root_qtopia 中并没有/etc/inittab 这个配置文件,根据 busybox 的逻辑,它将生成默认的配置 。
2.1 etc/inittab代码分析
查看busybox-1.13.3/init/init.c文件中parse_inittab()函数的源码:
代码第701行: new_init_action(SYSINIT, INIT_SCRIPT, ""),也就决定了接下去初始化的脚本是 INIT_SCRIPT 所定义的值。这个宏的默认值是"/etc/init.d/rcS".
#define INITTAB "/etc/inittab" /* inittab file location */
#ifndef INIT_SCRIPT
#define INIT_SCRIPT "/etc/init.d/rcS" /* Default sysinit script. */
#endif
parse_inittab() 函数的源代码
2.2 /etc/init.d/rcS 代码分析
该文件的路径: /etc/init.d/rcS。详细分析代码如下:
代码第3~5行: 为启动环境设置必要的环境变量
代码第13行: 设置机器的名称
代码第15~18行:
挂载“虚拟”文件系统“/proc”和“/sys”,并且在/dev 目录上挂载一个 ramfs,相当于把原本 NAND Flash 上的只读的/dev 目录“覆盖”上一块可写的空的 SDRAM。
/sys 和挂载了 ramfs 的/dev 是正确创建设备节点的关键。对于 2.6.29 内核来说,已经没有了 devfs 的支持,创建设备节点只有通过两种办法由文件系统完成:
1) 制作文件系统镜像前用 mknod 手动创建好系统中所有的(包括可能有的)设备节点, 并把这些节点文件一起做进文件系统镜像中;
2)在文件系统初始化过程中,通过/sys 目录所输出的信息,在/dev 目录下动态的创建 系统中当前实际有的设备节点
代码第20~22行:
1)通过 mdev -s 在/dev 目录下建立必要的设备节点;
2)设置内核的 hotplug handler 为 mdev, 即当设备热插拔时,由 mdev 接收 来自内核的消息并作出相应的回应, 比如挂载 U 盘。
对于 mdev,需要注意的是,文件系统里存在/etc/mdev.conf 文件,它包含了 mdev 的配置信息。
代码第24~35行:用来挂载其他一些常用的文件系统,并在/var 目录下(同样是ramfs,可写的)新建必要的目录。
代码第36行:用来设定系统时间的,从硬件 RTC 中获取,要获取正确的时间,必须先设置好正确的时间(如何设置 RTC 见用户手册说明)。
代码第39~54行:启动一系列服务:
服务类型 | 说明 |
---|---|
syslog | 用于记录内核和应用程序 debug 信息 |
netd - inetd | 一个挂载启动各种网络相关服务的看守进程 |
httpd - http server | 进程 |
leds | 跑马灯看守进程 |
代码47~48行:配置网络设备(网卡): 设定本机回环地址为 127.0.0.1 2)运行网卡设置脚本/etc/init.d/ifconfig-eth0
查看/etc/init.d/ifconfig-eth0 文件的内容:
#!/bin/sh
echo -n Try to bring eth0 interface up......>/dev/ttySAC0
if [ -f /etc/eth0-setting ] ; thensource /etc/eth0-setting
if grep -q "^/dev/root / nfs " /etc/mtab ; thenecho -n NFS root ... > /dev/ttySAC0elseifconfig eth0 downifconfig eth0 hw ether $MACifconfig eth0 $IP netmask $Mask uproute add default gw $Gatewayfi
echo nameserver $DNS > /etc/resolv.conf
else
if grep -q "^/dev/root / nfs " /etc/mtab ; thenecho -n NFS root ... > /dev/ttySAC0else/sbin/ifconfig eth0 192.168.1.230 netmask 255.255.255.0 upfi
fi
echo Done > /dev/ttySAC0
查看/etc/eth0-setting,源码如下:
2.3 /etc/mdev.conf代码分析
2.3.1 功能概述
在 /etc/mdev.conf文件查看源码:
1)原本串口驱动注册的设备名是 s3c2410_serial0, s3c2410_serial1 和s3c2410_serial2,而 mdev 则会在/dev 目录下对应生成 ttySAC0, ttySAC1 和 ttySAC2 以符合应用程序对于串口设备名称的习惯。
2) /dev/sdcard 和/dev/udisk 永远分别指向 SD 卡和U 盘的第一个分区。
3) 当 SD 卡或者 U 盘插入/拔出时,将这个消息传递给自定义的热插拔 handler, /bin/hotplug. 这个程序用于自动挂载可移动设备的,目前是 SD卡和 U 盘。它的逻辑很简单,将 SD 卡或者 U 盘的第一个分区作为 FAT/FAT32 挂载到/sdcard或者/udisk.
注意的问题:
当 SD 卡或者 U 盘上没有分区表或者第一个分区不是 FAT/FAT32 格式的时候,它就不能正常工作
2.3.2 /etc/mdev.conf的详细代码
# system all-writable devices
full 0:0 0666
null 0:0 0666
ptmx 0:0 0666
random 0:0 0666
tty 0:0 0666
zero 0:0 0666
# console devices
tty[0-9]* 0:5 0660
vc/[0-9]* 0:5 0660
# serial port devices
s3c2410_serial0 0:5 0666 =ttySAC0
s3c2410_serial1 0:5 0666 =ttySAC1
s3c2410_serial2 0:5 0666 =ttySAC2
s3c2410_serial3 0:5 0666 =ttySAC3
# loop devices
loop[0-9]* 0:0 0660 =loop/
# i2c devices
i2c-0 0:0 0666 =i2c/0
i2c-1 0:0 0666 =i2c/1
# frame buffer devices
fb[0-9] 0:0 0666
# input devices
mice 0:0 0660 =input/
mouse.* 0:0 0660 =input/
event.* 0:0 0660 =input/
ts.* 0:0 0660 =input/
# rtc devices
rtc0 0:0 0644 >rtc
rtc[1-9] 0:0 0644
# misc devices
mmcblk0p1 0:0 0600 =sdcard */bin/hotplug.sh
sda1 0:0 0600 =udisk * /bin/hotplug.sh
2.4 /etc/init.d/rcS的源代码文件
#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
#
# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
#
trap ":" INT QUIT TSTP
/bin/hostname FriendlyARM
/bin/mount -n -t proc none /proc
/bin/mount -n -t sysfs none /sys
/bin/mount -n -t usbfs none /proc/bus/usb
/bin/mount -t ramfs none /dev
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s
/bin/hotplug
# mounting file system specified in /etc/fstab
mkdir -p /dev/pts
mkdir -p /dev/shm
/bin/mount -n -t devpts none /dev/pts -o mode=0622
/bin/mount -n -t tmpfs tmpfs /dev/shm
/bin/mount -n -t ramfs none /tmp
/bin/mount -n -t ramfs none /var
mkdir -p /var/empty
mkdir -p /var/log
mkdir -p /var/lock
mkdir -p /var/run
mkdir -p /var/tmp
/sbin/hwclock -s
syslogd
/etc/rc.d/init.d/netd start
echo " " > /dev/tty1
echo "Starting networking..." > /dev/tty1
/etc/rc.d/init.d/leds start
echo " " > /dev/tty1
echo "Starting leds service..." > /dev/tty1
echo " "
/sbin/ifconfig lo 127.0.0.1
/etc/init.d/ifconfig-eth0
soundplayer /root/testsound.mp3&
/bin/rtm&
echo " " > /dev/tty1
echo "Starting MiniTest, please waiting..." > /dev/tty1
3 分析内核中加载root_fs的流程
内核的启动时从start_kernel()开始的,在该函数中调用vfs_caches_init() 和rest_init函数。其具体函数调用关系如下图所示:
3.1 调用入口一:vfs_caches_init
文件地址: \init\main.c
vfs_caches_init()所在的文件地址: \fs\dcache.c
在vfs_caches_init()函数中调用mnt_init()函数
mnt_init()函数所在文件地址:\fs\namespace.c
在mnt_init()函数中调用 init_rootfs()和init_mount_tree()初始化和挂载文件系统
函数调用关系如下:
3.1.1 init_rootfs
该函数所在的文件地址:fs\namespace.c
查看init_rootfs()的源码:
在init_rootfs函数中初始化RAM fs,函数调用关系:
3.1.2 init_mount_tree
在函数中匹配root_fs的类型;init_mount_tree()所在的文件地址:\fs\namespace.c
函数调用关系:
3.1.2.1 vfs_kern_mount
init_mount_tree()函数调用vfs_kern_mount()函数挂载文件系统
在vfs_kern_mount()函数中调用mount_fs(),函数中的调用关系
3.1.2.2 配置root path
在init_mount_tree()中还调用两个重要的函数:
代码3090行: set_fs_pwd()
代码3091行: set_fs_root()
3.2 调用入口二: rest_init函数
3.2.1 函数调用关系
函数调用关系:
函数rest_init中的细节如下:
代码394行: 该线程调用kernel_init,初始化root_fs其他的参数
3.2.2 kernel_init函数
函数调用关系:
kernel_init()的详细代码如下:
相关文章:

root_fs文件系统结构分析和内核加载流程
目录 概述 1 根文件系统下目录介绍 2 文件系统内容分析 2.1 etc/inittab代码分析 2.2 /etc/init.d/rcS 代码分析 2.3 /etc/mdev.conf代码分析 2.3.1 功能概述 2.3.2 /etc/mdev.conf的详细代码 2.4 /etc/init.d/rcS的源代码文件 3 分析内核中加载root_fs的流程 3.1 调…...

macOS系统配置RUST开发环境
打开rust语言官方网,然后点击马上开始: Rust 程序设计语言 配置RUST开发环境: 使用curl下载rust安装脚本: 复制到终端执行: curl --proto =https --tlsv1.2 -sSf https://sh.rustup.rs | sh 输入: y 选择默认安装,输入: 1...
Android 15全面解读:性能飙升、隐私守护与智能生活新纪元
1. 更强大的性能 Android 15 带来了一系列性能方面的改进,以确保您的设备在运行应用程序时能够更加流畅。通过对系统进行优化,Android 15 在响应速度和性能方面都有了显著的提升。 这些优化包括: 新一代处理器支持: Android 15 …...

Java项目:80 springboot师生健康信息管理系统
作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统的角色:管理员、宿管、学生 管理员管理宿管员,管理学生,修改密码,维护个人信息。 宿管员…...
云服务器配置 docker-spark
云服务器配置 docker-spark 1. 安装2. 启动3. 查看4. 验证5. 其他 1. 安装 我的服务器是腾讯云轻量应用服务器,2 核 2 G,已经内置了 docker, 配置大概如下: ubuntuVM-20-5-ubuntu --------------------- OS: Ubuntu 22.04 LTS x…...

Matlab之求直角坐标系下两直线的交点坐标
目的:在直角坐标系下,求两个直线的交点坐标 一、函数的参数说明 输入参数: PointA:直线A上的点坐标; AngleA:直线A的倾斜角,单位度; PointB:直线B上的点坐标…...

Python3:ModuleNotFoundError: No module named ‘elftools‘
问题背景 问题 ModuleNotFoundError: No module named ‘elftools’ 解决方法 pip3 install pyelftools 成功!!!...
【Vue】创建vue项目 npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED
在安装完vue后,一段时间后发现再次使用出错;感觉可能是使用了代理的原因,但是就算关闭了代理一样不行;最后重启大法解决。 此处记录解决时使用到的命令。 检查版本 node -v cnpm -v vue --version vue -V安装 npm install -g vu…...
5、Cocos Creator 动作系统
目录 1、动作系统 API 2、动作系统 API 3、缓动动作 4、参考 动作系统并不能取代动画系统,动作系统提供的是面向程序员的 API 接口,而动画系统则是提供在编辑器中来设计的。它们服务于不同的使用场景,动作系统比较适合来制作简单的形变和…...
web3 token 如何理解
"Web3 Token"是指建立在Web3技术堆栈上的数字令牌。为了更好地理解这个概念,让我们逐步解释: Web3:指的是下一代互联网(Web3.0),它是基于区块链技术的去中心化网络。Web3的核心理念是去中心化、安…...
unity pivot和center的区别
在Unity中,“pivot” 和 “center” 是两个在物体变换和编辑过程中经常提到的概念,它们表示物体的不同位置或者参考点。下面是它们的区别: Pivot(中心点): Pivot 是物体的旋转和缩放的参考点。在 Unity 中&…...

Python学习笔记-简单案例实现多进程与多线程
Python 的多进程与多线程是并发编程的两种重要方式,用于提高程序的执行效率。它们各自有不同的特点和适用场景。 多进程(Multiprocessing) 概念: 多进程是指操作系统中同时运行多个程序实例,每个实例称为一个进程。…...
python常用的语法
Python是一种高级、通用、解释型的编程语言,具有简洁、易于阅读和理解的语法。以下是Python中常用的语法: 变量定义和赋值: variable value输出内容: print("Hello, World!")条件判断: if condition:# 条件…...
【计算机网络】概述
📝本文介绍 本文为计算机网络的概述,会综合概述一下计算机网络 👋作者简介:一个正在积极探索的本科生 📱联系方式:943641266(QQ) 🚪Github地址:https://github.com/sankexilianhua &…...
【Flink connector】文件系统 SQL 连接器:实时写文件系统以及(kafka到hive)实战举例
文章目录 一. 滚动策略:sink后文件切分(暂不关注)1. 切分分区目录下的文件2. 小文件合并 二. 分区提交1. 分区提交触发器 (什么时候创建分区)1.1. 逻辑说明1.2. 举例说明 2. 分区时间提取器 (用于partition-time情况下partition commit策略)2…...
RpcContext :提供了在 RPC 调用过程中访问当前调用信息的方法
在 Dubbo 中,RpcContext 是一个上下文对象,它提供了在 RPC 调用过程中访问当前调用信息的方法。RpcContext.getClientAttachment() 方法用于获取客户端设置的附件(Attachment)信息。这些附件信息通常是在 RPC 调用发起方ÿ…...
机器学习 - 提高模型 (代码)
如果模型出现了 underfitting 问题,就得提高模型了。 Model improvement techniqueWhat does it do?Add more layersEach layer potentially increases the learning capabilities of the model with each layer being able to learn some kind of new pattern in…...
数值代数及方程数值解:预备知识——二进制及浮点数
文章目录 二进制IEEE浮点数 本篇文章的前置知识:数学分析 二进制 命题:二进制转化为十进制 二进制的数字表示为 ⋯ b 2 b 1 b 0 . b − 1 b − 2 ⋯ \cdots b_2b_1b_0.b_{-1}b_{-2}\cdots ⋯b2b1b0.b−1b−2⋯这等价于十进制下的 ⋯ b 2 2 …...

新数字时代的启示:揭开Web3的秘密之路
在当今数字时代,随着区块链技术的不断发展,Web3作为下一代互联网的概念正逐渐引起人们的关注和探索。本文将深入探讨新数字时代的启示,揭开Web3的神秘之路,并探讨其在未来的发展前景。 1. Web3的定义与特点 Web3是对互联网未来发…...

算法——动态规划:01背包
原始01背包见下面这篇文章:http://t.csdnimg.cn/a1kCL 01背包的变种:. - 力扣(LeetCode) 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 简化一…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...