嵌入式面试知识点总结 -- ARM篇

一、交叉编译与移植

问题:

  • 问题一:简单介绍一下交叉编译与移植?

解答:

参看:S5PV210开发 – 交叉编译器
(1)下载安装交叉编译器
(2)增加/etc/profile环境变量

在最末尾添加:
export PATH=/usr/local/arm/arm-2009q3/bin/:$PATH
执行如下指令让环境变量生效:
#source /etc/profile
检验:
which arm-none-linux-gnueabi-gcc 查看所在位置
echo $PATH 查看环境变量

二、移植根文件系统

问题:

  • 问题一:简单介绍根文件系统移植?
  • -问题二:常用文件系统有哪几种?
    嵌入式系统中常用文件系统包括有 cramfs、 JFFS2、 NFS、 initrd、 yaffs2 以及squashfs。它们的特点如下:
    cramfs 和 JFFS2 具有好的空间特性,很适合嵌入式产品应用。
    cramfs 与 squashfs 为只读文件系统。
    squashfs 压缩率最高。
    JFFS2 为可读写文件系统。
    NFS 文件系统适用于开发初期的调试阶段。
    yaffs2 文件系统只用于 NAND Flash。
    initrd 采用 cramfs 文件系统,为只读。

解答:

参看:Hi3516A开发–根文件系统
(1)利用busybox制作根文件系统,编译和安装 busybox。
(2)创建并配置 etc、 lib、 dev 目录的必需文件。
完成以上两个步骤,一个完整的根文件系统就生成了。

A、etc 目录可参考系统/etc 下的文件。其中最主要的文件包括 inittab、 fstab、 init.d/rcS文件等,这些文件最好从 busybox 的 examples 目录下拷贝过来,根据需要自行修改。
B、dev 目录下的设备文件,可以直接从系统中拷贝过来或者使用 mknod 命令生成需要的设备文件。拷贝文件时请使用 cp –R file,例如:
在dev目录下创建两个设备文件
sudo mknod dev/console c 5 1
sudo mknod dev/null c 1 3
sudo chmod 666 dev/console
sudo chmod 666 dev/null
C、 lib 目录是存放应用程序所需要的库文件,请根据应用程序需要拷贝相应的库文件。

三、用户态和内核态的转换

问题:

  • 问题一:用户态和内核态的转换方式?

解答:

用户态切换到内核态的3种方式:
(1)系统调用
这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使 用操作系统提供的服务程序完成工作,比如前例中fork()实际上就是执行了一个创建新进程的系统调用。而系统调用的机制其核心还是使用了操作系统为用户 特别开放的一个中断来实现,例如Linux的int 80h中断。
(2)异常
当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。
(3) 外围设备的中断
当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会 暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到 内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。

这3种方式是系统在运行时由用户态转到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的。

四、linux内核态和用户态之间的通信方式

问题:

  • 问题一:linux内核态和用户态之间的通信方式?

解答:

内核态(Kernel Mode):在内核态,代码拥有完全的,不受任何限制的访问底层硬件的能力。可以执行任意的CPU指令,访问任意的内存地址。内核态通常情况下,都是为那些最底层的,由操作系统提供的,可信可靠的代码来运行的。内核态的代码崩溃将是灾难性的,它会影响到整个系统。
用户态(User Mode):在用户态,代码不具备直接访问硬件或者访问内存的能力,而必须借助操作系统提供的可靠的,底层的APIs来访问硬件或者内存。由于这种隔离带来的保护作用,用户态的代码崩溃(Crash),系统是可以恢复的。我们大多数的代码都是运行在用户态的。

syscall: 一般情况下,用户进程是不能访问内核的。它既不能访问内核所在的内存空间,也不能调用内核中的函数。Linux内核中设置了一组用于实现各种系统功能的子程序,用户可以通过调用他们访问linux内核的数据和函数,这些系统调用接口(SCI)称为系统调用;
procfs: 是一种特殊的伪文件系统 ,是Linux内核信息的抽象文件接口,大量内核中的信息以及可调参数都被作为常规文件映射到一个目录树中,这样我们就可以简单直接的通过echo或cat这样的文件操作命令对系统信息进行查取。
在这几个通信方式中,选择netlink,原因如下:

全双工:procfs是基于文件系统,用于内核向用户发送消息;syscall是用户访问内核。它们都是单工通信方式。netlink 是一种特殊的通信方式,用于在内核空间和用户空间传递消息,是一种双工通信方式。使用地址协议簇AF_NETLINK,使用头文件include/linux/netlink.h;
易于添加:为新特性添加system call、或者procfs是一件复杂的工作,它们会污染kernel(内核),破坏系统的稳定性,这是非常危险的。Netlink的添加,对内核的影响仅在于向netlink.h中添加一个固定的协议类型,然后内核模块和应用层的通信使用一套标准的API。

五、uboot启动过程

问题:

  • 问题一:简述uboot启动过程?

解答:

大多数bootloader都分为stage1和stage2两部分,u-boot也不例外。依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。
1、Stage1 start.S代码结构
u-boot的stage1代码通常放在start.S文件中,他用汇编语言写成,其主要代码部分如下:
(1)定义入口。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。
(2)设置异常向量(Exception Vector)。
(3)设置CPU的速度、时钟频率及终端控制寄存器。
(4)初始化内存控制器。
(5)将ROM中的程序复制到RAM中。
(6)初始化堆栈。
(7)转到RAM中执行,该工作可使用指令ldr pc来完成。
2、Stage2 C语言代码部分
lib_arm/board.c中的start arm boot是C语言开始的函数也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数只要完成如下操作:
(1)调用一系列的初始化函数。
(2)初始化Flash设备。
(3)初始化系统内存分配函数。
(4)如果目标系统拥有NAND设备,则初始化NAND设备。
(5)如果目标系统有显示设备,则初始化该类设备。
(6)初始化相关网络设备,填写IP、MAC地址等。
(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。

六、linux设备分类

问题:

  • 问题一:设备分类有哪几种?
    字符设备、块设备、网络设备。

七、内核/用户空间的数据交换方法

问题:

  • 问题一:内核/用户空间的数据交换方法?
    copy_to_user / copy_from_user

八、加载模块,创建设备节点

问题:

  • 问题一:加载模块,创建设备节点?
    加载模块:
    insmod dev_fifo.ko
    创建设备节点
    mknod /dev/dev_fifo.ko c 168 0
    其中/dev/dev_fifo.ko 为设备节点, c 代表字符设备 ,168代表主设备号 ,0代表次设备号
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

聚优致成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值