【内核】01.内核基础

【嵌入式八股】一、语言篇https://www.nowcoder.com/creation/manager/columnDetail/mwQPeM

【嵌入式八股】二、计算机基础篇https://www.nowcoder.com/creation/manager/columnDetail/Mg5Lym

【嵌入式八股】三、硬件篇https://www.nowcoder.com/creation/manager/columnDetail/MRVDlM

【嵌入式八股】四、嵌入式Linux篇(本专栏)https://www.nowcoder.com/creation/manager/columnDetail/MQ2bb0

LINUX内核

alt

内核基础

01.Linux内核五大功能/子系统

什么是 Linux 内核?

Linux内核是Linux操作系统的核心部分,负责管理和控制系统的各种硬件和软件资源。其五大功能包括:

  1. 进程管理:Linux内核负责管理系统中所有的进程和线程,包括进程的创建、销毁、调度和同步等。它还负责为进程分配和管理系统资源,如CPU时间、内存、文件句柄等。
  2. 内存管理:Linux内核负责管理系统中的内存资源,包括内存分配、释放和回收等。它还负责为进程提供虚拟内存管理功能,包括内存映射、分页、缓存和交换等。
  3. 文件系统管理:Linux内核支持多种文件系统,包括常见的ext4、NTFS、FAT32等。它负责管理文件系统中的文件和目录,提供文件读写、权限管理、硬链接和软链接等功能。
  4. 设备驱动管理:Linux内核支持多种硬件设备,如磁盘驱动器、网卡、USB设备等。它负责管理和控制这些设备,提供设备驱动程序和设备文件等接口,使应用程序可以访问和控制这些设备。
  5. 网络协议管理:Linux内核支持多种网络协议,包括TCP/IP、UDP、ICMP等。它负责管理网络连接、数据传输和协议处理,提供网络套接字和套接字接口等接口,使应用程序可以访问和控制网络资源。
02.Linux驱动程序的功能是什么?

Linux驱动程序是一个用于连接操作系统和硬件设备之间的软件程序,其主要功能是向操作系统提供访问硬件设备的接口和服务。Linux驱动程序的功能可以概括如下:

  1. 硬件控制:驱动程序提供了访问和控制硬件设备的接口和服务,如读写硬件寄存器、控制硬件中断和 DMA、处理硬件错误等。
  2. 设备管理:驱动程序管理设备的资源分配和释放,包括内存分配、中断处理、设备注册和注销等。
  3. 文件系统支持:驱动程序将硬件设备抽象成文件系统中的设备节点,提供了文件系统接口和服务,使应用程序可以像访问文件一样访问硬件设备。
  4. 性能优化:驱动程序可以通过优化硬件访问方式、减少中断处理延迟等方式提高系统的性能。
  5. 安全性保障:驱动程序可以限制对硬件设备的访问和操作,防止对系统的攻击和破坏。
03.内核镜像格式有几种?分别有什么区别?

u-boot.bin:

u-boot.bin是一种常见的嵌入式Linux系统引导加载程序,它是由U-Boot项目开发的一个开源软件,用于在嵌入式系统启动时加载内核和文件系统。u-boot.bin通常是在编译U-Boot源代码时生成的可执行二进制文件,它可以直接烧录到系统的启动设备上,以实现系统的启动。这个u-boot.bin就叫镜像(image)

vmlinux:

vmlinux是Linux内核的未压缩二进制文件,它包含了内核的全部代码和数据,通常只用于调试和分析目的。vmlinux文件通常比压缩后的内核镜像文件(如zImage)要大得多,因为它没有进行压缩。经过制作加工成烧录镜像的文件就叫Image

Image:

Image是指经过制作加工后的内核镜像文件,它通常是指将内核代码、设备树(Device Tree)和根文件系统(Root Filesystem)等文件打包成一个文件,以便在启动时由引导加载程序加载。Image文件可以使用mkimage工具进行制作,其中包括U-Boot的mkimage工具和Linux内核源码中的mkimage工具,制作完成后可以直接烧录到启动设备上。

zImage:

