Linux操作系统面试总结

1.系统启动流程。

uboot -> kernel -> 根文件系统。

uboot第一阶段属于汇编阶段:

定义入口(start.S):uboot中因为有汇编阶段参与,因此不能直接找main.c。

设置异常向量:当硬件发生故障的时候CPU会强制PC指针指向对应的异常入口执行代码。

设置CPU为SVC模式(设置CPU速度、时钟频率和中断控制寄存器)。

初始化内存控制器(MMU),实现虚拟地址到物理地址的映射。

跳转到lowlevel_init函数,关看门狗,供电锁存,时钟初始化。

初始化堆栈,DDR。

uboot第二阶段属于C语言阶段:

uboot的第二阶段就是要初始化剩下的还没被初始化的硬件。主要是SoC外部硬件(譬如iNand、网卡芯片····)、uboot本身的一些东西(uboot的命令、环境变量等····)。

调用一系列的初始化函数:init_sequence里的init函数是一个函数指针数组,数组中存储了很多个函数指针,会去调用其他初始化函数。

cpu_init(CPU内部的初始化),board_init(x210开发板相关的初始化),interrupt_init(初始化定时器),env_init(环境变量有关的初始化),

init_baudrate(初始化串口通信的波特率),serial_init(初始化串口),display_banner(用来串口输出显示uboot的信息)。

uboot启动内核:

启动内核第一步:加载内核到DDR中,boot只需要从SD卡的kernel分区去读取内核镜像到DDR中即可。

启动内核第二步:校验内核格式(zImage格式,uImage格式)。

启动内核第三步:内核传参。

内核启动过程:

内核启动的汇编阶段:

__lookup_processor_type:读取出硬件的CPU ID号,__lookup_machine_type:本函数校验的是机器码,

__vet_atags:用来校验uboot通过tag给内核传的参数。

内核启动C语言阶段:

lockdep_init:锁定依赖,是一个内核调试模块,处理内核自旋锁死锁问题相关的。

boot_init_stack_canary:用来防止栈溢出。

cgroup_init_early:control group,内核提供的一种来处理进程组的技术。

local_irq_disable:屏蔽当前CPU上的所有中断。

lock_kernel:获得大内核锁,该锁可以用来锁定整个内核。

page_address_init:函数初始化高端内存页表池的链表。

打印内核版本信息。

最后会执行init进程,init进程刚开始运行的时候是内核态,然后他自己运行了一个用户态下面的程序后把自己强行转成了用户态。

init进程会去挂载根文件系统,打开控制台,访问一个设备,就要去打开这个设备对应的文件描述符。譬如/dev/fb0这个设备文件就代表LCD显示器设备。

根文件系统:

根文件系统是特殊用途的文件系统,文件系统是一些代码,是一套软件,这套软件的功能就是对存储设备的扇区进行管理,将这些扇区的访问变成了对目录和文件名的访问.

2.什么是操作系统

操作系统是运行在计算机上最重要的一种软件,它管理计算机的资源和进程以及所有的硬件和软件。它为计算机硬件和软件提供了一种中间层,使应用软件和硬件进行分离。

3.操作系统的主要功能

进程管理: 进程管理的主要作用就是任务调度,在单核处理器下,操作系统会为每个进程分配一个任务。

内存管理:内存管理主要是操作系统负责管理内存的分配、回收。

设备管理:根据确定的设备分配原则对设备进行分配,使设备与主机能够并行工作。

文件管理:有效地管理文件的存储空间,合理地组织和管理文件系统。

提供用户接口:操作系统提供了访问应用程序和硬件的接口。

4.操作系统的主要目的

  • 管理计算机资源,这些资源包括 CPU、内存、磁盘驱动器、打印机等。
  • 提供一种图形界面,就像我们前面描述的那样,它提供了用户和计算机之间的桥梁。
  • 为其他软件提供服务,操作系统与软件进行交互,以便为其分配运行所需的任何必要资源。

5.什么是进程,什么是线程?

进程是系统中正在运行的一个程序,程序一旦运行就是进程,进程可以看成程序执行的一个实例。

