嵌入式 操作系统(二)
标题:
1.简单说说什么是大端小端,如何判呢?
2.什么是Linux系统态和用户态?什么时候会进入系统态?为什么要区分用户态和系统态?
3.请你说说linux内核的组成?
4.请简单说说linux用户空间与内核通信方式有哪些?
5.IPC(进程间通信)机制中最快的?
6.在linux中系统调用的好处?
7.请说说bootloader、内核和根文件?
8.Bootloader多数有几个阶段的启动过程?
9.为什么需要BootLoader?
内容:
1.简单说说什么是大端小端,如何判呢?
大端模式
在大端模式下,数据的高位字节存放在内存的低地址端,而低位字节存放在高地址端。
给大家举一个例子:整数 0x1234
,假设该整数存储在内存地址 0x1000
和 0x1001
处(2 字节存储),并且使用 大端模式。
0x12
(高字节)存储在0x1000
地址。0x34
(低字节)存储在0x1001
地址。
地址 0x1000 0x1001 内容 0x12 0x34
- 大端模式下,
0x1234
的高字节0x12
存储在最低地址0x1000
,而低字节0x34
存储在高地址0x1001
。
小端模式
在小端模式下,数据的低位字节存放在内存的低地址端,而高位字节存放在高地址端。
如何判断大端或小端?
在 Linux 中,可以使用 lscpu
命令来查看系统的字节序。
$ lscpu | grep "Endianness"
输出类似于:
makefile Endianness: Little Endian
如果是 大端,则输出:
makefile Endianness: Big Endian
当然我们常见的
- 小端为主机字节序,像X86结构DSP都为小端。
- ARM:可以是大端或小端。
- 大端为网络字节序,像keil 则为大端
2.什么是Linux系统态和用户态?什么时候会进入系统态?为什么要区分用户态和系统态?
用户态
用户态是普通应用程序执行的模式。
- 在用户态下,程序不能直接访问硬件资源(如磁盘、内存、CPU寄存器等),也不能执行特权操作(如直接管理内存、控制外设等)。
- 程序只能访问它自己的内存空间,不能访问其他进程的内存空间,也不能执行直接影响操作系统和硬件的操作。
系统态
系统态是操作系统内核执行的模式。内核具有完全的控制权限,可以访问硬件资源、管理内存、控制进程调度等。
什么时候进入系统态?
- 系统调用:当用户程序需要访问操作系统提供的服务时,例如文件操作、内存分配、进程控制等。
- 硬件中断:如硬件设备发出中断请求
- 异常:如程序出现错误
为什么要区分用户态和系统态?
- 通过区分用户态和系统态,操作系统能够确保用户程序不能直接访问硬件或其他程序的内存,从而避免恶意代码直接破坏系统。提供了安全性。
- 在用户态下运行的程序无法直接干预操作系统内核或其他程序,防止了某个用户程序错误导致整个系统崩溃。只有内核态程序(由操作系统控制)可以执行特权操作,保证了系统的稳定性。
- 用户态允许每个应用程序运行在独立的地址空间中,程序之间的内存互不干扰。只有通过系统调用与操作系统交互,才能访问外部资源或进行特权操作。
3.请你说说linux内核的组成?
UNIX系统由内核、shell、文件系统(系统调用和共用函数库)和应用程序等4部分组成
Linux内核
内核是操作系统的核心,具有很多最基本功能,如虚拟内存、多任务、共享库、需求加载、可执行程序和TCP/IP网络功能。Linux内核的模块分为以下几个部分:存储管理、CPU和进程管理、文件系统、设备管理和驱动、网络通信、系统的初始化和系统调用等。
shell
shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。用户通过 Shell 向操作系统发送命令,操作系统再通过 Shell 执行这些命令。Shell 主要用于执行命令行输入的任务,如文件管理、程序执行、输入输出控制等。另外,shell编程语言具有普通编程语言的很多特点,用这种编程语言编写的shell程序与其他应用程序具有同样的效果。
Linux文件系统
文件系统是文件存放在磁盘等存储设备上的组织方法。不同于 Windows 系统的驱动器(如 C:、D:),Linux 使用单一的根目录(/
)作为文件的顶层目录,从而在一个统一的层级结构中组织所有的文件和设备。Linux系统能支持多种目前流行的文件系统,如EXT2、EXT3、EXT4、FAT、FAT32、VFAT、NTFS和F2FS。
Linux应用程序
标准的Linux系统一般都有一套都有称为应用程序的程序集,它包括文本编辑器、编程语言、XWindow、办公套件、Internet工具和数据库等。
linux内核组成
1.进程管理子系统
进程管理的核心就是进程的调度。在 Linux 内核中,进程调度的单元是进程,进程调度控制系统中的多个进程对 CPU 的访问,从宏观上看,系统中的进程在 CPU 中是并发执行的。此外内核通过系统调用提供了应用程序编程接口,例如:创建新进程(fork,exec),结束进程(kill,exit),并且提供了控制进程,同步进程和进程间通信的接口。
2.内存管理子系统
- 主要作用是保证系统安全访问内存区域,且绝大部分 CPU 都是支持内存管理单元的
- 内存管理子系统负责管理每个进程完成从虚拟内存到物理内存的转换,以及系统可用内存空间。
3.文件管理子系统
- 在 Linux 系统中一切皆文件,它把一切资源都看作是文件,包括硬件设备,通常称为设备文件。
4.网络子系统
在 Linux 内核中,与网络相关的代码被 Linux 独立开,形成一个相对独立的子系统,称为网络子系统,网络子系统是一个层次化的结构,可分为以下几个层次:
- Socket 层(也可以称之为协议无关层):Linux 在发展过程中,采用 BSD Socket API 作为自己的网络相关的 API 接口。同时,Linux 的目标又要能支持各种不同的协议族,而且这些协议族都可以使用 BSD Socket API 作为应用层的编程接口,这样一来将 Socket 层抽象出来就能屏蔽不同协议族之间的差异,不会对应用层的使用产生影响。
- 协议层:Linux 网络子系统功能上相当完备,它不仅支持 INET 协议族(也就是通常所说的 TCP/IP 协议族),而且还支持其它很多种协议族,如 INET6、DECnet,ROSE,NETBEUI 等,对于 INET 、INET6 协议族来说,又会进一步将协议族划分为传输层和网络层以及链路层等。
- 网络设备层:网络设备其实是设备驱动层的内容了,它抽象了网卡数据结构,在一个系统中可能存在多种网卡,屏蔽了不同硬件上的差异,这一层提供了一组通用函数供底层网络设备驱动程序使用。
5.设备子系统
系统调用层是 Linux 内核与应用程序之间的接口,而设备驱动则是 Linux 内核与硬件之间的接口,设备驱动程序为应用程序屏蔽了硬件的细节,在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作(打开、读、写和关闭)。
4.请简单说说linux用户空间与内核通信方式有哪些?
系统调用
系统调用是用户空间与内核空间通信的最基本方式。用户程序通过调用系统调用,向内核请求执行特权操作。系统调用提供了用户空间访问硬件资源、管理进程、文件操作、内存管理、网络通信等操作的能力。
共享内存
共享内存是一种进程间通信(IPC)机制,可以让不同的进程共享内存区域。当进程需要大量的数据交换时,使用共享内存可以提供非常高效的通信方式。
- 操作方式:内核分配一块物理内存区域,并允许多个进程(包括用户空间进程)映射到自己的虚拟地址空间。通过共享内存,进程可以直接读写数据。
- 使用方式: 在 Linux 中,使用 shmget() 和 shmat() 等系统调用来创建和附加共享内存。进程通过内核提供的 API 来操作共享内存。
管道
管道是一种特殊的文件,允许一个进程的输出直接作为另一个进程的输入。管道可以用于用户空间进程之间的通信,也可以通过特殊的设备文件将数据从用户空间传递到内核。
- 无名管道:通常用于父子进程之间的通信。管道创建后,一个进程可以通过
write()
将数据写入管道,另一个进程通过read()
从管道中读取数据。 - 有名管道(FIFO):允许不相关的进程通过文件系统中的特殊文件进行通信。通过
mkfifo()
创建管道文件,然后进程通过open()
、read()
和write()
操作进行通信。
套接字
套接字是 Linux 提供的一种用于进程间通信(IPC)以及进程和网络之间通信的机制。套接字可以用于在不同主机之间进行网络通信,也可以用于同一台计算机上不同进程之间的通信。
- UNIX 域套接字:用于同一台机器上的进程间通信(IPC)。进程可以通过文件系统中的路径来访问和通信。
- 网络套接字:用于进程之间通过网络进行通信,支持 TCP/IP 协议,常用于客户端-服务器模式的应用程序。
文件接口
文件接口是用户空间程序通过文件接口读写文件来与内核进行通信,传递数据和命令。
中断
中断是由外部硬件或内核产生的信号,告诉 CPU 停止当前执行的任务,转而处理某些紧急任务。中断机制本身并不直接提供用户空间和内核的通信,但在硬件中断的处理过程中,内核通常需要与用户空间进行交互。
- 硬件中断:如键盘输入、鼠标点击、网络数据包到达等,这些外部事件会触发硬件中断,内核接管控制权。
- 软件中断:内核或用户空间程序可以通过系统调用触发软件中断,进而切换到内核模式执行操作。
5.IPC(进程间通信)机制中最快的?
共享内存
原因:
与其他 IPC 机制(如管道、消息队列、套接字等)不同,使用共享内存时,进程之间的通信不需要内核进行数据的复制。数据可以直接从一个进程写入共享内存区域,另一个进程可以直接读取这些数据,极大减少了上下文切换和内核调用的开销。
6.在linux中系统调用的好处?
隔离用户空间和内核空间
- 提高安全性:通过限制用户程序的直接访问权限,避免恶意程序直接操作硬件或破坏系统资源。
- 防止崩溃:用户程序发生错误时不会直接影响内核,减少因程序崩溧引起的整个系统崩溃的风险。
简化用户程序与硬件的交互
- 简化开发:开发者无需编写与硬件直接交互的代码,内核为用户程序提供了统一的、高度抽象的接口,隐藏了硬件的复杂性。
- 提高可移植性:通过系统调用,用户程序与操作系统之间的接口是一致的,不同硬件平台下的操作系统可以实现不同的底层硬件操作,但用户程序依然使用相同的系统调用接口。
提供访问系统资源的统一接口
系统调用为程序提供了统一、规范化的接口,使得程序可以方便地访问各种操作系统资源,如文件、设备、网络、内存、进程等。这些接口包含了对底层硬件的抽象,可以让程序在不关心硬件细节的情况下进行复杂的操作。常见的操作系统资源如文件、网络接口、设备等,都通过系统调用提供了标准接口。
- 文件操作:如
open()
,read()
,write()
,close()
等。 - 进程管理:如
fork()
,exec()
,exit()
,wait()
等。 - 内存管理:如
malloc()
,mmap()
,brk()
等。
提供系统级服务
系统调用使得用户程序能够访问内核层次的功能,如进程管理、文件系统操作、网络通信、内存分配等,这些功能对用户程序的高效运行至关重要。通过系统调用,用户程序能够:
- 创建和管理进程、分配内存、操作设备、执行网络通信等。
- 与硬件交互:虽然用户程序不能直接与硬件交互,但通过系统调用可以访问底层硬件(如磁盘、网络、显示器等),进行数据读写、设备控制等。
7.请说说bootloader、内核和根文件?
Bootloader(引导加载程序)
Bootloader 是操作系统启动过程中首先执行的程序。它的作用是引导和加载操作系统内核,负责系统的引导和初始化。它可以包括固化在固件中的boot代码和Bootloader程序。Bootloader 在系统启动时从计算机的存储介质(如硬盘、固态硬盘、U 盘等)中读取内核映像,加载到内存中并传递控制权给内核。
常见的 Bootloader 包括:
- GRUB:广泛用于 Linux 系统。
- LILO:较旧的 Linux 引导程序,已经被 GRUB 取代。
- U-Boot:通常用于嵌入式系统。
内核
内核是操作系统的核心部分,负责管理计算机硬件和系统资源,提供程序运行所需的环境和接口。内核执行的任务包括:
- 硬件管理:包括内存管理、CPU 调度、磁盘 I/O、网络通信等。
- 进程管理:创建和调度进程,处理进程的执行、终止等。
- 文件系统管理:提供对文件的读写、创建、删除等操作。
- 设备驱动程序:通过设备驱动来与硬件进行交互,支持不同的硬件设备。
内核的作用是为上层的应用程序和用户空间提供服务,控制硬件资源,确保系统的稳定性和安全性。
根文件系统
根文件系统是整个操作系统的基础文件系统,包含系统启动后所需的所有文件和目录。在 Linux 系统中,根文件系统是所有文件和目录的起点,所有其他文件系统(如 /home
, /usr
, /var
)都挂载在根文件系统下。此外,嵌入式系统还可以建立在闪存或其他存储设备上的文件系统,用于存储应用程序、配置文件和数据等。
应用程序
应用程序是嵌入式系统中运行在用户空间的程序,利用Linux内核提供的服务和资源完成特定的功能需求。应用程序可以包括各种应用、服务和驱动程序,用于实现各种功能,如通信、控制、数据处理等。
Bootloader、内核和根文件系统的协作
Bootloader 在系统启动时加载内核,并将控制权交给内核。内核接管控制并初始化系统,同时根据 Bootloader 提供的配置,挂载根文件系统。
8.Bootloader多数有几个阶段的启动过程?
第一阶段
- 它的主要任务是加载更大的引导加载程序(第二阶段)到内存中,并将控制权交给第二阶段。
- 基本的硬件初始化(关闭看门狗和中断,MMU(带操作系统),CACHE。 配置系统工作时钟)
- 拷贝内核映像和文件系统映像到RAM中
- 设置堆栈指针sp
- 如果系统支持多重启动(多操作系统),这个阶段还负责选择要启动的操作系统,并加载相应的引导程序。
注意:
- 第一阶段引导程序非常小,通常只有 512 字节,因为它必须适应 MBR 的大小限制。
- 它的功能非常简单,仅负责加载第二阶段的引导程序。
第二阶段:
- 第二阶段的引导程序通常比第一阶段大得多,负责加载和启动操作系统的内核,并进行更多复杂的操作,如系统选择、内核加载、启动参数配置等。
- 第二阶段引导程序通常会提供一个菜单,让用户选择要启动的操作系统或内核。
- 配置内核参数:第二阶段引导程序通常支持传递内核参数(例如 root=/dev/sda1,表示根文件系统的位置)。
- 加载内核映像:将内核映像(如 vmlinuz)从存储设备中读取到内存并启动内核。
- 内核模块加载:有时第二阶段引导程序还会加载一些必要的内核模块,为内核的启动做准备。
9.为什么需要BootLoader?
硬件抽象与初始化
- 初始化 CPU 和 内存,配置硬件使其进入适当的工作模式。
- 检查 硬盘 或其他存储设备是否可用。
- 配置基本的 输入输出设备(如键盘、显示器等)和网络设备。
操作系统的加载
- 加载内核:Bootloader 从存储设备(硬盘、SSD、U 盘等)中加载操作系统内核到内存中。
- 内核映像解压与加载:有些操作系统内核是压缩的,Bootloader 会解压这些内核映像并准备将其加载到内存。
多重启动(Dual-Boot / Multi-Boot)支持
- 选择操作系统:如果计算机上安装了多个操作系统,Bootloader 可以在启动时提供一个菜单,允许用户选择要启动的操作系统。
- 配置启动项:例如,用户可以配置默认启动操作系统的选项,设置启动超时、启动参数等。
加载启动参数
- 根文件系统的位置(如
root=/dev/sda1
); - 内存分配配置;
- 内核调试信息;
- 其他定制的配置(例如,在系统恢复模式下启动)。
系统维护和升级
- Bootloader还可以用于系统维护和固件升级。它可以提供功能,如备份和还原系统、加载和更新固件等。通过这些功能,系统的维护和升级可以更加方便、安全和可靠。
本人双飞本,校招上岸广和通。此专栏覆盖嵌入式常见面试题,有C/C++相关的知识,数据结构和算法也有嵌入式相关的知识,如操作系统、网络协议、硬件知识。本人也是校招过来的,大家底子甚至项目,可能都不错,但是在面试准备中常见八股可能准备不全。此专栏很适合新手学习基础也适合大佬备战复习,比较全面。最终希望各位友友们早日拿到心仪offer。也希望大家点点赞,收藏,送送小花。这是对我的肯定和鼓励。 持续更新中