一、动态更改内核
1、low level(静态修改)
【1】将led_drv.c拷贝到kernel/drivers/char/目录中
【2】修改当前目录下的Makefile文件
obj-y += led_drv.o #将新添加的驱动文件加入到Makefile文件中
【3】退回kernel目录,执行make uImage
2、high level(动态修改)
【1】通过make menuconfig影响编译
【2】通过修改Kconfig文件,影响menuconfig选项的更改
1)打开Kconfig文件
vim kernel/drivers/char/Kconfig
2)增加一个选项
3)打开menuconfig验证
make menuconfig
4)修改Makefile文件
vim kernel/drivers/char/Makefile
5)验证
1】禁用LED灯,修改make menuconfig
Device Drivers --->
Character devices --->
< > MY LEDS DRIVER
2】查看.config文件确认是否禁用成功
vim kernel/.config
3】重新编译内核
make uImage
4】下位机验证
cp arch/arm/boot/uImage /tftpboot/
之前的图:
现在的图:
5】总结
二、根文件系统
1、 文件系统
存储文件的有效数据 + 索引 + 操作索引的代码
有效数据:文件的内容
索引:文件的路径+ 文件名
操作索引的代码:命令
2、根文件系统
文件的有效数据 + 索引 + 操作索引的代码
根文件系统是Linux内核启动后挂载的第一个真实的文件系统
/proc:虚拟的文件系统,存储进程号等相关信息
/sys:虚拟的文件系统,存储系统相关的信息
3、特殊需求
根文件系统中存放的文件是有特殊需求的
1号进程对应的程序
etc:配置文件和初始化执行的文件
bin:可执行程序
sbin:基本的系统管理程序
lib:基本的库文件
opt:附加的软件包
。。。
4、制作根文件系统
1)busybox工具
官网:https://busybox.net/
busybox被称为嵌入式领域的瑞士军刀,体积小、功能强悍,它是一个集成了很多最常用的Linux命令和工具的软件,包含了常用的命令,如:cd、ls、cp、mv、echo。。。
简单来说,busybox集成了Linux所需的基本内容。
2)准备系统所需命令
ls、cd、touch、du、file、fine。。。编译busybox源码就可以自动生成
【1】解压busybox源码
tar -xvf busybox-1.21.1.tar.bz2 -C ./
【2】进入busybox-1.21.1
【3】修改Makefile文件
vim Makefile
【4】配置menuconfig
make menuconfig
【5】编译
make
【6】安装
make install // 安装到busybox源码的_install目录中
3)准备系统所需的库文件
【1】上位机与下位机体积差别
【2】原因
busybaox生成的命令都是busybox文件的符号链接文件,并且生成的命令并不全,是PC机的精简版。
【3】分析busybox程序
【4】查找依赖库文件
which arm-cortex_a9-linux-gnueabi-gcc
cd /opt/toolchains/arm-cortex_a9-eabi-4.7-eglibc-2.18/
find -name libc.so.6
cd ./arm-cortex_a9-linux-gnueabi/sysroot/lib/
【5】将链接与源文件一同拷贝到_install/lib目录
mkdir lib
ld-2.18-2013.10.so
ld-linux.so.3
链接器 libc-2.18-2013.10.so
libc.so.6
C标准库 libm-2.18-2013.10.so
libm.so.6
数学库
4)准备系统所需的配置文件
【1】在_install目录中创建etc目录
mkidr etc
【2】分析
在uboot中的bootargs环境变量有过init=/linuxrc,linuxrc就是1号进程对应的程序,我们需要在etc目录中对其进行配置,仿照着busybox的源码。
vim init.c
【3】写初始化表(inittab)
vim etc/inittab
----------------------
初始化表的格式说明:
id:runlevel:action:process
id:空着不写使用默认id
runlevel:内核运行的等级
action:执行的动作
process:执行的操作
----------------------
【4】创建初始化脚本(rcS)
mkdir etc/init.d
touch etc/init.d/rcS
【5】修改权限
chmod 777 rcS
【6】编写脚本
vim etc/init.d/rcS
【7】编写分区文件(fstab)
touch etc/fstab
vim etc/fstab
----------------------
分区表的格式说明:
fs mp type ops dump pass
fs:文件系统(file system),要加载的文件系统
mp:挂载点(mount point),文件系统要挂载的目录
type:类型(type),文件系统的类型
ops:选项(options),加载文件系统时需要使用的特定参数选项
dump:转储(dump),是否对该分区进行备份(0-不备份,1-备份)
pass:通过(pass),是否对该分区进行检查(0-不检查,1-前期检查,2-后期检查)
----------------------
5)准备其他的必要目录
mkdir home proc mnt var opt tmp sys dev lib/modules
6)创建两个必要的设备文件
sudo mknod dev/console c 5 1 // 控制终端文件(控制台)
sudo mknod dev/null c 1 3 // 黑洞文件(放进去的文件会泯灭)
------------------------------
mknod命令创建特殊文件
sudo mknod 设备文件名 设备类型 主设备号 次设备号
设备类型:
1】b 块设备文件(存储类设备-磁盘\U盘\软盘\硬盘)
2】c字符设备文件(非存储类设备-led灯\蜂鸣器\按键。。。)
3】p管道文件(命名管道)
注意:命名管道还可以使用mkfifo命令创建
主设备号:
被系统用来确定驱动程序类型
次设备号:
被驱动程序用来确定具体的设备
------------------------------
7)验证根文件系统
使用nfs挂载根文件系统
【1】修改上位机nfs服务的配置文件
sudo vim /etc/exports
【2】重启nfs服务
sudo service nfs-kernel-server restart
【3】关闭防火墙
sudo service ufw stop
【4】修改下位机的bootargs环境变量
setenv bootargs root=/dev/nfs nfsroot=192.168.1.8:/nfs_share/_install ip=192.168.1.6:192.168.1.8:192.168.1.1:255.255.255.0 init=/linuxrc console=ttySAC0,115200 maxcpus=1 lcd=wy070ml tp=gslx680-linux
【5】保存环境变量并重启
saveenv
re
三、各种根文件系统的特性
-----------------------------------
存储类介质的区别
rom、prom、eprom、eeprom
flash、nor-flash、nand-flash
mmc、emmc
-----------------------------------
文件系统 | 制作工具 | 说明 |
jffs2 | mkfs.jffs2 | 针对nor-flash开发的文件系统,智龙、树莓派、双椒派 |
yaffs | mkfs.yaffs | 针对nand-flash开发的文件系统 |
cramfs | mkfs.cramfs | 针对Linux开发,压缩的只读文件系统 |
1、cramfs类型的根文件系统
1)配置linux内核,让内核支持 cramfs 系统
【1】进入Linux内核源码的根目录
cd kernel
【2】进入make menuconfig配置界面
make menuconfig
【3】找到支持文件系统选项
【4】编译内核
make uImage
【5】将uImage拷贝至tftp共享目录
【6】下位机烧写uImage
tftp 48000000 uImage
mmc write 48000000 2000 3000
setenv bootcmd mmc read 48000000 2000 3000 \; bootm 48000000
saveenv
re
2)制作 cramfs 类型的根文件系统
【1】进入到busybox源码的根目录下
cd busybox-1.21.1
【2】制作 cramfs 文件系统镜像
sudo mkfs.cramfs _install/ rootfs.cramfs
【3】查看信息
file rootfs.cramfs
du -h rootfs.cramfs
3)验证 cramfs 类型的文件系统是否可用
【1】上位机把 rootfs.cramfs 拷贝至 tftp 共享目录
cp rootfs.cramfs /tftpboot
【2】下位机烧写rootfs.cramfs文件系统
tftp 48000000 rootfs.cramfs
mmc write 48000000 22000 1000
setenv bootargs root=/dev/mmcblk0p2 rootfstype=cramfs init=/linuxrc console=ttySAC0,115200 maxcpus=1 lcd=wy070ml tp=gslx680
saveenv
re
【3】查看结果
cramfs类型的根文件系统是只读的
2、ext4类型的根文件系统
ext4是我们的手机、电脑、平板会经常使用的文件系统的类型
除了ext4以外,还有fuse、fat等文件系统
/mnt:linux系统默认用来挂载的目录
-------------------------
mount:用于挂载的命令,直接录入mount,查看挂载信息
umount:用于卸载的命令
-------------------------
1)配置linux内核,让内核支持 ext4 系统
【1】进入Linux内核源码的根目录
cd kernel
【2】进入make menuconfig配置界面
make menuconfig
【3】编译内核
make uImage
【4】将uImage拷贝至tftp共享目录
【5】下位机烧写uImage
tftp 48000000 uImage
mmc write 48000000 2000 3000
setenv bootcmd mmc read 48000000 2000 3000 \; bootm 48000000
saveenv
re
2)制作 ext4 类型的根文件系统
【1】进入到busybox源码的根目录下
cd busybox-1.21.1
【2】制作空文件
dd if=/dev/zero of=rootfs.ext4 bs=1k count=8192
-------------------------
if:input file源数据文件
of:output file目标文件
bs:一次读取的字节数
count:连续读写多少次
命令效果:创建了一个8MB的文件,文件里面的都是0
-------------------------
【3】查看信息
hexdump -C rootfs.ext4
-------------------------
hexdump:以十六进制查看文件内容
-C:输出规范的十六进制和ASCII的形式
-------------------------
【4】把空文件格式化为 ext4 类型
mkfs.ext4 rootfs.ext4
【5】挂在该分区
sudo mkdir /mnt/zjd_ext4 // 创建挂载点
sudo mount -t ext4 rootfs.ext4 /mnt/zjd_ext4 // 挂载文件
mount // 查看是否挂载成功
【6】将根文件系统数据拷贝到该分区
sudo cp _install/* /mnt/zjd_ext4/ -a
【7】卸载
sudo umount /mnt/zjd_ext4
注意:卸载之后一定要用 mount 再查看一下
3)验证 ext4 类型的文件系统是否可用
【1】上位机把 rootfs.ext4 拷贝至 tftp 共享目录
cp rootfs.cramfs /tftpboot
【2】下位机烧写 rootfs.ext4 文件系统
tftp 48000000 rootfs.ext4
mmc write 48000000 22000 4000
setenv bootargs root=/dev/mmcblk0p2 rootfstype=ext4 init=/linuxrc console=ttySAC0,115200 maxcpus=1 lcd=wy070ml tp=gslx680
saveenv
re
【3】查看结果
【4】分析原因
在Ubuntu20.04中使用mkfs.ext4指定文件系统类型时,指定的参数在旧的内核中是不被支持的,报出的错误码为400
解决方法:去掉旧的内核不支持的特性
cd /tftpboot
tune2fs -O ^metadata_csum rootfs.ext4
e2fsck -f -a -v rootfs.ext4
tune2fs -l rootfs.ext4
tune2fs -O ^has_journal rootfs.ext4
tune2fs -l rootfs.ext4
【5】下位机重新烧写rootfs.ext4
tftp 48000000 rootfs.ext4
mmc write 48000000 22000 4000
setenv bootargs root=/dev/mmcblk0p2 rootfstype=ext4 init=/linuxrc console=ttySAC0,115200 maxcpus=1 lcd=wy070ml tp=gslx680-linux
saveenv
re
【6】查看结果
ext4类型的根文件系统是可读可写的
3、基于内存的根文件系统
内存的特点:掉电丢失
ramdisk:将内存当作硬盘来使用
优点:提高根文件系统的访问速度
缺点:掉电丢失,消耗更多的内存空间
1)配置linux内核,让内核支持 ramdisk 系统
【1】进入Linux内核源码的根目录
cd kernel
【2】进入make menuconfig配置界面
make menuconfig
【3】编译内核
make uImage
【4】将uImage拷贝至tftp共享目录
【5】下位机烧写uImage
tftp 48000000 uImage
mmc write 48000000 2000 3000
setenv bootcmd mmc read 48000000 2000 3000 \; bootm 48000000
saveenv
re
2)制作 ext2 类型的ramdisk
【1】进入到busybox源码的根目录下
cd busybox-1.21.1
【2】制作空文件
dd if=/dev/zero of=rootfs.ramdisk bs=1k count=8192
-------------------------
if:input file源数据文件
of:output file目标文件
bs:一次读取的字节数
count:连续读写多少次
命令效果:创建了一个8MB的文件,文件里面的都是0
-------------------------
【3】查看信息
hexdump -C rootfs.ramdisk
-------------------------
hexdump:以十六进制查看文件内容
-C:输出规范的十六进制和ASCII的形式
-------------------------
【4】把空文件格式化为 ext2 类型
mkfs.ext2 rootfs.ramdisk
【5】挂在该分区
sudo mkdir /mnt/zjd_ext2 // 创建挂载点
sudo mount -t ext2 rootfs.ramdisk /mnt/zjd_ext2 // 挂载文件
mount // 查看是否挂载成功
【6】将根文件系统数据拷贝到该分区
sudo cp _install/* /mnt/zjd_ext2/ -a
【7】卸载
sudo umount /mnt/zjd_ext2
注意:卸载之后一定要用 mount 再查看一下
3)验证 ramdisk 类型的文件系统是否可用
【1】上位机把 rootfs.ramdisk 拷贝至 tftp 共享目录
cp rootfs.ramdisk /tftpboot
【2】下位机烧写 rootfs.ramdisk 文件系统
tftp 48000000 rootfs.ramdisk
mmc write 48000000 22000 4000
setenv bootcmd mmc read 48000000 2000 3000\; mmc read 49000000 22000 4000 \; bootm 48000000
setenv bootargs root=/dev/ram rw initrd=0x49000000,8M init=/linuxrc console=ttySAC0,115200 maxcpus=1 lcd=wy070ml tp=gslx680-linux
saveenv
re
【3】查看结果
断电之前:
断电之后:
【4】总结
我们发现在 ramdisk 的根文件系统中创建的内容(hello.c),掉电之后消失了
ramdisk类型的根文件系统是一种掉电丢失的根文件系统