zImage是一种针对ARM和x86等架构的压缩格式的内核镜像文件,它将内核代码进行压缩后存储,占用空间相对较小。在ARM架构中,zImage是由mkimage工具制作的,其中包括了压缩后的内核代码、设备树和命令行参数等信息。压缩格式的镜像就叫zImage

uImage:

uImage是一种由zImage加工得到的格式化镜像文件,它将zImage文件添加了一些附加信息,如内核版本、编译时间、编译器版本等,并且可以在启动时进行验证以确保文件完整性和安全性。uImage通常由mkimage工具制作,它也可以包含设备树和命令行参数等信息。在使用U-Boot引导加载程序的嵌入式系统中,通常使用uImage文件作为内核镜像文件进行启动。

uvIzu

04.Linux内核镜像里的具体内容?

Linux内核镜像是一个包含操作系统内核代码的二进制文件。它是操作系统启动过程中加载的核心组件之一。具体内容会因内核版本和编译选项而异,但通常包含以下几个主要组成部分:

  1. 启动加载程序(Bootloader): 内核镜像的头部通常包含有关如何加载内核的信息,例如GRUB或LILO等引导加载程序使用的元数据。
  2. 内核代码段: 这是Linux内核的实际代码,负责管理系统的核心功能,如进程管理、内存管理、设备驱动程序、网络协议栈等。
  3. 初始化数据: 内核镜像可能包含一些初始化数据结构,用于设置内核的初始状态和参数。
  4. 模块: 在一些Linux系统中,部分功能被编译为模块,而不是直接编译进内核镜像。这些模块可以在运行时动态加载到内核中,以便根据需要添加或移除功能。
  5. 符号表: 内核镜像中可能包含用于调试的符号表,这些符号表提供了函数和变量名称的映射,便于开发人员进行内核调试。
05.得到一个Linux Kernel的软件包后编译安装的过程。

编译和安装Linux内核的过程一般包括以下几个步骤:

1.安装前置软件包

2.下载并解压内核源码包

将下载的Linux内核软件包解压缩到一个目录中,例如:

$ tar xvf linux-x.y.z.tar.gz
$ cd linux-x.y.z

3.配置交叉编译工具链

vim ~/.bashrc
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihfexport PATH=$PATH:/home/用户名/100ask_firefly-rk3288/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin

4.配置内核

在Linux内核目录下执行 make menuconfig 命令,通过交互式的方式配置内核选项。在这个过程中,可以选择需要编译进内核的模块和驱动程序、修改内核的配置参数等等。完成配置后,将配置保存到 .config 文件中,例如:

$ make deconfig
$ make menuconfig
$ make savedefconfig

5.编译内核

执行 make 命令编译内核。编译时间可能会比较长,具体取决于计算机的性能和内核的复杂程度。可以通过指定 -j 选项使用多个CPU核心并行编译,例如:

$ make -j8

6.安装内核

编译完成后,执行 make modules_install 命令安装内核模块,然后执行 make install 命令将内核安装到系统中。这个过程会将内核文件复制到/boot目录下,并更新系统引导程序的配置文件。例如:

$ make modules_install
$ make install

7.重启系统

完成内核安装后,重启系统以应用新的内核。在引导时,选择新内核启动即可。

注意:在执行上述过程之前,应当备份重要的系统文件和数据,以避免意外情况发生导致数据丢失或系统不稳定。此外,对于生产环境的系统,建议在正式应用前进行充分的测试和验证。

06.Linux内核源码启动分析
  1. BIOS/UEFI阶段:计算机开机后首先会执行BIOS或UEFI程序,进行一些硬件初始化操作,如检查硬件配置信息、启动自检程序、加载操作系统引导程序等。
  2. Bootloader阶段:BIOS/UEFI会加载引导程序,比如GRUB等,这个引导程序会在屏幕上显示一个菜单,供用户选择要启动的操作系统,如果只有一个操作系统,那么该引导程序将自动启动内核。引导程序会根据用户选择或默认设置找到内核映像文件,加载到内存中。
  3. 内核启动自解压阶段:内核启动时,它首先会解压缩自身,然后进行一系列的初始化工作,如初始化CPU、内存管理、设备管理、文件系统等。其中,内存管理是最重要的一步,因为内核需要将系统中的所有可用内存映射到自己的地址空间中。
  4. 内核引导阶段:
  5. init进程启动阶段:当内核初始化完毕后,会启动init进程。在Linux系统中,init进程是用户空间中的第一个进程,它负责初始化系统环境,包括加载配置文件、启动系统服务等。
  6. 过渡到rootfs