线程是CPU独立运行和独立调度的基本单位,一个进程可以拥有多个线程,线程是进程的一个实体,是进程的一条执行路径。

6.进程和线程之间的区别是什么

因为进程拥有独立的堆栈空间和数据段,所以每当启动一个新的进程必须分配给它独立的地址空间,系统开销比较大。

而线程不一样,线程拥有独立的堆栈空间,但是共享数据段,它们彼此之间使用相同的地址空间,共享大部分数据,比进程更节俭,开销比较小,切换速度也比进

程快,效率高。

通信机制上面,正因为进程之间互不干扰,相互独立,进程的通信机制相对很复杂,譬如管道,信号,消息队列,共享内存,套接字等通信机制,而线程由于

共享数据段所以通信机制很方便。

7.多进程和多线程的优缺点

进程优点:每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系;

进程缺点:需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算多进程调度开销比较大。

线程优点:能适当提高程序的执行效率,能适当提高资源的利用率。

线程缺点:每个线程与主程序共用地址空间,受限于2GB地址空间;

8.什么时候使用进程,什么时候使用线程

当频繁创建和销毁的时候,当然是线程。

当考虑的安全性的问题时候,是进程.

提高cpu利用率,是线程。

9.线程在一定条件下,状态会发生变化。线程一共有以下5种状态

新建状态:新创建了一个线程对象。

就绪状态:线程只等待获取CPU的使用权。

运行状态:就绪状态的线程获取了CPU使用权。

阻塞状态:阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。

死亡状态:线程执行完了或者因遇到error或exception退出了run()方法,该线程结束生命周期。

10.孤儿进程,僵尸进程和守护进程

孤儿进程:指的是在其父进程执行完成或被终止 后仍继续运行的一类进程。

僵尸进程:如果子进程退出,而父进程并没有调用 wait() 或 waitpid()去回收的一类进程。

守护进程:是运行在后台的一种特殊进程。守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。

11.进程之间通信的途径有哪些?

无名管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。

有名管道 (named pipe) :有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们成为高级管道方式。

消息队列( message queue ) :消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。

套接字( socket ) :套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。

12.进程上下文

进程上文:其是指进程由用户态切换到内核态是需要保存用户态时cpu寄存器中的值,进程状态以及堆栈上的内容,即保存当前进程的进程上下文,

以便再次执行该进程时,能够恢复切换时的状态,继续执行。

进程下文:其是指切换到内核态后执行的程序,即进程运行在内核空间的部分。

13.LINUX中的虚拟地址空间

防止不同进程同一时刻在物理内存中运行而对物理空间的争夺采用虚拟地址空间。虚拟内存使得不同进程运行过程中,

每个进程只把自己目前需要的虚拟内存空间映射存储到物理空间中。

实际上,每个进程创建时,内核只为进程创建虚拟内存的布局,并不立即把虚拟内存和磁盘文件

之间的映射拷贝到物理内存中,等到运行时才会来拷贝数据。
 

14.linux怎么进行内存管理?

对内存的分配和管理,也就是平时应用层malloc和内核层vmalloc、kmalloc之类的内存申请的管理

虚拟内存和物理内存之间的转换

15.驱动中操作物理绝对地址为什么要先ioremap?

因为在内核中操作的都是虚拟地址,内核访问不到物理地址,只能通过ioremap映射为虚拟地址,内核才能访问此内存空间

16.操作系统为什么要分内核态和用户态

为了安全,在CPU的一些指令中,有的指令如果用错,就会导致整个系统崩坏,分了内核态和

用户态之后,当用户需要操作这些指令的时候,内核为其提供了API,可以通过系统调用陷入

内核,让内核去执行这些操作。

17.死锁产生的原因

死锁产生的原因大致有两个:资源竞争和程序执行顺序不当

18.死锁产生的必要条件

互斥条件:每个资源都被分配给了一个进程或者资源是可用的。

保持和等待条件:已经获取资源的进程被认为能够获取新的资源。

