本人是2020年毕业于广东工业大学研究生:许乔丹,有国内大厂CVTE和世界500强企业嵌入式和安卓开发经验,该专栏整理本人对常见嵌入式高频开发面试题的理解;
网上嵌入式资料千千万,笔者将继续维护专栏,一杯奶茶价格不止提供答案解析,承诺提供专栏内容免费技术答疑,直接咨询即可。助您提高嵌入式面试准备效率,为您面试保驾护航!
本专栏内容主要是面试过程口头提问的问题答案汇总,订阅后送C++资料和笔试真试题,欢迎嵌入式或者安卓交流哈!
5.1 Linux内核相关
5.1.1 Linux内核的组成⭐⭐
5.1.2用户空间与内核通信方式有哪些?⭐⭐⭐⭐⭐
5.1.3系统调用read()/write(),内核具体做了哪些事情⭐⭐
5.1.4系统调用的作用⭐⭐⭐⭐⭐
5.1.5内核态,用户态的区别⭐⭐⭐⭐⭐
5.1.6 bootloader内核 根文件的关系⭐⭐⭐⭐
5.1.7 Bootloader多数有两个阶段的启动过程:⭐⭐⭐
5.1.8 linux的内核是由bootloader装载到内存中的?⭐⭐⭐
5.1.9为什么需要BootLoader⭐⭐⭐⭐
5.1.10 Linux内核同步方式总结⭐⭐⭐⭐
5.1.11为什么自旋锁不能睡眠 而在拥有信号量时就可以?⭐⭐⭐⭐
5.1.12 linux下检查内存状态的命令⭐⭐⭐
5.2 其他操作系统常见面试题
5.2.1大小端的区别以及各自的优点,哪种时候用⭐⭐⭐⭐⭐
5.2.2 linux中怎么查看堆栈⭐⭐⭐
5.2.3什么是堆,栈,内存泄漏和内存溢出?⭐⭐⭐⭐
5.2.4堆和栈的区别⭐⭐⭐⭐⭐
5.2.5死锁的原因、条件 创建一个死锁,以及如何预防⭐⭐⭐⭐⭐
5.2.6硬链接与软链接的区别;⭐⭐⭐⭐⭐
5.2.7虚拟内存,虚拟地址与物理地址的转换⭐⭐⭐⭐
5.2.8计算机中,32bit与64bit有什么区别⭐⭐⭐
5.2.9中断和异常的区别⭐⭐⭐⭐⭐
5.2.10中断怎么发生,中断处理大概流程⭐⭐⭐⭐
5.2.11 select、poll、epoll区别⭐⭐⭐⭐⭐
5.2.12数据库为什么要建立索引,以及索引的缺点⭐⭐
5.2.13 Linux 操作系统挂起、休眠、关机相关命令⭐⭐
解析:
UNIX系统由内核、shell、文件系统(系统调用和共用函数库)和应用程序等4部分组成。
一.Linux内核
内核是操作系统的核心,具有很多最基本功能,如虚拟内存、多任务、共享库、需求加载、可执行程序和TCP/IP网络功能。Linux内核的模块分为以下几个部分:存储管理、CPU和进程管理、文件系统、设备管理和驱动、网络通信、系统的初始化和系统调用等。
二.Linux shell
shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行,是一个命令解释器。另外,shell编程语言具有普通编程语言的很多特点,用这种编程语言编写的shell程序与其他应用程序具有同样的效果。
三.Linux文件系统
文件系统是文件存放在磁盘等存储设备上的组织方法。Linux系统能支持多种目前流行的文件系统,如EXT2、EXT3、FAT、FAT32、VFAT和ISO9660。
四.Linux应用程序
标准的Linux系统一般都有一套都有称为应用程序的程序集,它包括文本编辑器、编程语言、XWindow、办公套件、Internet工具和数据库等。
内核分为 进程管理系统 、 内存管理系统 、 I/O管理系统和文件管理系统 等四个子系统
解析:
1)首先想到的是系统调用,用户空间进程通过系统调用进入内核空间,访问指定的内核空间数据;
2).其次是驱动程序,用户空间进程可以使用封装后的系统调用接口访问驱动设备节点,以和运行在内和空间的驱动程序通信;
3).共享内存mmap,在代码中调用接口,实现内核空间与用户空间的地址映射,在实时性要求很高的项目中为首选,省去拷贝数据的时间等资源,但缺点是不好控制;
4).最后,copy_to_user()、copy_from_user(),是在驱动程序中调用接口,实现用户空间与内核空间的数据拷贝操作,应用于实时性要求不高的项目中。
问: IPC(进程间通信)机制中最快的,可以跨进程的是什么?
我们可以看出,共享内存的消息复制只有两次。一是,从输入文件到共享内存;二是,从共享内存到输出文件。这样就很大程度上提高了数据存取的效率。
以下这个问题忘了哪里看到的,当时也保存下来,但比较少接触到,读者当作阅读看看即可。
问:Linux的用户态与内核态的转换方法?
解答:Linux下内核空间与用户空间进行通信的方式主要有syscall(system call)、procfs、ioctl和netlink等。还有copy_to_user copy_from_user共享内存mmap 驱动
1)syscall:一般情况下,用户进程是不能访问内核的。它既不能访问内核所在的内存空间,也不能调用内核中的函数。Linux内核中设置了一组用于实现各种系统功能的子程序,用户可以通过调用他们访问linux内核的数据和函数,这些系统调用接口(SCI)称为系统调用;
2)procfs:是一种特殊的伪文件系统 ,是Linux内核信息的抽象文件接口,大量内核中的信息以及可调参数都被作为常规文件映射到一个目录树中,这样我们就可以简单直接的通过echo或cat这样的文件操作命令对系统信息进行查取;应该就是根目录里的/proc
3)netlink:用户态应用使用标准的socket API就可以使用netlink提供的强大功能;
4)ioctl:函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。
在这几个通信方式中,效率最高的方式,选择netlink,原因如下:
全双工:procfs是基于文件系统,用于内核向用户发送消息;syscall是用户访问内核。它们都是单工通信方式。netlink是一种特殊的通信方式,用于在内核空间和用户空间传递消息,是一种双工通信方式。使用地址协议簇AF_NETLINK,使用头文件include/linux/netlink.h;
易于添加:为新特性添加system call、或者procfs是一件复杂的工作,它们会污染kernel(内核),破坏系统的稳定性,这是非常危险的。Netlink的添加,对内核的影响仅在于向netlink.h中添加一个固定的协议类型,然后内核模块和应用层的通信使用一套标准的API。
感谢:感谢牛友寞明,指出5.1.2我总共整理开头4个和下面4个总共8个知识点,有点懵(可见评论),在此解释一下:下面4点中syscall就是系统调用,对应上面的第1点系统调用,ioctl那里写着“用户就可以在用户程序中使用ioctl函数控制设备的I/O通道”,对应上面的第2点驱动程序,这个你要自己写过驱动才能理解ioctl的应用,其他两个我其实还没接触过,水平有限。所以说“读者当作阅读看看即可”,面试问到,回答上面4点即可。
解析:本题是本人曾亲自被问到,但感觉还是比较少人会问此问题,所以可能其他人的面经没有这个问题,读者可稍微了解即可。
用户空间read()–>内核空间sys_read()–>scull_fops.read–>scull_read();
该过程分为两个部分:用户空间的处理和核心空间的处理。在用户空间中通过 0x80 中断的方式将控制权交给内核处理,内核接管后,经过6个层次的处理最后将请求交给磁盘,由磁盘完成最终的数据拷贝操作。在这个过程中,调用了一系列的内核函数
解析:
1、为了管理硬件资源和为应用程序开发人员提供良好的环境来使应用程序具有更好的兼容性,为了达到这个目的,内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用(system call)的接口呈现给用户。系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序。
2、具有多任务处理的功能,通常靠进程来实现。
3、为了安全问题,一些I/O操作的指令都被限制在只有内核模式可以执行,因此操作系统有必要提供接口来为应用程序提供诸如读取磁盘某位置的数据的接口,这些接口就被称为系统调用。
4、当操作系统接收到系统调用请求后,会让处理器进入内核模式,从而执行诸如I/O操作,修改基址寄存器内容等指令,而当处理完系统调用内容后,操作系统会让处理器返回用户模式,来执行用户代码。
解析:
系统态(也称为管态或核心态),操作系统在系统态运行——运行操作系统程序
用户态(也称为目态),应用程序只能在用户态运行——运行用户程序
当一个进程在执行用户自己的代码时处于用户运行态(用户态),此时特权级最低,为3级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态。Ring3状态不能访问Ring0的地址空间,包括代码和数据;当一个进程因为系统调用陷入内核代码中执行时处于内核运行态(内核态),此时特权级最高,为0级。执行的内核代码会使用当前进程的内核栈,每个进程都有自己的内核栈。
用户运行一个程序,该程序创建的进程开始时运行自己的代码,处于用户态。如果要执行文件操作、网络数据发送等操作必须通过write、send等系统调用,这些系统调用会调用内核的代码。进程会切换到Ring0,然后进入3G-4G中的内核地址空间去执行内核代码来完成相应的操作。内核态的进程执行完后又会切换到Ring3,回到用户态。这样,用户态的程序就不能随意操作内核地址空间,具有一定的安全保护作用。这说的保护模式是指通过内存页表操作等机制,保证进程间的地址空间不会互相冲突,一个进程的操作不会修改另一个进程地址空间中的数据。