Linux内核学习:目录结构、配置、编译和常用Shell命令

之前在嵌入式Linux中,学习了U-Boot相关的知识,从本节开始就来学习一下Linux内核的知识。本篇文章主要介绍一下Linux内核的相关知识,让我们对Linux内核有一个入门的理解。

1 Linux入门

1.1 简介

Linux是一种开源的类Unix操作系统内核,它由LinusTorvalds在1991年创建。Linux操作系统是基于Unix设计理念的,旨在提供一个稳定、可靠、安全且高度可定制的操作环境。以下是Linux的一些特点:

  1. 内核:Linux内核是操作系统的核心,负责管理系统的资源和提供基本的硬件控制。它是开源的,可以根据需要进行定制和修改。
  2. 开源:Linux采用开源模型,意味着其源代码是公开可用的。这使得用户可以自由查看、修改和分发系统的源代码。
  3. 多用户和多任务:Linux支持多用户环境,多个用户可以同时使用系统。它还是多任务的,能够同时运行多个程序。
  4. 文件系统:Linux使用类Unix的文件系统,文件和目录的管理遵循一种层次结构。文件系统被视为树状结构,以根目录(/)为起点。
  5. 命令行界面:Linux通常提供强大的命令行界面(CLI),允许用户通过命令进行系统管理和配置。同时,也有图形用户界面(GUI)可用,如GNOMEKDE
  6. 软件包管理:多数Linux发行版使用包管理系统,使用户能够方便地安装、更新和删除软件包。例如,Debian系使用APT,RedHat系使用RPM
  7. 网络功能:Linux内建了强大的网络功能,支持各种网络协议和服务。它可以用作服务器、路由器或桥接设备,也适用于各种网络应用。
  8. 移植性: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用于构建内核的脚本
securityLinux安全模块
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 内核编译后,生成的 vmlinuxzImageuImage 代表了不同的内核镜像格式,它们的主要区别可以总结如下:

  1. vmlinux:
    • 类型: 未压缩内核镜像。
    • 用途: 主要用于调试和分析,包含了完整的可执行二进制代码。
    • 加载: 直接加载到指定的内存地址执行。
  2. zImage:
    • 类型: 使用LZ77压缩算法压缩过的内核镜像。
    • 用途: 用于较小的系统,适合于启动时压缩内核。
    • 加载: 被引导加载程序加载到内存中,然后由引导加载程序进行解压缩和执行。
  3. 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 -lll:列出详细内容 (长格式)
    • ls -a:查看隐藏文件
  • cd:改变目录

    • cd ..:上一级
    • cd ../../:上两级
  • pwd(print working dir):显示当前工作目录

  • mkdir:创建目录

    • 创建目录结构:mkdir -p ch3/srcpparents
  • 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 rootsu -
    • 以管理权限打开文件: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),如lessmoreheadtail
  • 管线命令仅会处理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,某些指令需要用到文件名来处理时,该stdinstdout可以利用减号-来代替。例:

tar -cvf - /home | tar -xvf -

tar打包/home,文件名位置填-,打包的数据传送到stdout,则后面的tar-就是前一个指令的stdout

在这里插入图片描述

  • 15
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tilblackout

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值