不可抢占条件:分配给一个进程的资源不能强制的从其他进程抢占资源,它只能由占有它的进程显示释放。

循环等待:死锁发生时,系统中一定有两个或者两个以上的进程组成一个循环,循环中的每个进程都在等待下一个进程释放的资源。

19.insmod 一个驱动模块,会执行模块中的哪个函数?rmmod呢?这两个函数在设计上要注意哪些?遇到过卸载驱动出现异常没?是什么问题引起的?

insmod调用init函数,rmmod调用exit函数。设计时需要严格记住相关内存的操作后必须在exit中进行释放,

避免内存泄漏。如存储,ioremap,定时器,工作队列等等。卸载失败原因是因为有进程正在使用该模块,这跟我们在windows下拔出正在使用的U盘类似。

20.linux引入模块的好处。

该机制有助于缩短模块的开发周期。

21.copy_to_user()和copy_from_user()主要用于实现什么功能?一般用于file_operations结构的哪些函数里面?

由于内核空间和用户空间是不能互相访问的,如果需要访问就必须借助内核函数进行数据读写。

copy_to_user():完成内核空间到用户空间的复制。

copy_from_user():是完成用户空间到内核空间的复制。

一般用于file_operations结构里的read,write,ioctl等内存数据交换作用的函数。当然,如果ioctl没有用到内存数据复制,那么就不会用到这两个函数。
 

22.内核函数mmap的实现原理,机制?

mmap函数实现把一个文件映射到一个内存区域,从而我们可以像读写内存一样读写文件,他比单纯调用read/write也要快上许多。

在某些时候我们可以把内存的内容拷贝到一个文件中实现内存备份,当然,也可以把文件的内容映射到内存来恢复某些服务。

另外,mmap实现共享内存也是其主要应用之一,mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存。
 

23.用户空间与内核通信方式有哪些?

系统调用。用户空间进程通过系统调用进入内核空间,访问指定的内核空间数据;

)驱动程序。用户空间进程可以使用封装后的系统调用接口访问驱动设备节点,以和运行在内核空间的驱动程序通信;

共享内存mmap。在代码中调用接口,实现内核空间与用户空间的地址映射,在实时性要求很高的项目中为首选,省去拷贝数据的时间等资源,但缺点是不好控制;

copy_to_user()、copy_from_user(),是在驱动程序中调用接口,实现用户空间与内核空间的数据拷贝操作,应用于实时性要求不高的项目中。
 

24.Linux驱动程序的功能是什么?

设备驱动连接操作系统和硬件。设备驱动程序是一种可以使计算机与设备进行通信的特殊程序,可以说相当于硬件的接口。操作系统只有通过这个接口,

才能控制硬件设备的工作。安装在操作系统中的驱动程序可以完成设备的初始化和释放,进行外部数据和操作系统的通信和数据交互,控制硬件的行为,

并检查设备可能出现的故障并报错。
 

25.Linux驱动程序的分类有哪些?

Linux将硬件设备分为3大类,分别是字符设备、块设备和网络设备。字符设备是指那些能一个字节一个字节读取数据的设备,如键盘鼠标等,

常见的SPI/I2C/UART默认也是字符设备。块设备与字符设备类似,一般是像磁盘一样的设备。网络设备主要负责主机之间的数据交换。

与字符设备和块设备完全不同,网络设备主要是面向数据包的接收和发送而设计的。
 

26.linux的锁机制?

互斥锁:mutex,保证在任何时刻,都只有一个线程访问该资源,当获取锁操作失败时,线程进入阻塞,等待锁释放。

读写锁:rwlock,分为读锁和写锁,处于读操作时,可以运行多个线程同时读。但写时同一时刻只能有一个线程获得写锁。

自旋锁:spinlock,在任何时刻只能有一个线程访问资源。但获取锁操作失败时,不会进入睡眠,而是原地自旋,直到锁被释放。

           这样节省了线程从睡眠到被唤醒的时间消耗,提高效率。

条件锁:就是所谓的条件变量,某一个线程因为某个条件未满足时可以使用条件变量使该程序处于阻塞状态。一旦条件满足了,即可唤醒该线程(常和互斥锁配合使用)。

