转载自:https://www.jianshu.com/p/9eff04cbbc0f
请问uboot启动过程都做了些什么?
1、cpu刚开始初始化的时候,还未设置栈,所以先使用汇编代码,构建异常项链表,然后设置cpu为svc(特权)模式,同时关闭FIQ和IRQ(防止突发中断程序跑飞了)
注:在跳转到内核之前,要满足CPU出在SVC模式下。
2、对cp15协处理器进行设置,这里主要是关闭MMU和cache
3、进入到板级初始化阶段,这里会进行时钟、内存、串口的初始化。最后还要关闭看门狗。
4、接下来就是设置栈,为c语言准备运行环境,调用board_init_f,填充gd结构体。
5、对代码重定位,搬运到内存中去,搬运之后,跳转到内存中去执行board_init_r,这里就可以开启cache了,当然也可以不开启。然后初始化其他设备。比如flash、网卡、emmc等。初始化完之后,在执行main_loop
为什么uboot要关掉cache?
1、cpu刚开始初始化的时候,还未设置栈,所以先使用汇编代码,构建异常项链表,然后设置cpu为svc(特权)模式,同时关闭FIQ和IRQ(防止突发中断程序跑飞了)
注:在跳转到内核之前,要满足CPU出在SVC模式下。
2、对cp15协处理器进行设置,这里主要是关闭MMU和cache
3、进入到板级初始化阶段,这里会进行时钟、内存、串口的初始化。最后还要关闭看门狗。
4、接下来就是设置栈,为c语言准备运行环境,调用board_init_f,填充gd结构体。
5、对代码重定位,搬运到内存中去,搬运之后,跳转到内存中去执行board_init_r,这里就可以开启cache了,当然也可以不开启。然后初始化其他设备。比如flash、网卡、emmc等。初始化完之后,在执行main_loop
nandflash和norflash的区别,对norflash的操作方式的理解?
两种芯片的结构不同 NORflash之所以可以片内执行,就是因为他符合CPU去指令译码执行的要求。CPU送一个地址出来,NORflash就能给一个数据让CPU执行,中间不需要额外的处理操作。
NAND flash不一样是因为nandflash有地址,数据,命令共用IO口的问题,cpu把地址发出来之后,并不能直接得到数据,还需要控制线的操作才能完成。就是他没有专用的SRAM接口。
嵌入式系统中代码的执行方式主要有3种:
完全映射\按需分页\eXecute In Place (XIP)片上执行。
语句for( ;1 ;)有什么问题?它是什么意思?
无限循环,和while(1)相同。
do……while和while……do有什么区别?
前一个循环一遍再判断,后一个判断以后再循环。
代码输出结果是?
#include <stdio.h>
main()
{
int a,b,c,d;
a=10;
b=a++;
c=++a;
d=10*a++;
printf(“b,c,d:%d,%d,%d”,b,c,d);
return 0;
}
输出结果:
b,c,d:10,12,120
Linux设备中字符设备与块设备有什么主要的区别?
字符设备:字符设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性。字符设备驱动程序通常至少实现open,close,read和write系统调用。字符终端、串口、鼠标、键盘、摄像头、声卡和显卡等就是典型的字符设备。
块设备:和字符设备类似,块设备也是通过/dev目录下的文件系统节点来访问。块设备上能够容纳文件系统,如:u盘,SD卡,磁盘等。
字符设备和块设备的区别仅仅在于内核内部管理数据的方式,也就是内核及驱动程序之间的软件接口,而这些不同对用户来讲是透明的。在内核中,和字符驱动程序相比,块驱动程序具有完全不同的接口。
查看驱动模块中打印信息应该使用什么命令?如何查看内核中已有的字符设备的信息?如何查看正在使用的有哪些中断号?
查看驱动模块中打印信息的命令:dmesg
查看字符设备信息可以用lsmod 和modprobe,lsmod可以查看模块的依赖关系,modprobe在加载模块时会加载其他依赖的模块。
显示当前使用的中断号cat /proc/interrupt
Linux中引入模块机制有什么好处?
首先,模块是预先注册自己以便服务于将来的某个请求,然后他的初始化函数就立即结束。换句话说,模块初始化函数的任务就是为以后调用函数预先作准备。
好处:
应用程序在退出时,可以不管资源的释放或者其他的清除工作,但是模块的退出函数却必须仔细此撤销初始化函数所作的一切。
该机制有助于缩短模块的开发周期。即:注册和卸载都很灵活方便。
MMU的作用有( )?
[A] 内存保护
[B] 地址转换
[C] 加快存取速度
[D] 安全保密
[E] 内存分配
答案 : AB
以下属于DMA特点的有( )
[A]占用CPU
[B]占用总线
[C]不占用CPU
[D]不占用总线
答案: BC
FIQ的什么特点使得它处理的速度比IRQ快?
1)FIQ优先级比IRQ高,不会被中断
2)FIQ有自己的专属寄存器:r8~r12,不用对通用寄存器入栈保护,可以加快速度
3)FIQ位于异常向量表的末尾0x1c,故无需跳转,可以在这里直接放置异常处理函数
全局变量、局部变量、静态全局变量、静态局部变量的区别和引用方式?
初始化的全局变量在.data段,可以外部文本加extern引用;
未初始化的全局变量在.bss段,可以外部文本加extern引用;
静态全局变量区别是不能在外部文件引用;
局部变量在运行时,栈区分配空间;
静态局部变量在静态区分配空间,函数调用后内存不释放;
内存的分配方式有哪三种,请简单介绍一下。
内存分配有三种:静态存储区、堆区和栈区。他们的功能不同,他们使用方式也就不同。
静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。
栈区:在执行函数时,函数(包括main函数)内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。(任何变量都处于站区,例如int a[] = {1, 2},变量a处于栈区。数组的内容也存在于栈区。)
堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。 但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,并立即将指针置位NULL,防止产生野指针。
IRQ和FIQ有什么区别?
FIQ和IRQ是两种不同类型的中断,ARM为了支持这两种不同的中断,提供了对应的叫做FIQ和IRQ处理器模式(ARM有7种处理模式)。
1、FIQ比IRQ快;2、FIQ比IRQ有更高优先级;3、FIQ的入口地址是0x1c,IRQ的入口地址是0x18。
驱动里面为什么要有并发、互斥的控制?如何实现?讲个例子?
并发(concurrency)指的是多个执行单元同时、并行被执行,而并发的执行单元对 共 享资源(硬件资源和软件上的全局变量、静态变量等)的访问则很容易导致竞态(race conditions) 。 解决竞态问题的途径是保证对共享资源的互斥访问, 所谓互斥访问就是指一个执行单 元 在访问共享资源的时候,其他的执行单元都被禁止访问。 访问共享资源的代码区域被称为临界区, 临界区需要以某种互斥机 制加以保护, 中断屏蔽, 原子操作,自旋锁,和信号量都是 linux 设备驱动中可采用的互斥途径。
什么是GPIO?
general purpose input/output
GPIO是相对于芯片本身而言的,如某个管脚是芯片的GPIO脚,则该脚可作为输入或输出高或低电平使用,当然某个脚具有复用的功能,即可做GPIO也可做其他用途。 也就是说你可以把这些引脚拿来用作任何一般用途的输入输出,例如用一根引脚连到led的一极来控制它的亮灭,也可以用一根(一些)引脚连到一个传感器上以获得该传感器的状态,这给cpu提供了一个方便的控制周边设备的途经。如果没有足够多的gpio管脚,在控制一些外围设备时就会力有不逮,这时可采取的方案是使用CPLD来帮助管理。
字符型驱动设备怎么创建设备文件?
手动创建:mknod /dev/led c 250 0 其中dev/led 为设备节点 c 代表字符设备 250代表主设备号 0代表次设备号
还有UDEV/MDEV自动创建设备文件的方式,UDEV/MDEV是运行在用户态的程序,可以动态管理设备文件,包括创建和删除设备文件,运行在用户态意味着系统要运行之后。在 /etc/init.d/rcS 脚本文件中会执行mdev -s 自动创建设备节点。
写一个中断服务需要注意哪些?如果中断产生之后要做比较多的事情你是怎么做的?
中断处理例程应该尽量短,把能放在后半段(tasklet,等待队列等)的任务尽量放在后半段。
写一个中断服务程序要注意快进快出,在中断服务程序里面尽量快速采集信息,包括硬件信息,然后退出中断,要做其它事情可以使用工作队列或者tasklet方式。也就是中断上半部和下半部。
第二:中断服务程序中不能有阻塞操作。应为中断期间是完全占用CPU的(即不存在内核调度),中断被阻塞住,其他进程将无法操作;
第三:中断服务程序注意返回值,要用操作系统定义的宏做为返回值,而不是自己定义的OK,FAIL之类的。
自旋锁和信号量在互斥使用时需要注意哪些?在中断服务程序里面的互斥是使用自旋锁还是信号量?还是两者都能用?为什么?
使用自旋锁的进程不能睡眠,使用信号量的进程可以睡眠。
中断服务例程中的互斥使用的是自旋锁,原因是在中断处理例程中,硬中断是关闭的;但是要注意这样会丢失可能到来的中断。