第三类笔记
一、tar命令
1.1 核心参数的英文全称与意义
短参数 | 英文全称 | 中文含义 | 核心作用场景 |
---|---|---|---|
-c | --create | 创建(新的归档文件) | 打包文件时必须使用,用于初始化一个新的归档包 |
-x | --extract | 提取(归档文件中的内容) | 解压时必须使用,用于从归档包中释放文件 |
-t | --list | 列表(显示归档文件中的内容) | 查看压缩包内的文件列表,不实际解压 |
-z | --gzip | 通过 gzip 工具处理(压缩或解压) | 针对 .tar.gz 格式,启用 gzip 压缩算法 |
-f | --file=ARCHIVE | 指定归档文件(后面必须紧跟文件名) | 所有场景都需要,明确操作的目标文件名 |
-C | --directory=DIR | 切换到指定目录(Directory) | 解压时使用,指定文件释放到哪个目标目录 |
1.2 参数组合逻辑与示例解析
1. 打包并 gzip 压缩:tar -czf 打包后.tar.gz 需打包的文件/
拆解参数:
-c
+-z
+-f
-c
(create):表示 “我要创建一个新的归档包”;-z
(gzip):表示 “创建时用 gzip 算法压缩,生成 .tar.gz 格式”;-f 打包后.tar.gz
(file):表示 “这个新归档包的名字是打包后.tar.gz
”;- 最后跟 “需打包的文件 /”:指定要放入归档包的原始文件或目录。
逻辑链:创建(-c)一个用 gzip 压缩(-z)的归档包,命名为 xxx.tar.gz(-f),内容是指定的文件。
2. 解压 tar.gz 包:tar -xzf 压缩包.tar.gz -C 目标目录
拆解参数:
-x
+-z
+-f
+-C
-x
(extract):表示 “我要从归档包里提取文件”;-z
(gzip):表示 “这个归档包是用 gzip 压缩的,需要先解压”;-f 压缩包.tar.gz
(file):表示 “要提取的归档包是压缩包.tar.gz
”;-C 目标目录
(directory):表示 “提取的文件要放到目标目录
下”。
逻辑链:从 gzip 压缩(-z)的归档包(-f)中提取文件(-x),并放到指定目录(-C)。
3. 查看 tar.gz 包内容:tar -tzf 压缩包.tar.gz
拆解参数:
-t
+-z
+-f
-t
(list):表示 “我要列出归档包里的内容”;-z
(gzip):表示 “这个归档包是 gzip 压缩的,需要先解析压缩格式”;-f 压缩包.tar.gz
(file):表示 “要查看的归档包是压缩包.tar.gz
”。
逻辑链:查看 gzip 压缩(-z)的归档包(-f)里的文件列表(-t),不实际提取。
总结:参数组合的核心规律
tar
命令的参数组合是 “功能 + 格式 + 目标” 的逻辑:- 功能(必选):
-c
(创建)/-x
(提取)/-t
(列表),决定操作类型; - 格式(可选):
-z
(gzip)/-j
(bzip2)等,指定压缩算法(对应 .tar.gz/.tar.bz2 等格式); - 目标(必选):
-f
必须紧跟文件名,是所有操作的 “对象”; - 辅助(可选):如
-C
用于指定解压目录,仅在-x
时常用。
- 功能(必选):
二、驱动
2.1 常见错误码(errno)
错误码 | 含义 | 典型场景 |
---|---|---|
EINVAL | 无效参数(22) | 传递给内核函数的参数格式错误(如 GPIO 号越界) |
ENODEV | 设备不存在(19) | 打开未注册的设备文件(如/dev/xxx 不存在) |
EBUSY | 设备忙(16) | 设备被其他进程占用(如摄像头已被打开) |
EFAULT | 错误地址(14) | 用户空间指针无效(如传递 NULL 给内核) |
EPERM | 权限不足(1) | 普通用户操作需要 root 权限的设备 |
2.2 字符设备驱动注销顺序(必须严格遵守)
// 正确顺序:从底层到顶层释放资源
cdev_del(&gpioled.cdev); // 1. 删除字符设备(释放文件操作关联)
unregister_chrdev_region(gpioled.devid, GPIOLED_CNT); // 2. 注销设备号(释放内核资源)
device_destroy(gpioled.class, gpioled.devid); // 3. 销毁设备实例(子对象先释放)
class_destroy(gpioled.class); // 4. 销毁设备类(父对象最后释放)
三、文件系统与环境配置
3.1 关键目录功能(类比理解)
目录 | 功能类比 | 驱动开发相关作用 |
---|---|---|
/bin | 常用工具箱(ls、cp 等) | 存放调试用基础命令 |
/dev | 设备接口(类似插座) | 驱动注册后生成的设备文件(如/dev/lcd ) |
/lib | 共享库仓库(.so 文件) | 存放驱动依赖的动态库(需移植到目标板) |
/etc | 系统配置表 | 存放驱动加载脚本、设备权限配置 |
/sys | 硬件状态面板 | 查看 GPIO、I2C 等硬件实时状态(调试用) |
/home/root | 管理员主目录 | 存放用户应用程序、驱动测试脚本 |
3.2 为何移植 lib 中的.so 文件?
.so
是动态共享库,包含可被多个程序共享的代码(如算法逻辑)、数据(如全局变量)和符号表(函数索引)。
- 优势:节省内存(多个程序共享同一份库代码)、便于更新(修改.so 即可,无需重新编译依赖它的程序)。
- 移植必要性:目标板上的应用程序(如 LCD 测试工具、摄像头 APP)依赖这些库才能运行,需确保与目标板架构(如 ARM)匹配。
3.3 启动参数配置(bootargs/bootcmd)
(1)设置自定义根目录(/home/root)
通过网络挂载(NFS)方式指定根目录,适合开发阶段调试:
# 设置bootargs:指定控制台、根目录为NFS共享目录
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw \
nfsroot=192.168.10.100:/home/gary/linux/nfs/rootfs \
ip=192.168.10.50:192.168.10.100:192.168.10.1:255.255.255.0::eth0:off'
nfsroot
:服务器 IP: 共享根目录路径(需包含/home/root
)ip
:客户端 IP: 服务器 IP: 网关:子网掩码:主机名:网卡:关闭自动配置
setenv bootcmd 'tftp 80800000 zImage; # 从TFTP下载内核镜像tftp 83000000 imx6ull-alientek-emmc.dtb; # 下载设备树bootz 80800000 - 83000000' # 启动内核
四、硬件调试目标实现指南
1. 让自己的根目录(/home/root)生效
- 确保 NFS 服务器已共享包含
/home/root
的目录,并设置权限(chmod 777
)。 - 目标板通过
bootargs
正确配置 NFS 参数,启动后执行cd /home/root
验证是否可访问。
2. 运行 LCD 驱动
- GPIO 配置:根据 LCD 引脚需求设置寄存器(以 GPIO1_IO03 为例):
/* 配置IO属性:关闭HYS、默认下拉、使能pull/keeper、100Mhz速度等 */
SW_PAD_GPIO1_IO03 = 0x10B0; // 按寄存器位定义配置
- 驱动步骤:
- 1.注册字符设备(分配设备号、初始化
cdev
)。 - 2.创建设备类和设备实例(
class_create
、device_create
)。 - 3.实现
file_operations
(open
、write
等,控制 LCD 显示)。 - 4.测试:在
/home/root
编写测试程序,通过/dev/lcd
发送指令。
3. 运行摄像头(V4L2 框架)
- V4L2 核心:摄像头驱动需遵循 Video for Linux 2 框架,实现
v4l2_file_operations
。 - 关键步骤:
- 注册视频设备(
video_device
结构体),关联设备节点(如/dev/video0
)。 - 实现格式设置(
VIDIOC_S_FMT
)、缓冲区管理(VIDIOC_REQBUFS
)等 IOCTL 命令。 - 调试:使用
v4l2-ctl
工具(需移植到/bin
)查看设备支持的格式:
- 注册视频设备(
五、一些常用的vi指令
5.1 撤销
先退出插入模式:如果你正在插入模式(编辑文字时,左下角显示
-- INSERT --
),先按Esc
键回到正常模式(左下角无插入提示)。执行撤销命令:在正常模式下,按
u
键(小写字母 u),即可撤销上一次的编辑操作。
5.2 返回
恢复被撤销的操作(即 “重做”),在正常模式下按 Ctrl + r
即可。
六、使用全志linux系统遇到的一些问题
6.1 使用TINA LINUX会遇到像是./脚本运行不了的情况
原因是TinaLinux预装的是ash(轻量级的shell)和bash这种完整的shell不同,只需要
sh <脚本名字>.sh
即可解决,一下是ash 和 bash 以及 sh 和 bash关系的介绍
6.1.1 sh 与 bash 的关系
- sh:全称是 Bourne Shell,是 Unix 系统中最早出现的 shell 之一(1979 年诞生),是很多后续 shell 的 “鼻祖”,语法简单,功能基础,主要用于执行基本的命令和脚本。
- bash:全称是 Bourne Again Shell(“再次诞生的 Bourne Shell”),是 1989 年在 sh 的基础上开发的增强版 shell,完全兼容 sh 的语法,但增加了很多实用功能(比如命令历史记录、Tab 自动补全、管道优化、更丰富的条件判断等)。
实际关系:
- 现代 Linux 系统中,
sh
通常是bash
的 “软链接”(符号链接),即输入sh
其实调用的是bash
(但 bash 会进入 “兼容模式”,模拟 sh 的行为)。 - 简单说:bash 是 sh 的 “升级版”,兼容 sh 但功能更强。
6.1.2 ash 与 bash 的关系
- ash:全称是 Almquist Shell,是 1989 年开发的轻量级 shell,设计目标是 “小巧、高效、占用资源少”,语法上兼容 sh,但功能比 bash 精简(比如没有命令历史、Tab 补全较弱)。
- bash:如前所述,是功能丰富的增强版 shell,但缺点是占用内存和磁盘空间更大,启动速度稍慢。
实际关系:
- 两者都是 sh 的 “兼容实现”(都遵循 sh 的基本语法),但定位不同:
- ash 适合 嵌入式系统、路由器、精简 Linux(如 TinaLinux、OpenWRT) 等资源有限的环境(体积小、速度快);
- bash 适合桌面 / 服务器 Linux(如 Ubuntu、CentOS),提供更友好的交互体验。
- 在很多精简系统中,
sh
其实是ash
的软链接(比如你的 TinaLinux 中,sh
很可能指向ash
)。
6.1.3 总结
- sh 是 “标准基础壳”,是 bash、ash 的 “前辈”;
- bash 是 sh 的 “增强版”,功能全,适合复杂场景;
- ash 是 sh 的 “轻量版”,体积小,适合嵌入式 / 精简系统。三者核心语法兼容,但功能和适用场景不同。