07.内核链表为什么具有通用性?

内核链表——一种可以存放不同数据类型的通用链表 - 知乎 (zhihu.com)

Linux内核链表——看这一篇文章就够了 - Crystal_Guang - 博客园 (cnblogs.com)

内核中由于要管理大量的设备,但是各种设备各不相同,必须将他们统一起来管理,于是内核设计者就想到了使用通用链表来处理,通用链表看似神秘,实际上就是双向循环链表,这个链表的每个节点都是只有指针域,没有任何数据域。

使用通用链表的好处是:

  1. 通用链表中每个节点中没有数据域,也就是说无论数据结构有多复杂在链表中只有前后级指针。
  2. 如果一个数据结构(即是描述设备的设备结构体)想要用通用链表管理,只需要在结构体中包含节点的字段即可
  3. 双向链表可以从任意一个节点的前后遍历整个链表,遍历非常方便。
  4. 使用循环链表使得可以不断地循环遍历管理节点,像进程的调度:操作系统会把就绪的进程放在一个管理进程的就绪队列的通用链表中管理起来,循环不断地,为他们分配时间片,获得cpu进行周而复始的进程调度。
08.Linux内核的调度策略有哪些?

剖析Linux内核进程调度策略_哔哩哔哩_bilibili alt

Linux内核提供了多种调度策略,常用的调度策略有以下几种:

  1. 限期进程使用限期调度策略(SCHED_DEADLINE) ;
  2. 实时进程支持两种调度策略(先进先出调度策略SCHED_FIFO,轮流调度策略SCHED_RR)。
  3. 普通进程支持两种调度策略(标准轮流分时调度策略SCHED_NORMAL,空闲调度策略SCHED_IDLE)

进程优先级:限期进程>实时进程>普通进程

  • 限期调度策略有3个参数:运行时间runtime,截止期限deadline及周期period。每个周期运行一次,在截止期限之前执行完毕,一次运行的时间长度runtime
  • 先进先出调度没有时间片,如果没有更高优先级实时进程,并且它不睡眠,将会一直占用处理器。
  • 轮流调度有时间片,进程用完时间片之后加入优先级对应运行队列尾部.把处理器让给优先级相同的其它实时进程。
  • 标准轮流分时策略使用CFS算法,把处理器赶时间公平地分配给每个进程。
  • 空闲调度策略用来执行优先级低的后台作业。

linux内核分析一CFS (完全公平调度算法)_linux cfs_九阈的博客-CSDN博客

Completely Fair Scheduler (CFS):完全公平调度器是Linux内核默认的调度器。它引入权重,分配给进程时间,并采用红黑树数据结构来管理任务,通过动态调整任务的优先级和时间片来实现公平调度。

Completely Fair Queuing (CFQ) Scheduler:CFQ调度器是一种I/O调度器,它通过维护一个I/O请求队列,以尽量平衡各个进程对I/O资源的使用,从而提高整个系统的I/O性能。

MuQSS Scheduler:MuQSS调度器是一种基于CFS的改进版本,它提供了更佳的响应性和更佳的实时性能。

记忆:三大五小:限时通,限先轮标空

09.BootLoader、Linux内核、根文件系统的关系?

BootLoader是指引导加载程序,是在计算机启动时最先加载的程序。BootLoader的主要作用是将操作系统内核加载到内存中,并执行内核启动。在Linux系统中,常用的BootLoader有Grub、LILO和Syslinux等。

Linux内核是操作系统的核心部分,它负责管理系统硬件、文件系统、内存管理和进程调度等核心任务。在启动过程中,BootLoader会加载Linux内核到系统的内存中,并执行内核启动。一旦内核启动成功,它就会接管系统的控制权,开始对系统进行初始化和配置。

