嵌入式Linux开发核心自测题(全系列精华浓缩)
这份自测题覆盖了从入门理论到实战操作的所有核心知识点。每题都对应一个必须掌握的内容。你可以用它反复自检,查漏补缺。建议先自答,再对照要点。
文章目录
-
- 嵌入式Linux开发核心自测题(全系列精华浓缩)
-
- 一、嵌入式系统基础与开发环境
- 二、Bootloader(U-Boot)
- 三、Linux内核基础
- [四、设备树(Device Tree)](#四、设备树(Device Tree))
- 五、内核配置与Kconfig
- [六、Tina-SDK 开发环境与内核编译](#六、Tina-SDK 开发环境与内核编译)
- 七、内核启动与调试
- 八、驱动添加实战(LCD触摸屏)
- 九、驱动添加实战(用户按键)
- 十、Git与内核代码追溯
- 十一、综合与进阶
- 补充必考题(共8题)
一、嵌入式系统基础与开发环境
1. 什么是交叉编译?为什么嵌入式开发要用交叉编译?
答:在PC(x86)上编译出ARM等目标平台能运行的程序。因为开发板资源有限,无法运行编译器。
2. 交叉编译工具链的前缀 arm-linux-gnueabihf- 中各个部分含义?
答 :arm 架构、linux 操作系统、gnueabihf C库及硬浮点ABI。
3. 本地编译与交叉编译的区别是什么?
答:本地编译:编译器和目标平台相同;交叉编译:编译器运行平台与目标平台不同。
4. 什么是 sysroot?作用是什么?
答:交叉编译时的假根目录,存放目标平台的头文件和库,避免错误使用主机文件。
5. make menuconfig 和 make kernel_menuconfig 在TinaSDK中有什么区别?
答:前者配置Tina系统的软件包;后者配置Linux内核(临时);永久配置内核模块应使用前者。
二、Bootloader(U-Boot)
6. U-Boot 的主要作用是什么?
答:初始化硬件、加载内核和设备树、提供命令行接口、支持烧录和调试。
7. U-Boot 中如何查看环境变量、修改并保存?
答 :printenv 查看;setenv 修改;saveenv 保存。
8. U-Boot 启动内核的常用命令是什么?
答 :bootz <内核地址> - <设备树地址>(zImage);bootm(uImage)。
9. 如何单独编译U-Boot而不重新编译整个系统?
答 :进入 lichee/brandy-2.0/u-boot-2018/,执行 make <板子>_defconfig;然后 make -jN。
10. bootargs 环境变量作用是什么?举例三个常用参数。
答 :传递给内核的命令行参数。例如 console=ttyS3,115200、root=/dev/mmcblk0p5、rootwait。
三、Linux内核基础
11. Linux内核官网 kernel.org 中的 mainline、stable、longterm 分别什么意思?
答:mainline:主线开发,最新功能;stable:稳定版,只修bug;longterm:长期支持版,维护数年。
12. 如何查看当前内核版本号?
答 :uname -r。
13. 内核源码目录中 arch/、drivers/、fs/ 分别作用?
答 :arch/ 体系结构相关;drivers/ 设备驱动;fs/ 文件系统。
14. 什么是内核模块?优点是什么?
答 :动态加载的.ko文件,无需重启内核就能加载/卸载驱动,减小内核体积。
15. 如何手动加载、卸载一个内核模块?
答 :insmod xx.ko、rmmod xx。推荐使用 modprobe(自动处理依赖)。
16. 加载模块失败,insmod 只返回 Operation not permitted,如何查看更多信息?
答 :使用 dmesg | tail 查看内核日志中的详细错误。
17. modinfo 命令作用?
答:查看模块信息(作者、许可证、参数、依赖)。
18. 如何查看当前已加载的模块?
答 :lsmod。
19. 内核编译命令 make -jN 中的 -j 参数含义?
答:并行编译的任务数,通常设为CPU核心数的两倍。
四、设备树(Device Tree)
20. 设备树的作用是什么?
答:描述硬件拓扑和资源,使同一内核适配不同板子。
21. .dts 和 .dtb 的区别?
答 :.dts 源文件(文本),.dtb 编译后的二进制文件,由内核或U-Boot使用。
22. 如何单独编译设备树?
答 :make dtbs(内核源码目录下)。
23. 设备树中 &pio 节点的作用是什么?
答:引用引脚控制器节点,用于配置引脚复用和电气属性。
24. gpios = <&pio PB 4 GPIO_ACTIVE_LOW>; 中每个参数含义?
答:引用pio控制器、bank PB、引脚4、低电平有效。
五、内核配置与Kconfig
25. menuconfig 中选项前的 <\*>、<M>、[ ] 分别代表什么?
答 :<*> 编译进内核;<M> 编译为模块;[ ] 排除。
26. 如何快速搜索某个配置项(如 printk)?
答 :在 menuconfig 中按 / 键输入关键词。
27. 某些选项是灰色的无法修改,怎么办?
答 :说明被其他选项依赖,按 ? 查看帮助,找到依赖项并先启用。
28. depends on 和 select 的区别?
答 :depends on 表示依赖条件;select 表示当前选项会强制启用另一个选项。
29. 在TinaSDK中,如何永久保存内核配置修改(非临时)?
答 :使用 make menuconfig 而不是 make kernel_menuconfig,通过Tina的Kernel modules菜单选择。
六、Tina-SDK 开发环境与内核编译
30. TinaSDK 中内核源码位置?如何快速跳转?
答 :lichee/linux-5.4;快捷命令 ckernel。
31. 板级设备树和配置文件路径在哪?如何快速跳转?
答 :device/config/chips/t113/configs/100ask/;快捷命令 ccconfigs。
32. 单独编译内核的命令是什么?
答 :mkernel(需先 source build/envsetup.sh 和 lunch)。
33. 编译内核后,如何打包生成烧录镜像?
答 :pack。
34. TinaSDK 最终镜像文件名及路径?
答 :out/t113-100ask/tina_t113-100ask_uart3.img。
七、内核启动与调试
35. 如何查看内核启动时传递的命令行参数?
答 :cat /proc/cmdline。
36. loglevel=8 内核参数作用?
答:将所有内核消息打印到控制台(最高日志级别)。
37. rootwait 内核参数干嘛用的?
答:无限等待根设备出现,常用于SD卡或USB设备启动。
38. 如何修改内核打印等级(降低输出冗余)?
答 :修改 CONFIG_MESSAGE_LOGLEVEL_DEFAULT 为较小值(如4),或在内核命令行加 loglevel=4。
39. 启动后系统反复重启,没有登录提示,如何排查?
答 :检查串口输出,看是否 kernel panic;用 panic=0 参数阻止自动重启,读最后一条错误。
八、驱动添加实战(LCD触摸屏)
40. 为I2C触摸屏添加驱动的主要步骤是什么?
答:看原理图确定引脚和总线,修改设备树添加I2C节点和触摸子节点,配置内核模块,编译烧录测试。
41. 设备树中 ctp_int_port 和 ctp_wakeup 属性作用?
答:指定触摸屏的中断引脚和复位引脚,用于上报触摸事件和复位芯片。
42. 触摸驱动加载成功后,如何查看对应的输入设备节点?
答 :cat /proc/bus/input/devices,找到 Name 为触摸屏的设备,查看 Handlers。
43. 触摸屏不工作,如何初步测试I2C通信是否正常?
答 :使用 i2cdetect -y <bus> 扫描设备地址,确认设备是否应答。
九、驱动添加实战(用户按键)
44. gpio-keys 驱动的作用?设备树中如何描述一个按键?
答 :将GPIO按键抽象为输入设备。需在根节点下创建 gpio-keys 子节点,每个按键用单独节点,指定 gpios、linux,code、label 等。
45. linux,code = <114>; 中 114 代表什么?
答 :KEY_VOLUMEDOWN(键值定义在 include/uapi/linux/input-event-codes.h)。
46. 按键驱动加载后,如何测试按键上报数据?
答 :cat /dev/input/eventX(会有乱码),或 hexdump /dev/input/eventX 查看十六进制数据。
47. 为什么按键驱动手动 insmod 有效,但重启后消失?如何开机自动加载?
答 :因为模块未配置为自动加载。解决方法:在 /etc/init.d/rc.modules 中添加 insmod 命令。
十、Git与内核代码追溯
48. 如何在内核源码仓库中搜索包含某个关键词(如 imx6ull)的提交?
答 :git log --grep='imx6ull' --oneline。
49. 拿到一个commit id,如何查看它的完整修改内容?
答 :git log -p -1 <commit-id> 或 git show <commit-id>。
十一、综合与进阶
50. 在TinaSDK中,修改设备树后,是否需要单独编译设备树?如何生效?
答 :设备树不能单独编译,必须执行 make(或 mkernel)然后 pack,重新烧录整个镜像。
51. 如何判断一个内核驱动是编译进内核还是编译为模块?
答 :查看 .config 中对应选项:=y 内建,=m 模块,未定义 或 =n 排除。
52. make distclean 会删除哪些文件?
答 :删除所有编译产物、.config 以及编辑器备份文件。相当于回到原始源码状态。
53. 调试驱动时,频繁修改设备树,最快验证的方法是什么?
答 :在U-Boot中用 fdt set 临时修改内存中的设备树,然后 boot 启动测试(不烧录镜像)。
54. 如何查看开发板上所有的输入设备及其对应的event节点?
答 :cat /proc/bus/input/devices,然后找 Handlers= 字段。
55. 开发板上电后一直卡在 U-Boot 倒计时,即使按任意键也无法进入命令行?
答:可能是串口接收问题,检查串口线、波特率、流控;或 bootdelay=0,需断电重试。
补充必考题(共8题)
56. CISC 和 RISC 的主要区别是什么?嵌入式领域为什么普遍使用 RISC?
答:CISC指令复杂、变长,一条指令可完成多步操作;RISC指令精简、定长,采用加载/存储架构。RISC硬件简单、功耗低、面积小,适合嵌入式。
57. ARM Cortex-A、Cortex-R、Cortex-M 三大系列分别用于什么场景?
答:A系列应用处理器(跑Linux/Android);R系列实时处理器(汽车、硬盘控制器);M系列微控制器(单片机、RTOS)。
58. 开源软件许可证中,GPL 和 LGPL 有什么区别?商业闭源产品应优先选择哪种?
答:GPL具有"传染性",链接GPL库的代码也须开源;LGPL允许动态链接而不开源闭源应用程序。商业产品优先选择MIT、BSD、Apache或LGPL(动态链接)。
59. Autotools 构建系统的典型配置编译命令是什么?如何指定交叉编译工具链和安装路径?
答 :./configure --host=arm-linux-gnueabihf --prefix=/usr;make;make install DESTDIR=/path/to/rootfs。
60. CMake 交叉编译时,如何在 CMakeLists.txt 中指定交叉编译器?需要注意什么顺序?
答 :set(CMAKE_C_COMPILER "/path/to/arm-gcc") 必须放在 project(...) 之前。
61. 交叉编译时,为什么要设置 CFLAGS=-I<path> 和 LDFLAGS=-L<path>?
答 :告诉编译器和链接器去构建空间的目录中找头文件和库,而非主机系统的 /usr/include 和 /usr/lib。
62. 设备树中 pinctrl-0、pinctrl-1 和 pinctrl-names 属性的作用是什么?
答 :pinctrl-names 定义状态名(如 "default", "sleep");pinctrl-0/-1 分别对应各状态的引脚配置,用于运行时切换。
63. 如何查看当前系统中某个已加载内核模块的参数值(例如 usb-storage 的 delay_use)?
答 :cat /sys/module/usb_storage/parameters/delay_use(模块名中的短横线变下划线)。
学习建议:对着以上55个题目,逐条自问是否能清晰回答。若某个题目卡住,就回到对应博客章节再学习。反复三遍,你就能应对领导任何技术考核。祝你顺利!