Linux内核学习(1):目录结构、配置、编译和常用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 用于构建内核的脚本
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 内核编译后,生成的 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

在这里插入图片描述

相关推荐

  1. Linux 命令 - cd 【切换目录

    2024-02-22 16:16:05       26 阅读
  2. 算法之工程化内容1)—— Linux命令

    2024-02-22 16:16:05       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-22 16:16:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-22 16:16:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-22 16:16:05       82 阅读
  4. Python语言-面向对象

    2024-02-22 16:16:05       91 阅读

热门阅读

  1. 深入理解CAS

    2024-02-22 16:16:05       49 阅读
  2. 05 SS之结合SS+Redis+JWT实现认证

    2024-02-22 16:16:05       40 阅读
  3. 【软考】类

    2024-02-22 16:16:05       56 阅读
  4. python opencv图像模糊

    2024-02-22 16:16:05       47 阅读