根文件系统是Linux系统的根目录,它包含了操作系统所需的所有文件和目录。在系统启动过程中,内核需要找到根文件系统并将其挂载到文件系统树上,以便操作系统能够正常地运行。根文件系统可以是本地磁盘、网络共享目录或者其他存储设备。

10.Linux进程有几种状态?

剖析Linux中进程的六种状态 - 知乎 (zhihu.com) alt

**R运行状态(running)**并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列。

**S睡眠状态(sleeping)**意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))。

**D磁盘休眠状态(Disk sleep)**有时候也叫不可中断睡眠状态(uninterruptible sleep),这个状态的进程通常会等待IO的结束。

**T停止状态(stopped)**可以发送 SIGSTOP 信号给进程来停止进程。被暂停的进程可以发送 SIGCONT 信号让进程继续运行。

**Z僵尸状态(Zombies)**父进程不读取子进程结束信息。

**X死亡状态(dead)**当父进程读取子进程的返回结果时,子进程立刻释放资源。

t追踪停止状态(trancing stop)

运睡眠,停死尸

#牛客创作充电计划##C++##嵌入式##面试##八股#
【嵌入式八股】嵌入式Linux 文章被收录于专栏

查阅整理上千份嵌入式面经,将相关资料汇集于此,主要包括: 0.简历面试 1.语言篇 2.计算机基础 3.硬件篇 4.嵌入式Linux【本专栏】 (建议PC端查看)

全部评论
自学得要多久才能入门?
1
送花
回复 分享
发布于 2023-03-31 18:30 山东

相关推荐

头像
不愿透露姓名的神秘牛友
05-13 09:07
1. 什么是函数指针?2. 虚函数和纯虚函数的区别是什么?3. 在C++中,如何实现函数重载?4. 什么是函数模板?如何使用函数模板实现通用函数?5. 解释一下C++中的静态成员函数和虚函数之间的区别。6. 在C++中,如何使用默认参数来定义函数?7. 什么是函数占位符?它在C++中的使用场景是什么?8. 什么是函数重载?它的满足条件是什么?9. 在C++中,如何实现多态性?虚函数表是如何实现多态的?10. 什么是函数调用约定?在ARM体系结构中,函数参数是如何传递的?11. 解释一下类和对象在面向对象编程中的概念。12. 封装、继承和多态在面向对象编程中的作用分别是什么?13. 什么是深拷贝和浅拷贝?它们在C++中的应用场景是什么?14. 在C++中,什么是友元函数?它的作用是什么?15. 结构体和类在C++中有何区别?它们的默认访问权限有何不同?16. 在嵌入式系统中,为什么需要交叉编译?17. 基于RAM和基于ROM的嵌入式系统运行方式有何区别?18. 什么是ARM处理器的哈弗结构和冯诺依曼结构?它们的特点是什么?19. ARM流水线技术是如何提高处理器性能的?20. ARM处理器中有多少32位寄存器?这些寄存器的作用是什么?21. ARM指令集包含哪些类别?它们各自的特点是什么?22. ARM处理器有多少种工作状态?这些工作状态分别是什么?23. 在ARM体系结构中,函数调用时参数是如何传递的?24. 什么是锁相环在嵌入式系统中的作用?25. 中断和异常在嵌入式系统中有何区别?26. 中断和DMA在嵌入式系统中的应用场景有何不同?27. 中断的响应执行流程是怎样的?28. 中断和轮询在嵌入式系统中的区别是什么?29. 如何使用位操作统计一个整数的二进制表示中1的个数?30. 在不使用第三个变量的情况下,如何交换两个变量的值?  c++/嵌入式面经专栏-牛客网 https://www.nowcoder.com/creation/manager/columnDetail/MJNwoM
查看30道真题和解析
点赞 评论 收藏
分享
La_place:选JAVA,CPP其实比JAVA更卷。主要是因为JAVA覆盖的公司多,范围广,hc也多,机会更多。cpp小厂用的不多,大厂学历卷的飞起,难度很大。
点赞 评论 收藏
分享
7 11 评论
分享
牛客网
牛客企业服务