102,file_operations是什么?
答:linux驱动程序中最重要的涉及3个重要的内核数据结构,分别为file_operations,file和inode。
在linux中inode结构用于表示文件,而file结构则表示打开的文件的描述,因为对于单个文件而言可能会有许多个表示打开的文件的描述符,因而就可能会的对应有多个file结构,但是都指向单个inode结构。
在系统内部,I/O设备的存取操作通过特定的的入口来进行,而这组特定的入口由驱动程序来提供的。通常这组设备驱动的接口是由结构体file_operations向系统说明的。
第一个 file_operations 成员根本不是一个操作; 它是一个指向拥有这个结构的模块的指针。这个成员用来在它的操作还在被使用时阻止模块被卸载. 几乎所有时间中, 它被简单初始化为THIS_MODULE, 一个在 中定义的宏.这个宏比较复杂,在进行简单学习操作的时候,一般初始化为THIS_MODULE。
举例:static struct file_operations hi35x_fops = {
.owner = THIS_MODULE,
.open = hi35x_open,
.read = hi35x_read,
.write = hi35x_write,
.mmap = hi35x_mmap,
.ioctl = hi35x_ioctl,
.release = hi35x_release
};
参考:http://blog.chinaunix.net/uid-25100840-id-304208.html
103,什么是RISC?
答:精简指令集,是计算机中央处理器的一种设计模式,也被称为RISC(Reduced Instruction Set Computing的缩写)。[1] 这种设计思路对指令数目和寻址方式都做了精简,使其实现更容易,指令并行执行程度更好,编译器的效率更高。常用的精简指令集微处理器包括DECAlpha、ARC、ARM、AVR、MIPS、PA-RISC、PowerArchitecture(包括PowerPC)和SPARC等。这种设计思路最早的产生缘自于有人发现,尽管传统处理器设计了许多特性让代码编写更加便捷,但这些复杂特性需要几个指令周期才能实现,并且常常不被运行程序所采用。此外,处理器和主内存之间运行速度的差别也变得越来越大。在这些因素促使下,出现了一系列新技术,使处理器的指令得以流水执行,同时降低处理器访问内存的次数。早期,这种指令集的特点是指令数目少,每条指令都采用标准字长、执行时间短、中央处理器的实现细节对于机器级程序是可见的。
参考:https://baike.so.com/doc/6099149-6312257.html
104,嵌入式ubuntu怎么加载i2c总线?
答:Linux定义了系统的IIC驱动体系结构,在Linux系统中,IIC驱动由3部分组成,即IIC核心、IIC总线驱动和IIC设备驱动。这3部分相互协作,形成了非常通用、可适应性很强的IIC框架。
参考:https://zhidao.baidu.com/question/1435019384330844339.html
105,什么情况导致段错误(核心已转储)?
答:所谓的段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了。
通过上面的解释,段错误应该就是访问了不可访问的内存,这个内存区要么是不存在的,要么是受到系统保护的。
情况1)访问不存在的内存地址;
情况2)访问系统保护的内存地址;
情况3)访问只读的内存地址;
情况4)访问空指针;
情况5)内存越界(数组越界,变量类型不一致等);
情况6)堆栈溢出。
参考:https://blog.csdn.net/qq_29350001/article/details/53780697
106,BIOS的作用?
答:BIOS的中文名称就是基本输入输出系统,其主要功能是为计算机提供最底层的、最直接的硬件设置和控制。
BIOS的功能分为三个部分:
第一部分是自检及初始化,即主要负责启动电脑,包括用于电脑刚接通电源时对硬件部分的检测、初始化、引导程序;
第二部分是程序服务处理,即主要是为应用程序和操作系统服务,这些服务主要与输入输出设备有关,例如读磁盘、文件输出到打印机等;
第三部分是硬件中断处理,主要是分别处理PC机硬件的需求,BIOS的服务功能是通过调用中断服务程序来实现的,这些服务分为很多组,每组有一个专门的中断。
参考:https://baike.so.com/doc/24988424-25948540.html
107, Bootloader种类?
答:嵌入式Linux系统已经有各种各样的Bootloader,种类划分的方法也不是唯一的,一般可以按照它所支持处理器体系结构不同进行划分,如下表:
Bootloader | Mointor | 描述 | X86 | ARM | PowerPC |
LILO | 否 | Linux磁盘引导程序 | 是 | 否 | 否 |
Grub | 否 | GNU引导的LILO替代程序 | 是 | 否 | 否 |
Loadlin | 否 | 从DOS引导Linux | 是 | 否 | 否 |
ROLO | 否 | 从ROM引导Linux而不需要BIOS | 是 | 否 | 否 |
Etherboot | 否 | 通过以太网启动Linux引导程序 | 是 | 否 | 否 |
Linux BIOS | 否 | 完全替代BUIS的Linux引导程序 | 是 | 否 | 否 |
Blob | 否 | LART等硬件平台的引导程序 | 否 | 是 | 否 |
U-Boot | 是 | 通用引导程序 | 是 | 是 | 是 |
RedBoot | 是 | 基于eCos的引导程序 | 是 | 是 | 是 |
常见嵌入式Linux的Bootloader有:Blob、Redboot、U-Boot.
108,Bootloader 的启动方式?
答:(1)网络启动方式
这种方式的开发板不需要较大的存储介质,跟无盘工作站有点类似,但是使用这种启动方式之前,需要把Bootloader安装到板上的EPROM或者Flash中。Bootloader通过以太网接口远程下载Linux内核映像或者文件系统。Bootloader下载文件一般都使用TFTP网络协议,还可以通过DHCP的方式动态配置IP地址。
(2)硬盘启动方式
传统的Linux系统运行在台式机或者服务器上,这些计算机一般都使用BIOS引导,并使用磁盘作为存储介质。Linux传统上是LILO (Linux Loader) 引导,后来又出现了GUN的软件 (Grand Unified Bootloader) 。 这两种Bootloader广泛应用在X86的Linux系统上。
(3)Flash启动方式
大多数嵌入式系统上都使用Flash存储介质。Flash有很多类型,包括NOR Flash、NAND Flash和其它半导体盘。它们之间的不同在于: NOR Flash 支持芯片内执行(XIP, eXecute In Place),这样代码可以在Flash上直接执行而不必拷贝到RAM中去执行。而NAND Flash并不支持XIP,所以要想执行 NAND Flash 上的代码,必须先将其拷贝到 RAM中去,然后跳到 RAM 中去执行。NOR Flash 使用最为普遍。Bootloader一般放在Flash的底端或者顶端,这需要根据处理器的复位向量来进行设置。可以配置成MTD设备来访问Flash分区。
109,Bootloader启动过程?
答:嵌入式Linux系统通过Bootloader引导,一上电,就要执行Bootloader来初始化系统。在完成对系统的初始化任务之后,它会将非易失性存储器(通常是 Flash或 DOC 等)中的Linux 内核拷贝到 RAM 中去,然后跳转到内核的第一条指令处继续执行,从而启动 Linux 内核。Bootloader 和 Linux 内核有着密不可分的联系。
Bootloader多数有两个阶段的启动过程:
Stage1:
基本的硬件初始化
为加载stage2准备RAM空间
拷贝内核映像和文件系统映像到RAM中
设置堆栈指针sp
跳到stage2的入口点
Stage2:
初始化本阶段要使用到的硬件设备
检测系统的内存映射
加载内核映像和文件系统映像
设置内核的启动参数
嵌入式系统中广泛采用的非易失性存储器通常是 Flash,而 Bootloader就位于该存储器的最前端,所以系统上电或复位后执行的第一段程序便是 Bootloader。
110, Linux内核的启动过程?
答:Linux 内核有两种映像:一种是非压缩内核,叫 Image,另一种是它的压缩版本,叫zImage。根据内核映像的不同,Linux 内核的启动在开始阶段也有所不同。ZImage 是 Image经过压缩形成的,所以它的大小比 Image 小。但为了能使用 zImage,必须在它的开头加上解压缩的代码,将 ZImage 解压缩之后才能执行,因此它的执行速度比 Image 要慢。但考虑到嵌入式系统的存储空容量一般比较小,采用 zImage 可以占用较少的存储空间,因此牺牲一点性能上的代价也是值得的。所以一般的嵌入式系统均采用压缩内核的方式。
在 Bootloader将 Linux 内核映像拷贝到 RAM 以后,解压内核映像和初始化,完成剩余的与硬件平台相关的初始化工作,再进行一系列与内核相关的初始化后,调用第一个用户进程-init 进程并等待用户进程的执行,这样整个 Linux 内核便启动完毕。在很多情况下,我们可以调用一个简单的 shell 脚本来启动必需的嵌入式应用程序。
111,精简指令集和复杂指令集的区别?
答:
比较内容 | CISC | RISC |
指令系统 | 复杂,庞大 | 简单,精简 |
指令数目 | 一般大于200 | 一般小于100 |
指令格式 | 一般大于4 | 一般小于4 |
寻址方式 | 一般大于4 | 一般小于4 |
指令字长 | 不固定 | 等长 |
可访存指令 | 不加限制 | 只有LOAD/STORE指令 |
各种指令使用频率 | 相差很大 | 相差不大 |
优化编译实现 | 很难 | 很容易 |
程序源代码长度 | 较短 | 较长 |
软件系统开发时间 | 较短 | 较长 |
控制器实现方式 | 绝大多数为微程序控制 | 绝大多数为硬布线控制 |
各种指令执行时间 | 相差很大 | 绝大多数在一个周期内完成 |
参考:https://blog.csdn.net/kai8wei/article/details/51030569
112,linux启动过程?