27.设备驱动程序中如何注册一个字符设备?分别解释一下它的几个参数的含义。

注册一个字符设备驱动有两种方法:

 1) void cdev_init(struct cdev *cdev, struct file_operations *fops)

该注册函数可以将cdev结构嵌入到自己的设备特定的结构中。cdev是一个指向结构体cdev的指针,而fops是指向一个类似于file_operations结构(可以是file_operations结构,但不限于该结构)的指针.

2) int register_chrdev(unsigned int major, const char *namem , struct file)operations *fopen);

        该注册函数是早期的注册函数,major是设备的主设备号,name是驱动程序的名称,而fops是默认的file_operations结构(这       是只限于file_operations结构)。对于register_chrdev的调用将为给定的主设备号注册0-255作为次设备号,并为每个  设备建     立一个对应的默认cdev结构。

28.insmod 一个驱动模块,会执行模块中的哪个函数?rmmod呢?这两个函数在设计上要注意哪些?遇到过卸载驱动出现异常没?是什么问题引起的?

 insmod调用init函数,rmmod调用exit函数。这两个函数在设计时要注意什么?卸载模块时曾出现卸载失败的情形,原因是存在进程正在使用模块,检查代码后发现产生了死锁的问题。

      要注意在init函数中申请的资源在exit函数中要释放,包括存储,ioremap,定时器,工作队列等等。也就是一个模块注册进内核,退出内核时要清理所带来的影响,带走一切不留下一点痕迹。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/149410.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

动态内存管理<C语言>

✨Blog:🥰不会敲代码的小张:)🥰 🉑推荐专栏:C语言🤪、Cpp😶‍🌫️、数据结构初阶💀 💽座右铭:“記住,每一天都是一個新的開始&#x1…

微信小程序代驾系统源码(含未编译前端,二开无忧) v2.5

简介: 如今有越来越多的人在网上做代驾,打造一个代驾平台,既可以让司机增加一笔额外的收入,也解决了车主酒后不能开发的问题,代驾系统基于微信小程序开发的代驾系统支持一键下单叫代驾,支持代驾人员保证金…

Python的NumPy库(一)基础用法

NumPy库并不是Python的标准库,但其在机器学习、大数据等很多领域有非常广泛的应用,NumPy本身就有比较多的内容,全部的学习可能涉及许多的内容,但我们在这里仅学习常见的使用,这些内容对于我们日常使用NumPy是足够的。 …

2023.10.5 文件操作IO 经典例题

目录 例题一 例题二 例题一 扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否删除该文件 代码如下: package io;import java.io.File; import java.util.Scanner;//扫描指定目…

RSA攻击:模数分解

目录 一、模数分解总览 1.1直接分解法 1.2费马分解与Pollard_rho分解 1.3公约数分解 1.4其他模数分解 二、实战特训 2.1[黑盾杯 2020]Factor 2.2[GWCTF 2019]babyRSA 2.3[LitCTF 2023]yafu (中级) 2.4[RoarCTF 2019]RSA 2.5[CISCN 2022 西南]rsa 三、总结 一、模数分解总览 …

使用idea 中的rest 将 git 合并部分分支代码到主分支

需求:当要将dev的分支中的部分代码合并到test分支时,又不想把dev的全部代码合并到test分支 例如dev分支已经提交了 demo1到4,到想把demo1-3的代码合并到test分支,demo4暂时不合并 可以使用idea的reset 功能满足以上需求 1首先切…

Seata 源码篇之AT模式启动流程 - 中 - 03

Seata 源码篇之AT模式启动流程 - 中 - 03 数据源代理会话代理锁定查询执行器本地事务提交本地事务回滚 更新执行器删除执行器插入执行器 小节 本系列文章: Seata 源码篇之核心思想 - 01Seata 源码篇之AT模式启动流程 - 上 - 02 数据源代理 当我们的数据源被代理后&#xff0c…

.Net开源迁移框架FluentMigrator的使用。

