之前在嵌入式Linux中,学习了U-Boot相关的知识,从本节开始就来学习一下Linux内核的知识。本篇文章主要介绍一下Linux内核的相关知识,让我们对Linux内核有一个入门的理解。
文章目录
1 Linux入门
1.1 简介
Linux是一种开源的类Unix操作系统内核,它由LinusTorvalds在1991年创建。Linux操作系统是基于Unix设计理念的,旨在提供一个稳定、可靠、安全且高度可定制的操作环境。以下是Linux的一些特点:
- 内核:Linux内核是操作系统的核心,负责管理系统的资源和提供基本的硬件控制。它是开源的,可以根据需要进行定制和修改。
- 开源:Linux采用开源模型,意味着其源代码是公开可用的。这使得用户可以自由查看、修改和分发系统的源代码。
- 多用户和多任务:Linux支持多用户环境,多个用户可以同时使用系统。它还是多任务的,能够同时运行多个程序。
- 文件系统:Linux使用类Unix的文件系统,文件和目录的管理遵循一种层次结构。文件系统被视为树状结构,以根目录(
/
)为起点。 - 命令行界面:Linux通常提供强大的命令行界面(
CLI
),允许用户通过命令进行系统管理和配置。同时,也有图形用户界面(GUI
)可用,如GNOME
和KDE
。 - 软件包管理:多数Linux发行版使用包管理系统,使用户能够方便地安装、更新和删除软件包。例如,Debian系使用
APT
,RedHat系使用RPM
。 - 网络功能:Linux内建了强大的网络功能,支持各种网络协议和服务。它可以用作服务器、路由器或桥接设备,也适用于各种网络应用。
- 移植性:Linux可以运行在多种硬件平台上,从个人计算机到嵌入式系统、服务器和超级计算机。
Linux有多个不同的发行版,每个发行版有其独特的特性和工具。常见的发行版包括Ubuntu、Fedora、Debian和CentOS。
1.2 源码下载
Linux官方提供了不同版本的Linux源码,官网仅提供最新版本的Linux源码和长期维护的一些Linux版本的源码。下载地址:The Linux Kernel Archives
如上图所示,mainline
即最新版本的源码,stable
即相对稳定的版本,longterm
即Linux官方会长期维护的版本。我们可以点击tarball
下载不同版本的源码。
与U-Boot一样,不同的半导体产商都有提供基于官方开发板移植好的Linux源码,比如我现在用的是基于NXP的I.MX系列的Linux开发板,我们就可以去下载NXP官方移植好的源码。下载地址:linux-imx。厂商提供的源码帮我们适配了不同的ARM架构,还有硬件平台的差异,所以我们优先使用厂商提供的源码。
1.3 目录结构
解压后,可以看到有如下的目录:
Directory | 描述 |
---|---|
arch | 架构特定的源代码 |
block | 块I/O层 |
crypto | 加密API |
Documentation | 内核源代码文档 |
drivers | 设备驱动程序 |
firmware | 用于使用特定驱动程序的设备固件 |
fs | 虚拟文件系统和各个文件系统 |
include | 内核头文件 |
init | 内核引导和初始化 |
ipc | 进程间通信代码 |
kernel | 核心子系统,如调度程序 |
lib | 辅助例程 |
mm | 内存管理子系统和虚拟内存 |
net | 网络子系统 |
samples | 示例演示代码 |
scripts | 用于构建内核的脚本 |
security | Linux安全模块 |
sound | 音频子系统 |
usr | 早期用户空间代码(称为initramfs) |
tools | 帮助开发Linux的工具 |
virt | 虚拟化基础设施 |
这些目录代表了Linux内核源代码树中不同部分,包括硬件架构、设备驱动、文件系统、内存管理、网络、安全等,各自负责实现和维护内核的不同核心功能和子系统。
1.4 配置
与U-Boot的编译类似,参考U-Boot的文章:U-Boot编译和.config配置文件生成分析,因为U-Boot的源码编译就是仿照Linux来实现的。
在arch/arm/configs
目录下有对应不同的配置文件,不同的配置文件对应不同的开发板,我们根据自己的需求选择一个配置文件进行make:
这里我就选择目录下的imx_v7_defconfig
,现在我们就使用make imx_v7_defconfig
来配置一下。同样地我们需要指定架构为arm
,还有交叉编译工具的前缀。
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfig
执行后会有一些警告,这里我们忽略,最后会提示:
同样地我们可以使用make menuconfig
,在可视化菜单中添加或删除一些选项。
1.5 编译
接下来我们就可以编译Linux内核了:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
编译过程中提示以下错误:
我们需要安装一下lzop
:
sudo apt-get install lzop
我们再次编译一下:
可以看到在arch/arm/boot
文件夹下生成了Linux的内核文件zImage。
1.6 不同镜像格式
在 Linux 内核编译后,生成的 vmlinux
、zImage
和 uImage
代表了不同的内核镜像格式,它们的主要区别可以总结如下:
- vmlinux:
- 类型: 未压缩内核镜像。
- 用途: 主要用于调试和分析,包含了完整的可执行二进制代码。
- 加载: 直接加载到指定的内存地址执行。
- zImage:
- 类型: 使用LZ77压缩算法压缩过的内核镜像。
- 用途: 用于较小的系统,适合于启动时压缩内核。
- 加载: 被引导加载程序加载到内存中,然后由引导加载程序进行解压缩和执行。
- uImage:
- 类型: 包含 U-Boot 需要的引导头的内核镜像。
- 用途: 用于嵌入式系统,支持 U-Boot 引导加载程序,并包含了额外的头部信息,如操作系统类型和加载程序信息。
- 加载: 被 U-Boot 引导加载程序加载,然后由 U-Boot 进行解压缩和执行。
- uImage主要在一些比较老的内核源码版本中有生成,现在的Linux内核源码更多使用的是zImage
在U-Boot中加载 zImage 时,通常不需要额外的解压步骤,因为zImage文件本身是自解压缩的。这是通过在zImage文件中包含一个小型的自解压缩程序来实现的。当U-Boot加载zImage时,它会执行这个自解压缩程序,将内核加载到内存中,并在必要时执行其他初始化步骤。
2 常用Shell命令
本篇文章先来介绍一下Linux中常用的一些Shell命令,方便后续的开发。
2.1 常用
ls
(list):列出目录文件ls -l
或ll
:列出详细内容 (长格式)ls -a
:查看隐藏文件
cd
:改变目录cd ..
:上一级cd ../../
:上两级
pwd
(print working dir):显示当前工作目录mkdir
:创建目录- 创建目录结构:
mkdir -p ch3/src
,p
为parents
- 创建目录结构:
cp
:拷贝单个文件,如cp ch1/hello.c ch2/
- 拷贝目录:
cp -r ch1 ch3
,其中-r
为递归,-i
是询问覆盖
- 拷贝目录:
mv
:剪切(可用于重命名)- 例:
mv ch2/hello.c ./
、mv hello.c helloworld.c
- 例:
rm
:删除单个文件- 删除目录:
rm -r ch3
- 删除目录:
cat
:查看文件内容- 显示行号:
cat -n file
- 显示行号:
su
:切换用户- 切换管理员:
su root
和su -
- 以管理权限打开文件:
sudo 文件
- 切换管理员:
vim
:编辑文件 文件存在则打开,不存在则创建touch
:用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。Linux区分大小写。man
:手册其中第一页:user commands(标准命令),第二页:System calls(系统调用),第三页:Library functions(库函数)
指定页码:如
man 1 ls
为打开第一页,不写页码默认第一页
2.2 find:查找符合条件的文件
- 语法:
find 目录名 选项 查找条件
- 例子:
find /work -name "test.txt"
- 注意
- 1.查找条件中可用正则表达式,如*
- 2.如果不指定目录,默认在当前目录
2.3 grep:查找文件中符合条件的字符串
- 语法:
grep [选项] [查找模式] [文件名]
- 选项
-R
(recursive):递归查找-n
(number):显示目标位置的行号-w
(whole words):全字匹配
- 例:
grep -nR "字符串" *
- 其中
*
代表当前目录下的所有文件和目录
- 其中
2.4 file:识别文件类型
语法:
file 文件名
例:
file ~/.bashrc 为ASCII 编码的text类型 file ~/.vimrc 为UTF-8 Unicode 编码的text类型 file /bin/pwd 出现 ELF 64-bit LSB executable,即为ELF格式的可执行文件 file /dev/* 出现character special(字符设备文件)、 block special(块设备文件)等
2.5 which和whereis:查找应用程序的所在位置
- 语法:
which/where is 命令名/应用程序名
which
只查找可执行文件的位置,而whereis
提供了更全面的信息,包括可执行文件、源代码文件和帮助文档等。
2.6 tar:解压缩
在Linux中使用tar
对文件进行解压缩,小文件用gzip
,大文件用bzip2
。
(1)常用选项
-c
(create) :表示创建文件,在压缩的时候需要指定-x
:表示解压,在解压的时候需要指定-t
:可以查看压缩的文件-z
:使用gzip方式进行处理,它与”c“结合就表示压缩,与”x“结合就表示解压缩。-j
:使用bzip2方式进行处理,它与”c“结合就表示压缩,与”x“结合就表示解压缩。-v
(verbose):详细报告tar处理的信息-f
(file):后面接着待操作的文件名-C <指定目录>
:解压到指定目录
(2)压缩
- 语法:
tar -czvf/cjvf 压缩文件名 目录名
- 例:
tar czvf dira.tar.gz dira
tar cjvf dira.tar.bz2 dira
(3)解压
- 语法:
tar xzvf/xjvf 压缩文件名 -C 指定目录
- 没有
-C
则默认在当前目录
- 没有
- 例:
tar xzvf dira.tar.gz -C /home/book
tar xjvf dira.tar.bz2 -C /home/book
2.7 ln:给文件和目录创建替代名或别名
在Linux中,inode
用于存储关于文件或目录的信息,每一个文件都有一个inode
。Linux通过inode
寻找对应文件(夹)的文件数据块,移动或重命名均不会改变其inode
号。
查看文件的inode
号:
ls -i
或
stat filename
- 语法:
ln [-s或P] source_file target_file
- 参数
-s
:建立软链接(符号链接,即快捷方式)-P
:建立硬链接(指向inode
,删除不影响原始数据)
- 例:
(1)软链接:支持文件和目录
ln -s /proc/version version #在当前目录下创建version,并让其指向/proc/version
可以看到软链接的inode是不同的。
(2)硬链接:仅支持文件,不支持跨文件系统(proc是VFS,其信息存放在内存中)
ln 1.txt 2.txt
可以看到硬链接的inode是相同的。
2.8 进程相关
2.8.1 top:实时监视系统中运行的进程
参数:
-d
或--delay
:指定更新之间的延迟时间。-p
或--pid
:通过提供进程ID来监视特定的进程。-U
或--user
:显示特定用户的进程。-q
:以“安静”模式启动top,仅显示有限的信息。
例:
top -d 5 # 每5秒更新一次
top -p 123 # 监视进程ID为123的进程
top -U 用户名 # 显示特定用户的进程
2.8.2 ps:显示当前运行的进程列表
参数:
aux
:显示所有进程的详细列表和附加信息。-e
:显示其他用户进程的信息。-f
:显示完整格式的列表。-u
或--user
:显示特定用户的进程。
例:
ps aux # 显示详细的进程信息
ps -e # 显示有关所有进程的信息
ps -u 用户名 # 显示特定用户的进程
- 我们可以使用指令
pstree
来显示树形结构的进程列表
2.8.3 jobs:显示后台运行的进程
参数:
- 无参数:不带参数时,
jobs
显示当前shell会话中的所有作业。 -l
:显示作业号以及与作业相关的进程组的详细信息。-n
:仅显示状态为stopped
(已暂停)或terminated
(已终止)的作业。%1
,%2
, …:通过指定作业号,可以只显示特定的作业信息。- 作业(
jobs
)号即使用jobs
指令列出的每个进程最前面的数字
- 作业(
例:
jobs # 显示当前shell会话中的所有作业
jobs -l # 显示详细信息,包括作业号和进程组
jobs -n # 仅显示已暂停或已终止的作业
我们先用sleep
命令休眠,然后用jobs
就可以查看到当前shell中的这个休眠作业。
2.8.4 fg和bg:将后台作业调至前台/将暂停的前台作业转到后台
fg %1 # 将作业号为1的作业调至前台
bg %2 # 将作业号为2的作业放到后台运行
2.8.5 nice:以指定的优先级启动进程
参数:
-n
:指定进程的优先级。范围一般为-20(最高优先级)到19(最低优先级)。--adjustment
:与-n
相同,用于指定优先级。
例子:
nice -n 10 my_process #设置优先级为10
nice --adjustment=5 my_process #设置优先级为5
2.8.6 kill:向进程发送信号
参数:
-s
或--signal
:指定要发送的信号。-l
或--list
:显示可用的信号列表。
例子:
(1)终止PID为1234的进程
- 不指定
-s
,则默认发送SIGTERM
终止信号
kill 1234
(2)列出所有可用的信号
kill -l
(3)向进程ID为5678的进程发送强制终止的信号(SIGKILL)
kill -s SIGKILL 5678
等价于
kill -9 5678
这里我们一个终端通过top
显示进程信息,在另一个终端中使用kill
杀掉top
进程。
2.9 权限管理
2.9.1 chmod:改变文件或目录的权限
它支持两种方式设置权限:符号模式和数字模式。
符号模式:
u
表示用户(owner)。g
表示组(group)。o
表示其他用户(others)。a
表示全部用户(所有者、组和其他用户)。+
表示添加权限。-
表示移除权限。=
表示设置权限。
使用符号模式的一些示例:
chmod u+rwx file # 用户给文件读、写、执行权限
chmod go-w file # 组和其他用户去掉写权限
chmod a=rx file # 所有用户只保留读和执行权限
数字模式:
数字模式通过三个数字表示权限,分别代表用户、组和其他用户的权限。每个数字由三位二进制数组成,分别表示读(4)、写(2)、执行(1)权限。因此,组合不同的数字可以表示不同的权限组合。
举例说明:
rwx
(读、写、执行)对应数字模式为7。rw-
(读、写)对应数字模式为6。r--
(只读)对应数字模式为4。
使用数字模式的一些示例:
chmod 755 file # 用户具有读、写、执行权限,组和其他用户具有读和执行权限
chmod 644 file # 用户具有读和写权限,组和其他用户只有读权限
chmod 700 file # 用户具有读、写、执行权限,组和其他用户没有权限
2.9.2 chgrp命令:改变文件或目录的组
使用格式:
chgrp new_group file
例子:
chgrp group file # 将文件的组改为"group"
2.9.3 chown:改变文件或目录的所有者
使用格式:
chown [new_owner]:[new_group] file
例子:
chown user:group file # 将文件的所有者改为"user",组改为"group"
2.10 文本处理命令和管道
管道用|
分开,例:
ls -al /etc|less #ls的stdout作为less命令的stdin
- 在
|
后面的指定必须是管线命令(可以接受stdin
),如less
、more
、head
、tail
- 管线命令仅会处理
stdout
,对于stderr
会忽略
例:
(1)cut
cut
用法:
cut -d '分隔字符' -f fields #-f为取出第几段,结果下标从1开始
cut -c 字符区间 #以字符为单位取出固定字符区间
管道:
echo $PATH | cut -d ':' -f 5 #取出第5个
echo $PATH | cut -d ':' -f 3,5 #取出第3与第5个
export | cut -c 12- #取出第12个字符后的字符串
export | cut -c 12-20 #取出12-20的字符串
(2)grep
last | grep 'root' #取出有root的行
last | grep -v 'root' #取出没有root的行
last | grep 'root' |cut -d ' ' -f1 #取出有root的行的第一列
(3)sort
:排序
选项:
-t
:分割符-k
:以分隔结果的哪个区间排序-r
:反向排序-f
:忽略大小写-b
:忽略最前面的空格-n
以数字排序
例:将帐号进行排序
cat /etc/passwd | sort
cat /etc/passwd | sort -t ':' -k 3 #以第三栏排序
cat /etc/passwd | sort -t ':' -k 3 -n #上述排序以字符串排序,1会出现在11后面,-n指出按数字排序
(4)uniq
:去除连续的重复行
last | cut -d ' ' -f1 | sort | uniq [-c] #去除重复,-c为计数
(5)wc
:统计
cat /etc/man.config | wc #输出的三个数字分别代表:行、字数、字符数
(6)tee
:作为管道的输入,同时也输出到屏幕
last | tee last.list #输出到屏幕和last.list
(7)tr
:删除或替换文字
选项:
-d
:删除后面接的字符串-s
:取代重复的字符
例:
last | tr '[a-z]' '[A-Z]'
cat /etc/passwd | tr -d ':' #将结果中的冒号删除
(8)减号-
的作用
在管道命令中,会用前一个指令的stdout
作为这次的stdin
,某些指令需要用到文件名来处理时,该stdin
与stdout
可以利用减号-
来代替。例:
tar -cvf - /home | tar -xvf -
用tar
打包/home
,文件名位置填-
,打包的数据传送到stdout
,则后面的tar
的-
就是前一个指令的stdout
。