天天看点

2018年第一次嵌入式底层面试记录

        面试某公司嵌入式底层,由于还在上班,所以是电话面试。原本以为会考很难的题目,但是问的都很基础。有些自己明明懂的也蒙圈了,所以有必要做个记录。

        1、自我介绍。

        答:-------------------

      2、请问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

3、为什么uboot要关掉cache?

    答: 根据cache的定位可以看出来,它是用来加快cpu从内存中取出指令的速度,但我们都知道,在设备上电之初,我们的内存初始化比较慢一拍,当cpu初始化了,但内存还没准备好之后,就对内存进行数据读,那么势必会造成了指令取址异常,系统就会挂了。所以,在u-boot的上电之初,就得关闭掉数据cache,指令的cache关闭与不关闭没有太大的关系。

    注:Dcache只能在MMU开启之后使用,因为没有MMU就没法完成虚实地址映射,也就不能索引Dcache了。

4、nandflash和norflash的区别,对norflash的操作方式的理解

    答:两种芯片的结构不同 NORflash之所以可以片内执行,就是因为他符合CPU去指令译码执行的要求。CPU送一个地址出来,NORflash就能给一个数据让CPU执行,中间不需要额外的处理操作。    

       NAND flash不一样是因为nandflash有地址,数据,命令共用IO口的问题,cpu把地址发出来之后,并不能直接得到数据,还需要控制线的操作才能完成。就是他没有专用的SRAM接口。

        嵌入式系统中代码的执行方式主要有3种:

        完全映射\按需分页\eXecute In Place (XIP)片上执行。

 参考:http://blog.csdn.net/amberman/article/details/8122300

http://blog.csdn.net/qq_30866297/article/details/72622107

5、uboot怎么传参给内核的

答:

     简单的讲,uboot利用函数指针及传参规范,它将

     R0: 0x0

     R1: 机器号

     R2: 参数地址

     三个参数传递给内核。

     其中,R2寄存器传递的是一个指针,这个指针指向一个TAG区域。

6、linux怎么进行内存管理

      早期计算机中,由于应用程序比较小,可以直接在物理内存中运行,但现在计算机里面程序那么多又那么大,所以就需要对内存进行管理。

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

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

     参考:https://www.linuxidc.com/Linux/2016-01/127538.htm

     参考:http://blog.csdn.net/u013616945/article/details/77435607

     参考:https://www.jianshu.com/p/52df413f9e74

7、说说进程和线程的区别

    答:  简单的来说,一个程序至少有一个进程,一个进程至少有一个线程。

       第一点、进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

       但这样带来的缺点就是,多线程程序只要有一个线程挂掉了,那么整个进程也就挂掉了,而进程则不会影响另外一个进程,它有自己的独立地址空间。

       第二点、线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。

8、进程间通信都有些什么?

答:

     1、无名管道通信

      内核维护一块内存,有读端和写端。只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

     2、有名管道通信

      内核维护一块内存,表现形式为一个有名字的文件。传输方式:半双工

     3、消息队列通信

     4、信号量通信

     5、信号     信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

     6、共享内存通信

     7、套接字通信

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

 参考:http://blog.csdn.net/violet_echo_0908/article/details/51201278

9、在应用层调用一个read,是怎么传到内核中去的,流程是啥。

答:

     应用程序通过系统调用进入内核,然后

 (这个回答的比较乱。。。)

10、ext4的文件系统单层目录可以创建多少文件?

答:

     按网上查资料来看:Ext3 目前只支持 32,000 个子目录,而 Ext4 本身支持无限数量的子目录

     https://www.jianshu.com/p/b28ed82a56a6

11、创建一个文件的时候,会创建一个怎么样的节点。

答:

     一个文件被创建后至少要占用一个inode和一个block

12、进程有几种状态

     一般来说,进程有三个状态,即就绪状态,运行状态,阻塞状态

     总结:fork一个进程之后,进程加入队列,处在就绪态,等待被调用,此时如果得到运行就进入运行态,这时如果遇到阻塞状态就进入等待态等待再条件满足后再次进入就绪态,如果运气不好,在运行态时直接被结束了,就进入了僵尸态,如果被信号给终止了,就进入停止态。

13、对内核各种锁的了解

 内核锁

 1、原子操作(atomic):

 2、自旋锁(spinlock/spinlock_irqsave):

 3、读写自旋锁(rwlock):

 4、顺序自旋锁(seqlock):

 5、RCU(读-拷贝-更新):

 6、信号量(semaphore):

 7、读写信号量:

 https://www.cnblogs.com/tolimit/p/4624070.html

 http://blog.csdn.net/FreeeLinux/article/details/54267446

 

继续阅读