一面自我介绍然后简历上写了用过gdb和git随口问了我几个gdb和git的用法。然后是提问Q1:Arm汇编中bl的意思A:抱歉,arm汇编我没深入研究过,我用的平台指令集是TI自研的,但我研究过X86的汇编我推测一下。B是跳转的意思,bl的意思可能是小于跳转等于X86汇编的jl,可也能是类似x86的long jump。这个题答案是小于跳转,没答出来但是面试官说还可以。Q2:static 修饰的C语言变量存放在哪里,有什么作用A:存放在data段,不会被重复初始化。Q3:C语言变量有几种储存方式A:存放在stack data heap bssQ4:变量未初始化值是多少A:stack是垃圾值,不确定,全局变量未初始化是0.Q5: 什么是野指针A:我认为是存放了一个不应该访问地址的指针,比如free之后的指针再次访问,访问了一个未进行初始化的指针,访问了一个函数返回的指向局部变量的指针。Q6:外设和处理器交互的方式A:中断,DMA,普遍嵌入式设备的外设会被映射到地址空间中,所以可以直接通过读写被映射的地址进行交互。Q7:使用gcc编译一个hello.c的程序使用什么指令A:gcc hello.c -o hello.out反问环节:Q:工作中会比较多的使用gdb吗?A:调试会用到,看你写了所以问你一下Q:还有有几轮面试A:一般就两轮,特别优秀的三轮。二面自我介绍然后:Q1:看你简历上写了使用fft进行信号处理,讲讲吧A:我们控制这边是用来获取对象的频率响应特性的,就是使用频率成分丰富的信号作为被控对象的输入然后获取被控对象的输出,对输入输出信号做fft分析。Q2:在线还是离线A:离线Q3 简历上写了解决了cache一致性维护讲讲这个A:实验室用的DSP是八核的一款DSP,测试读写的时候发现自读自写没有问题,但是0核写1核读读取不到正确的数据,查阅芯片手册发现可能是cache的原因,写没有写入下一级的内存,读没有无效化cache。去论坛看了一下相关的帖子,然后解决了这个问题。主要通过官方提供的两条指令cache_invalid cache_writeback。读的核需要无效化cache,写的核需要writeback写到下一级。Q4:你还写了解决了多核同步问题,怎么解决的A:我用的芯片没有像X86提供原子指令,转而提供了一种原子外设,官方叫做硬件信号量,访问这个外设的时候是原子的,我模拟实现了一把spinlock 访问临界区的时候上锁。Q5:了解linux吗A:了解,增加模仿linux写过一个简易版本的操作系统内核。Q6:我看你简历上没写啊,讲讲你这个内核吧,跑在什么平台上的,都实现了什么功能A:跑在i386平台,用qemu模拟器模拟的。可以实现内存管理、进程创建、Sytemcall、进程调度还有一个简易版本的内核调度Q7:从Boot开始吧,讲讲你的内核启动过程和你实现的功能。A:i386自导bios在启动之后会从0x7c80读取第一条指令执行,所以内核需要使用链接器来修改镜像的地址。启动后会跳转到镜像entry处的地址,这是一个初始化函数,首先会进行内存的初始化,探测剩余的内存大小,申请一块地址作为page directory,然后对剩余内存按照4kb进行分割,使用链表连接,实现内存池。需要时向内核申请。我的进程创建时模仿linux fork实现的,利用的是写时拷贝技术,只创建一个新的栈,拷贝父进程的page directory的映射,但是标记页表为只读不写,如果写会触发缺页中断,然后进行相应的拷贝。调度是就是在可以准备运行的进程中挑选一个可以准备运行的进程,简单的round-robin算法,后来加入了优先级调度,利用hash-map寻找优先级最高的进程。Q8:在内存初始化中,怎么探测剩余内存的。A:镜像在bss段的最后会创建的一个标记叫做end,可以探测一个cmos管知道总共的内存大小,可以间接知道剩余内存的大小。答案附在面经中 c++/嵌入式面经专栏-牛客网 https://www.nowcoder.com/creation/manager/columnDetail/MJNwoM