在实际的开发过程中,经常会遇到数据库结构变动,比如新增表、删除表;已有的表新增字段,删除字段;修改字段属性等等。而且需要开发环境、测试环境和生产环境进行同步。如果使用的是EF,还是挺方便的。而非EF环…

PyTorch入门之【tensor】

目录 tensor的创建tensor的相关信息tensor的运算 tensor的创建 1.手动创建 import torch test1torch.tensor([1,2,3])#一维时为向量 test2torch.tensor([[1,2,3]])#二维时为矩阵 test3torch.tensor([[[1,2,3]]])#三维及以上统称为tensor print(test1) print(test2) print(tes…

【Linux】线程详解完结篇——信号量 + 线程池 + 单例模式 + 读写锁

线程详解第四篇 前言正式开始信号量引例信号量的本质信号量相关的四个核心接口生产消费者模型用环形队列实现生产者消费者模型基于环形队列的生产消费模型的原理代码演示单生产者单消费者多生产者多消费者 计数器的意义 线程池基本概念代码 单例模式STL,智能指针和线程安全STL中…

文心一言 VS 讯飞星火 VS chatgpt (106)-- 算法导论10.1 4题

四、用go语言,重写 ENQUEUE 和 DEQUEUE 的代码,使之能处理队列的下溢和上溢。 文心一言: 在 Go 语言中,我们可以使用切片来实现队列。下面是如何实现 ENQUEUE 和 DEQUEUE 操作,同时处理队列的下溢和上溢的情况&#…

git提交代码的流程

1.拉取代码 当你进入了一家公司就需要拉去公司的代码进行开发,此时你的项目小组长会给你个地址拉代码, git clone 公司项目的地址 此时如果不使用了这个方式拉去代码,拉去的是master分支上的代码,但是很多数的情况下,公司的项目可能会在其它的分支上,因此到公…

经典算法-----汉诺塔问题

前言 今天我们学习一个老经典的问题-----汉诺塔问题,可能在学习编程之前我们就听说过这个问题,那这里我们如何去通过编程的方式去解决这么一个问题呢?下面接着看。 汉诺塔问题 问题描述 这里是引用汉诺塔问题源自印度一个古老的传说&#x…

Python3数据科学包系列(一):数据分析实战

Python3中类的高级语法及实战 Python3(基础|高级)语法实战(|多线程|多进程|线程池|进程池技术)|多线程安全问题解决方案 Python3数据科学包系列(一):数据分析实战 Python3数据科学包系列(二):数据分析实战 认识下数据科学中数据处理基础包: (1)NumPy 俗话说: 要学会跑需先…

<C++>类和对象-下

目录 一、构造函数的初始化 1. 构造函数体赋值 2. 初始化列表 2.1 概念 2.2 隐式类型转换式构造 2.3 explicit关键字 二、static静态成员 1. 概念 2. 特性 三、友元 1. 友元函数 2.友元类 四、内部类 1. 概念 五、匿名对象 1. const引用匿名对象 2. 匿名对象的隐式类型转换 总…

postgresql实现单主单从

实现步骤 1.主库创建一个有复制权限的用户 CREATE ROLE 用户名login # 有登录权限的角色即是用户replication #复制权限 encrypted password 密码;2.主库配置开放从库外部访问权限 修改 pg_hba.conf 文件 (相当于开放防火墙) # 类型 数据库 …

Swing程序设计(5)绝对布局,流布局

文章目录 前言一、布局管理器二、介绍 1.绝对布局2.流布局总结 前言 Swing窗体中,每一个组件都有大小和具体的位置。而在容器中摆放各种组件时,很难判断其组件的具体位置和大小。即一个完整的界面中,往往有多个组件,那么如何将这…

Unity如何实现TreeView

前言 最近有一个需求,需要实现一个TreeView的试图显示,开始我一直觉得这么通用的结构,肯定有现成的UI组件或者插件可以使用,结果,找了好久,都没有找到合适的插件,有两个效果差强人意。 最后在回家的路上突然灵光一闪,想到了一种简单的实现方式,什么插件都不用,仅使用…