野火【第一期】Linux系列教学视频之“零基础入门”篇,手把手教学,从0开始,基于野火i.MX6ULL Pro/MINI开发板_哔哩哔哩_bilibili
运行于ARM-A7的嵌入式Linux系统基础知识,开发板还没买,视频全部看一遍,PC装了Ubuntu和Linux,简单测试过视频中的几个例子,对嵌入式Linux有了基本了解
第二次看视频,已经买了开发板,文章了也多加了很多截图
1 开发板:核心板接口*3、Flash类型*2【512M flash为工业级,但某些qt项目第三方库可能很大,运行不了;学生建议用8G eMMC】、底板类型*2、Qt界面
2 大学堂:链接、安装演示、注册账号、下载资料
野火大学堂(fire-class) download | SourceForge.net
1 应用场景:看网站服务器www.netcraft.com、智能家居、工业机器人、笔记本、行车记录仪、Kindle
2 职业方向:服务器运维、应用软件开发、嵌入式系统开发
3 转型经验:
为了解析工控屏脚本,参考开源代码picoc(精简、3500行、建议有经验者研究)、write-a-c-interpreter(阉割版、建议菜鸟研究,国人写,有中文文档)编写C语言解释器,视频作者收获很大
Zik Saleeba / picoc · GitLab
GitHub - lotabout/write-a-C-interpreter: Write a simple interpreter of C. Inspired by c4 and largely based on it.
老师熟练掌握下述内容,感觉没有进步空间,于是转行Linux
1 学习群体定位:入门 进阶
2 传统学习路线:基本操作、ARM裸机、Linux移植【GNU C在C99标准上扩展了大量语法】、驱动开发【一般都是面向对象的开发方式】、应用编程、项目实战。
全天学习,也需要4个月才能到项目实战。
3 野火理念:树莓派启发及其优缺点;野火路线--常用操作、工具体验、应用编程。项目实战、ARM裸机开发(勿深入)、Linux系统移植、Linux驱动开发
1 i.MX系列处理器:挑选芯片--NXP/产品/网站芯片选择、性能稳定、资料齐全、芯片内部资源、开发工具、供货周期、性价比、运行环境;
i.MX6ULL官网介绍、ARM-A7、功能框图 外设丰富、官网文档
i.MX 6ULL Single-Core Processor with Arm® Cortex®-A7 Core
2 ARM体系架构:指令集--软硬件接口、本质是机器码、汇编;架构--具体指令集;处理器=内核、芯片为soc;
授权方式--指令集/架构授权、内核授权(电路图、测试方法)、使用授权(使用封装好的内核);A7内核--性能功耗平衡。
3 iMX RT简介:跨界处理器、外设与i.MX6ULL类似
1 起源:1991、企鹅logo、1979商业化的UNIX、Minix教学用 单人开发、GNU、Linux学习Minix 借助GNU
2 主要构成:内核+GNU工具和类库
3 发行版:Debian、Fedora、SUSE、其他
开发环境--单系统Linux、双系统【系统切换需要开关机】、Win10安装Linux子系统、虚拟机【VMWare收费、VirtualBox开源免费】、企业服务器+客户端
1 安装VirtualBox:VirtualBox官网介绍、开源、官网下载、安装演示、新建虚拟电脑 虚拟内存 虚拟硬盘
Oracle VM VirtualBox
2 安装Ubuntu:开源、官网下载桌面版、虚拟机中安装Ubuntu、安装增强功能动态调整Ubuntu分辨率
Ubuntu官网
3 设置网络、共享文件夹:ubuntu内设置--拖放、共享粘贴版、Ubuntu内ping
上述设置ubuntu重启后生效【共享粘贴版只支持文字】
1 Linux目录层次标准:根目录 / ls -l tree;50页的Linux目录标准
2 目录详细介绍:bin--binary 二进制命令文件,所有用户都可以使用;
boot--bootloader 启动文件;cdrom--挂载cd镜像、逐渐淘汰;dev--设备文件;etc--配置文件;home--用户主目录;lib lib64--bin目录的库文件;media--媒体设备;mnt--mount设备或文件系统挂载;opt--option可选、测试用;proc--应用程序、内存、控制台、CPU 信息;
root--管理员主目录;run--系统运行信息;sbin--root用户可执行的二进制命令;srv--网络服务信息;sys--硬件操作接口;tmp--临时存储;usr--大部分文件,占用较大存储空间;var--易变文件。
3 文件类型介绍:
d--目录文件;- --普通文件;l--链接文件;
c--字符设备文件;b--block块设备文件;
系统路径--/绝对路径、相对路径、. ./当前目录、.. ../上一层目录
1 用户与用户组:管理员root、系统用户、普通用户;多任务多用户系统、安全性;
UID user ID、GID group ID;
/etc/passwd文件介绍 UID、/etc/shadow文件介绍 加密密码、/etc/group文件介绍 GID;
登录ubuntu系统,会根据账户+密码依次核验上述3个文件
2 文件权限:r w x - 用户 用户组 其他用户
1 Shell是什么:硬件 内核 系统调用 应用程序Shell;Tab自动补全;APP一般都有Shell,但未必有图形界面
2 命令的格式与帮助:-h --help;command【-options】【argument】
3 常用命令:查询手册man比help更详细,一般用--help就够了,注意章节 man 3 printf;
目录操作--ls查看当前目录内容、cd改变目录 /根目录 ~用户目录、pwd打印当前目录、ls 打印当前目录下内容 -a查看隐藏文件 -lh查看详细信息、mkdir创建目录、rmdir删除空文件夹、mv重命名或移动文件 mv gzctemp/ gzcdebug 注意空格;
文本操作--touch新建文件、cat查看文件、echo写入文件 echo bye >> 123.txt文件后追加bye >>追加 >覆盖 在终端打印字符串、wc文本统计 -l行数 -w单词数 -c字符数、rm删除文件 -r递归删除
1 Shell是什么:
2 命令的格式与帮助:
3 常用命令:文本操作--ln创建软硬链接文件【硬链接为文件副本 软链接为快捷方式,另外不能在虚拟机与windows的共享目录执行ln命令】、cp复制文件或目录、tar打包解包【不负责压缩解压】、find寻找文件路径、grep文件内查找字符串;
用户管理--sudo一次性获取root权限、su切换用户、useradd adduser 2种添加用户的方式【adduser更详细,常用】、usermod改GID、userdel deluser删用户、passwd改用户密码【无需旧密码】、groupadd addgroup、groupdel delgroup操作权限;
1 Shell是什么:
2 命令的格式与帮助:
3 常用命令:文件权限--chmod修改文件权限、chown修改文件拥有者、chgrp修改文件用户组;
磁盘管理--df查看文件系统信息、du递归查看目录下所有文件信息【查看当前目录占用存储空间大小】、mount将硬件或网络设备挂载到目录、umount;
网络操作--ping、ifconfig需要安装APP 查看配置网络【修改IP、启停网卡】;
控制终端--clear清屏;
开关机--reboot重启、poweroff关机
小技巧:tab自动补全功能,按1下自动补全,按2下列出所有相关内容,多用于命令或路径;
!! 自动执行上一个命令,多用于和sudo配合,上一条指令缺乏权限,下一条指令直接改成sudo !!;
1 gedit:ubuntu默认【图形界面下双击文件调用gedit】、图形界面、类似notepad++。
gedit canvas.c打开某个文件
2 vi/vim:不依赖图形界面,应用范围广,效率很高;历史悠久,支持广泛【老版本的Linux、硬件配置较低的设备只支持vi/vim】;vim为升级版,需要单独安装 sudo apt install vim;
模式 ---- 一般模式(默认查看模式)、插入模式(编辑模式)、命令行模式(设置行号、代码高亮等功能);打开方式、模式切换;使用which vi查看vi路径;
一般模式快捷键--跳转到第n行、跳转到最末行、跳转第1行、查找文本
1 gedit:
2 vi/vim:
一般模式快捷键--u撤销操作;dw删除1个单词、dd删除当前行、ndd删除n行、x剪切光标对应1个字符、y复制、P p粘贴、yy复制当前行【实测只选1个字符则y复制1行,yy无效;若使用v选多个字符,与快捷键一致】、nyy复制n行、v V选择多个字符 多行
命令行模式快捷键--w保存 另存为、r读取、q未修改直接退出、q!不保存直接退出、wq保存并退出、set nu行首加入行号、set nonu不显示行号、!command
1 脚本简介:批处理、整合命令;
内置命令【cd pwd等】+外部命令【ifconfig等,shell在特定路径中寻找外部应用程序】,使用 type查看;
将C程序hello world变为shell【将编译好的可执行文件移动到shell搜索路径】;
编写shell脚本;启动方式--作为程序执行、指定解释器运行、source、.
2 脚本语法:
1 脚本简介:
2 脚本语法:定义变量--无单引号时不可以有空格或tab、双引号可以解引用;使用变量--{}确认边界;命令结果赋值给变量;删除变量unset;
特殊变量--$0当前脚本文件名、$n传递给脚本的第n个参数、$#传递的参数个数、$* $@传递给脚本的所有参数、$?上个脚本返回值、$$当前Shell ID;
字符串拼接--并排放;读取键盘输入数据read;退出当前进程exit;整数数学运算(());逻辑与 或$$ ||;
1 脚本简介:
2 脚本语法:
$* 与$的区别演示【无" "则相同,有" "则不同】
代码中利用数学运算符(())替代-eq等
后续课程image-build项目需要使用大量shell脚本
1 环境变量简介:export将全局变量导出为环境变量【shell中定义的全局变量只能在当前进程中访问,甚至在当前进程的子进程中都不能访问;输入/bin/bash即进入shell子进程;导出后可以在子进程访问,但不能在别的shell进程中访问】
2 Shell配置文件:相关配置文件、Shell执行顺序
/etc/profile任何用户登录时执行1遍;~/.profile当前用户登录时执行1遍;
修改/etc/bash.bashrc后需重新打开终端,变量才有效
source . 启动方式可以打印变量;/bin/bash ./ 启动方式无法打印变量
1 Linux软件包:组成文件;源码包、二进制包;
2 deb包与dpkg工具:deb包、rpm包;dpkg命令;
deb包文件结构分析【control文件必须有,其他文件可选】、打包脚本
3 构建一个helloworld的deb包:利用打包脚本实现,部分脚本如下
注意,脚本文件是从windows拷贝过来的,所以多了\r,执行如下所示命令即可sed -i 's/\r$//' build_deb.sh,链接如下
解决报错 “build.sh /bin/bash^M: 坏的解释器:没有那个文件或目录”_Biexiansheng的博客-CSDN博客
安装包默认安装在根目录,构建文件夹利用usr/bin实现安装在/usr/bin目录下
4 apt工具:新版包管理工具
1 硬件资源介绍:核心板--MPU、FLASH、RAM;Pro底板--外设简介;mini底板
2 SD卡烧录Debian镜像:跨平台Etcher工具--镜像、设备、Flash;
关于镜像:所谓镜像文件其实与压缩包类似,它将一系列文件按照特定的格式制作成单个文件,方便用户下载和使用。 iso文件的一个重要特性是它能被某些软件识别直接刻录到光盘上,而虚拟机虚拟的光驱则可以直接把iso文件像光盘一样加载读取, 从而通过iso系统镜像安装操作系统。
为了扩展适用范围,人们又制定了img文件格式,主要用于创建磁盘的镜像文件(disk image), 它可以用来打包整个磁盘或光盘的内容。img是iso文件格式的超集,它向后兼容iso文件格式。
嵌入式单板机一般没有光驱,而它们通常支持运行SD卡里的操作系统,所以嵌入式的系统镜像通常使用img文件的形式发布。 人们通常在PC上使用软件通过读卡器把img镜像文件烧录至SD卡,然后把SD接入到嵌入式单板机上运行。
Etcher烧录工具官网
1 开发板跑起来:boot配置、CH340串口驱动、MobaXterm安装使用
新版的野火大课堂与视频已经不一样了 视频效果 使用console镜像【SD卡启动】,不同于视频需要登录,直接可以使用命令
2 fire-config工具介绍:fire-config基于设备树插件实现
将SD卡内容写入FLASH,全程演示
BOOT配置为SD卡启动,进入fire-config,选中flasher
确定后finish,系统重启,2-3分钟后刷机结束【RGB闪烁且出现登录界面】,禁止flasher,避免每次重启刷机。power off关机【电源管理模块被关闭】,BOOT配置为eMMC启动,拔掉SD卡,开机【长按ON/OFF键2s】
上一讲先烧好FLASH、跳线帽设置【SD卡和wifi共用SDIO接口,无法同时使用】;
屏蔽驱动打印信息 echo "1 4 1 7" > /proc/sys/kernel/printk
使能wifi后finish重启;搜索、连接、ifconfig、ping
利用echo写驱动文件
实测1 55 255亮度差不多,基本就是非0就亮,0就灭安装脚本安装包、执行各个脚本
vi /etc/apt/sources.list 屏蔽倒数第2行,屏蔽国外软件源
实测 apt install peripheral 和 apt update都无法执行后续操作无法复现
安装 windows:Git官网 Linux:sudo apt install git -y
使用git clone能看到版本历史记录,直接download zip下载压缩包看不到
野火项目github链接 github项目下载链接
视频是2020.5.11,截图是2023.4.3 git克隆完成野火项目gitee链接 gitee项目下载链接
git pull【必须在git仓库内执行该命令】
使用野火大学堂下载方式
网络文件系统、开发板与PC共享文件;
sync--实时写入文件夹,而不是在缓冲区;no_root_sqush--访问共享文件夹的主机root账户拥有对文件夹的全部权限
配置PC机Linux NFS共享文件夹
windows主机、ubuntu、开发板三者互相ping通、开发板挂载PC机路径
视频中直接ping通,我自己做了如下设置才ping通。
windows主机与开发板ETH1通过网线连接,修改虚拟机网络设置如下图
修改主机IP
修改ubuntuIP【可能需要重启虚拟机才能用ifconfig显示正确IP】
修改开发板IP
主机ping ubuntu、开发板
ubuntu ping 主机、开发板
开发板ping主机、ubuntu
开发板安装nfs
在开发板上查看nfs服务器【即ubuntu】共享目录
挂载nfs
GCC由来:GNU组织、unix系统、minix系统、posix接口、internet
GCC编译工具链:gcc编译器--预处理、编译;binutils工具集--汇编、链接
运行第一个helloworld:PC端--建文件夹、新建c文件、编译、运行;
开发板端类似,开发板本地gcc编译
ARM-GCC:本地编译【编译工具链与目标程序运行在相同的架构平台】、交叉编译【一般是编译工具链运行在高性能X86,目标程序运行在低性能arm】;ARM-GCC是针对arm的编译器,是GCC编译工具链的一个分支;
x86 64位系统 针对linux系统 gnu--使用gnu glibc库 7--版本号 针对arm平台linux系统 gnu--使用gnu glibc库
安装:sudo apt install gcc-arm-linux-gnueabihf、官网【arm发起,其他公司加入成立的非营利组织】下载 linaro官网链接
案例:ARM中运行X86-64架构编译的程序报错,Exec format error;
ARM运行交叉编译程序成功
了解执行机制的用途:借鉴、了解报错信息
裸机执行机制:C调用底层串口驱动、编译、烧录、运行
Linux系统执行机制:GCC编译-- c-->i 预处理后->s 汇编文件->o 可重定位文件->应用程序;
Linux内核--Shell执行命令./hello、fork应用程序容器、execev、sys_execve系统调用函数、do_execve、load_elf_binary;
glibc库--10 动态链接、11 静态链接;执行函数;
glibc库退出--结束进程运行
gcc预处理: gcc -E【预处理】 helloworld.c【源文件】 -o【后面跟生成文件名】 hello.i【待生成文件】 -v【打印编译信息】;cc1应用程序
编译c: gcc -S【编译】 hello.i -o hello.s -v;cc1应用程序,
编译汇编: gcc -c【编译并汇编】 hello.s -o hello.o -v;as应用程序,
链接可重定位文件: gcc hello.o -o hello -v;collect2应用程序封装了ld链接器
动态链接、静态链接:动态链接依赖外部环境;静态链接文件较大
make和Makefile:文件太多时使用gcc命令耗时且复杂;make工具--找出修改过的文件及其影响的文件并编译;makefile--记录依赖关系和编译规则
如何学习: Linux缺乏集成式开发环境,主要使用makefile进行项目管理,必须精学;各种复杂的语法都是为了表示依赖关系;基本语法、变量、分支判断、头文件依赖、隐含规则、自动化变量、模式规则、函数
makefile最核心的就是基本语法,其他部分是为了更加高效
目标、依赖、命令
目标:依赖文件或其他目标
tab命令1~n
控制台演示,target a依赖b和c,执行完b和c之后再执行a
也可以单独执行makefile中的某个命令
使用伪命令,则不会关心目标日期,直接执行
2个文件,3个函数
gcc直接编译
使用Makefile编译
原始makefile
避免每次编译main.c mp3.c,改造Makefile,生成中间文件.o,缩短编译时间。优化后的makefile
将makefile文件变得通用
系统变量:CC编译器 AS汇编器 MAKE工具
自定义变量:=延迟赋值【使用时才赋值】 :=立即赋值
?=空赋值【变量为空时赋值有效】 +=追加赋值【类似于后面增加字符串】
自动化变量: $<第1个依赖文件 $^全部依赖文件 $@目标
用变量优化上一个视频的Makefile文件
模式匹配:%匹配任意多个非空字符【类似shell中*通配符】,类似参数传递;利用%优化Makefile
默认规则:.o默认使用.c文件编译
注释 %.o:%.c $(CC) -c $< -o $@,依然可以正常make
ifeq else endif;ifneq else endif;
利用条件分支使用不同的编译工具,注意下图中光标处的空格必须有
中英文 手册
官网英文手册链接
patsubst:模式替换
利用函数改造Makefile,按文件夹存放文件
增加头文件及声明
面向过程:问题分解为步骤、用函数实现步骤、根据需求调用函数
面向对象:问题分解为对象、调用对象的方法属性解决问题
面向对象三大特性:封装--隐藏内部细节;继承--复用代码;多态--函数指针
Linux内核:硬件抽象为文件
虚拟文件系统VFS:抽象层;抽象对象--封装底层细节、利用C语言多态;super_block具体文件系统、inode具体文件、dentry文件路径;inode_operation可以删除、重命名文件;file_operation打开、读写文件【图中*open等均为函数指针】;
普通文件系统:ext4、fat32、ubifs
特殊文件系统:进程文件系统procfs,类似任务管理器;设备文件系统devfs,硬件操作接口
用法:用户函数、系统调用函数、虚拟文件系统、实际文件系统
系统IO编程:系统调用函数;open--找到文件操作接口;write;read;lseek【找到文件的具体读写位置】;close;文件描述符--特殊索引、实际为进程中file_struct结构体成员fd_array数组下标;进程--程序本质为进程
文件打开模式:主模式--只读、只写、读写;副模式--不存在则创建、追加【无需lseek,直接在文件末尾追加】、直接IO【不经过页缓存区直接写入磁盘】、同步【相当于调用sync】、非阻塞
标准IO编程:glibc库
头文件、函数原型、返回值
虚拟机C代码演示:只读模式打开不存在文件报错、只读 创建模式打开不存在文件成功。【linux系统运行后默认打开标准输入、标准输出、标准出错,占用0 1 2三个文件描述符】
头文件、函数原型、返回值
虚拟机C代码演示:复制普通文件功能--打开源文件、新建目的文件、读取并写入、关闭所有文件;
lseek:设置文件读写位置,文件开头、当前位置、文件末尾
虚拟机C代码演示:lseek--偏移100个字节追加4个字节【vi将空格显示为^@】
sync:页缓存和回写--用户空间buff、内核空间页缓存区、磁盘;sync将页缓存区内容立刻强制写入磁盘;在每次wirte后直接执行sync();
C标准库实现了IO缓存区,避免频繁在用户态和内核态之间切换,降低系统性能。
标准IO函数:fopen、fclose、fwrite、fread、fseek、fflush类似sync,强制将IO缓存区内容写入页缓存区
文件IO五大模式:阻塞--无法读取则休眠;非阻塞--立即返回;IO多路复用;异步IO;信号驱动IO
驱动程序:本质为硬件的节点文件
应用程序:使用设备节点文件
控制硬件设备步骤:找到设备节点文件、/dev 更底层 1个文件控制全部特性、 /sys稍抽象 1个文件控制1个特性;找到设备文件使用方式
LED灯程序:设备节点文件位置-- /sys/class/leds;使用方式--brightness写入0-255数值控制亮度
开发板led.c代码写设备文件控制灯闪烁【没找到c源文件】
/sys 文件其实是Linux内核导出到用户空间的硬件接口
控制LED使用的是驱动程序的led子系统,控制蜂鸣器使用的是gpio子系统
GPIO子系统需要手动导出蜂鸣器接口
控制台控制蜂鸣器;
C函数控制蜂鸣器
执行现象
设备文件:/dev/input/by-path/platform-gpio-keys-event
input子系统:按键、键盘、鼠标、触摸屏;input_event结构体成员介绍
C代码检测按键是否按下
执行现象