嵌入式linux面试题解析——Linux应用编程部分

本文详细解析了TCP与UDP的区别、流量控制与拥塞控制的概念、多线程同步机制、进程间通信的各种方式及其优缺点,还介绍了epoll与select的区别、epoll的两种触发模式、进程组成的目的等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




1、TCP与UDP的区别

    TCP:是面向连接的流传输控制协议,具有高可靠性,确保传输数据的正确性,有验证重发机制,不会出现丢失或乱序。

    UDP:是无连接的数据报服务,不对数据报进行检查与修改,无须等待对方的应答,会出现分组丢失、重复、乱序,但具有较好的实时性,UDP段结构比TCP的段结构简单,因此网络开销也小。

 

2、流量控制和拥塞控制

    拥塞控制
    网络拥塞现象是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信业务陷入停顿,即出现死锁现象。拥塞控制是处理网络拥塞现象的一种机制。
    流量控制
    数据的传送与接收过程当中很可能出现收方来不及接收的情况,这时就需要对发方进行控制,以免数据丢失。

 

3、多线程如何同步

    Linux系统中多线程同步有最常用的是:互斥锁、条件变量和信号量。

 

4进程间通讯的方式优缺点

A、管道( pipe )

管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
B、有名管道 (named pipe)

有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
C、信号量( semophore )

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

消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
E、信号 ( sinal )

信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
F、共享内存( shared memory

共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是 针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。

G、套接字( socket )

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

优缺点:

    A、无名管道简单方便但局限于单向通信的工作方式并且只能在亲缘进程之间实现管道的共享有名管道虽然可以提供给任意关系的进程使用但是由于其长期存在于系统之中,使用不当容易出错。

    B、消息队列可以不再局限于父子进程而允许任意进程通过共享消息队列来实现进程间通信并由系统调用函数来实现消息发送和接收之间的同步从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题使用方便,但是信息的复制需要额外消耗 CPU的时间不适宜于信息量大或操作频繁的场合。

    C、共享内存针对消息缓冲的缺点改而利用内存缓冲区直接交换信息,无须复制,快捷、信息量大是其优点。但是共享内存的通信方式是通过将共享的内存缓冲区直接附加到进程的虚拟地址空间中来实现的因此,进程之间的读写操作的同步问题操作系统无法实现必须由各进程利用其他同步工具解决。另外,由于内存实体存在于计算机系统中所以只能由处于同一个计算机系统中的诸进程共享,不能网络通信。

 

5、tcp连接建立的时候3次握手,断开连接的4次握手的具体过程

    建立连接采用的3次握手协议,具体是指:
    第一次握手是客户端connect连接到server,server accept client的请求之后,向client端发送一个消息,是第二次握手,第3次握手就是client向server发送的,就是对第二次握手消息的确认。之后client和 server就开始通讯了。
    断开连接的4次握手,具体如下:
    断开连接的一端发送close请求是第一次握手,另外一端接收到断开连接的请求之后需要对close进行确认,发送一个消息,这是第二次握手,发送了确认 消息之后还要向对端发送close消息,要关闭对对端的连接,这是第3次握手,而在最初发送断开连接的一端接收到消息之后,进入到一个很重要的状态 time_wait状态,最后一次握手是最初发送断开连接的一端接收到消息之后对消息的确认。

 

6、epoll与select的区别

    select在一个进程中打开的最大fd是有限制的,由FD_SETSIZE设置,默认值是2048。不过 epoll则没有这个限制,它所支持的fd上限是最大可以打开文件的数目,这个数字一般远大于2048,一般来说内存越大,fd上限越大,1G内存都能达到大约10w左右。
    select的轮询机制是系统会去查找每个fd是否数据已准备好,当fd很多的时候,效率当然就直线下降了,epoll采用基于事件的通知方式,一旦某个 fd数据就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,而不需要不断的去轮询查找就绪的描述符,这就是epoll高效最本质的原因。
    无论是select还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的,而select则做了不必要的拷贝

 

7、epoll中et和lt的区别与实现原理

    LT:水平触发,效率会低于ET触发,尤其在大并发,大流量的情况下。但是LT对代码编写要求比较低,不容易出现问题。LT模式服务编写上的表现是:只要有数据没有被获取,内核就不断通知你,因此不用担心事件丢失的情况。
    ET:边缘触发,效率非常高,在并发,大流量的情况下,会比LT少很多epoll的系统调用,因此效率高。但是对编程要求高,需要细致的处理每个请求,否则容易发生丢失事件的情况。

 

8、UNIX系统中进程由三部分组成:进程控制块,正文段和数据段。这意味着一个程序的正文与数据可以是分开的,这种分开的目的是为了?ABC

  A.可共享正文

  B.可共享数据

  C.可重入

  D.方便编程

 

9、什么是驱动模块?

    答:驱动模块在大多数场合称为"主程序",它接收测试数据并将这些数据传递到被测试模块.单元测试一个函数单元时,被测单元本身是不能独立运行的,需要为其传送数据,为此写驱动。

  驱动模块主要完成以下事情:

    A、接受测试输入;

    B、对输入进行判断;

    C、将输入传给被测单元,驱动被测单元执行;

    D、接受被测单元执行结果,并对结果进行判断;

    E、将判断结果作为用例执行结果输出测试报告。

 

10、如果能够执行完美的黑盒测试,还需要进行白盒测试吗?(白盒与黑盒的区别)

    答案:任何工程产品(注意是任何工程产品)都可以使用以下两种方法之一进行测试。

    黑盒测试:已知产品的功能设计规格,可以进行测试证明每个实现了的功能是否符合要求。 白盒测试:已知产品的内部工作过程,可以通过测试证明每种内部操作是否符合设计规格要求,所有内部成分是否以经过检查。

软件的黑盒测试意味着测试要在软件的接口处进行。这种方法是把测试对象看做一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序 的需求规格说明书,检查程序的功能是否符合它的功能说明。因此黑盒测试又叫功能测试或数据驱动测试。黑盒测试主要是为了发现以下几类错误:

    A、是否有不正确或遗漏的功能?

    B、在接口上,输入是否能正确的接受?能否输出正确的结果?

    C、是否有数据结构错误或外部信息(例如数据文件)访问错误?

    D、性能上是否能够满足要求?

    E、是否有初始化或终止性错误?

    软件的白盒测试是对软件的过程性细节做细致的检查。这种方法是把测试对象看做一个打开的盒子,它允许测试人员利用程序内部的逻辑结构及有关信息,设计 或选择测试用例,对程序所有逻辑路径进行测试。通过在不同点检查程序状态,确定实际状态是否与预期的状态一致。因此白盒测试又称为结构测试或逻辑驱动测 试。白盒测试主要是想对程序模块进行如下检查:

    A、对程序模块的所有独立的执行路径至少测试一遍。

    B、对所有的逻辑判定,取"真"与取"假"的两种情况都能至少测一遍。

    C、在循环的边界和运行的界限内执行循环体。

    D、测试内部数据结构的有效性,等等。

    以上事实说明,软件测试有一个致命的缺陷,即测试的不完全、不彻底性。由于任何程序只能进行少量(相对于穷举的巨大数量而言)的有限的测试,在未发现错误时,不能说明程序中没有错误。

 

11、进程有三种状态:(   C )。
    A 、准备态、执行态和退出态           B 、精确态、模糊态和随机态
    C 、运行态、就绪态和等待态           D 、手工态、自动态和自由态

 

12、文件系统的主要功能是(  A  )。
    A、实现对文件的按名存取                    B、实现虚拟存储          
    C、 提高外存的读写速度                     D、用于保存系统文档

 

13、以下做法不利于嵌入式应用软件的移植的是 D 。
    A) 在软件设计上,采用层次化设计和模块化设计
    B) 在软件体系结构上,在操作系统和应用软件之间引入一个虚拟机层,把一些通用的、共性的操作系统API接口函数封装起来
    C) 将不可移植的部分局域化,集中在某几个特定的文件之中
    D) 在数据类型上,尽量直接使用C语言的数据类型

 

14、操作系统中同时存在着多个进程,它们(C )
    A、不能共享系统资源           B、不能调用同一段程序代码
    C、可以共享所有的系统资源        D、可以共享允许共享的系统资源

 

15、 B )不是进程和程序的区别。
    A. 程序是一组有序的静态指令,进程是一次程序的执行过程
    B. 程序只能在前台运行,而进程可以在前台或后台运行
    C. 程序可以长期保存,进程是暂时的
    D. 程序没有状态,而进程是有状态的

 

16、如果Boot Loader、内核、启动参数以及其他的系统映像四部分在固态存储设备上分别独立存放,则其存储结构的分配顺序应当是:_D____。                 
    A . 文件系统、内核、启动参数、Bootloader   
    B . 启动参数、Bootloader、内核、文件系统
    C . Bootloader、内核、启动参数、文件系统  
    D . Bootloader、启动参数、内核、文件系统  

 

17、Boot Loader 的stage2通常使用C语言实现,以完成复杂的功能,并增加可读性和可移植性,以下哪一步骤属于stage2的内容:__D____  
    A . 为加载 Boot Loader 的 stage2 准备 RAM 空间
    B . 设置好堆栈
    C . 硬件设备初始化
    D . 将 kernel 映像和根文件系统映像从 flash 上读到 RAM 空间中

<think>好的,我现在需要准备关于U-Boot内核移植的面试问题。首先,我应该回顾一下之前用户提供的技术要点总结,确保自己理解其中的核心步骤和关键点。 用户之前给出的回答分为U-Boot移植和Linux内核裁剪两部分,每个部分都有具体的步骤、命令示例以及常见问题处理。现在用户问的是关于uboot和kernel移植的面试回答,可能需要更综合性的概述,同时结合可能的面试问题。 首先,我需要确认U-Boot移植的主要流程。包括硬件适配、编译配置、启动调试和问题处理。硬件适配部分需要了解目标板的CPU架构、外设配置,比如时钟、DDR、串口等。编译配置涉及选择defconfig,使用menuconfig调整,交叉编译工具链的设置。启动流程的调试可能需要查看串口输出的阶段信息,比如SPL阶段、DRAM初始化等。常见问题如DDR参数错误、时钟配置错误和环境变量存储设置。 然后是内核移植,这部分可能包括配置系统的使用(如make menuconfig),裁剪策略,模块化处理,启动优化。裁剪策略需要了解如何移除不必要的驱动和功能,模块化处理将部分驱动编译为模块以减少内核体积。启动优化可能涉及压缩方式的选择、日志级别的调整和延迟初始化。 另外,用户之前的回答提到了关联技术要点,如U-Boot内核启动参数传递、镜像格式验证,以及系统完整性验证的方法,如启动时间测量、存储空间对比和稳定性测试。高频面试问题示例也需要注意,比如如何确定驱动是否可以裁剪,U-Boot移植时的链接错误处理,内核裁剪后网络问题的排查方法。 在思考过程中,需要注意面试回答的结构是否清晰,是否覆盖了移植的关键步骤、常见问题及解决方法,以及实际项目经验。可能需要举例说明在具体项目中如何操作,遇到的问题和解决方式,以及取得的成果,比如启动时间的优化,内核体积的减少等。 可能还需要考虑面试官会深入询问的技术细节,例如U-Boot启动流程,从SPL到加载内核的过程,或者内核配置中依赖关系的处理,如何确保裁剪后的内核不丢失必要功能。此外,交叉编译工具链的选择和配置也是一个重要点,需要说明如何正确设置环境变量,如CROSS_COMPILE。 需要确保回答中提到的命令和配置选项准确无误,例如在U-Boot编译时使用的make命令参数内核配置中的具体CONFIG选项。同时,要强调调试方法,比如通过串口日志定位问题,使用工具分析启动过程等。 在项目经验部分,需要具体化,比如提到在某项目中移植U-Boot到某个具体型号的处理器,解决了某个具体问题(如DDR初始化失败),或者裁剪内核后体积减少了多少,启动时间提升了多少。这些数据能增加回答的可信度。 另外,要注意高频问题的回答示例,如遇到未定义的引用错误时,如何检查工具链版本和链接脚本,或者内核网络问题需要逐层排查驱动和协议栈配置。这些问题需要提前准备,确保回答有条理,展示出系统的问题解决能力。 最后,确保整个回答结构清晰,分点明确,技术术语正确,同时用简洁的中文表达,避免冗长,突出重点。可能需要将内容分为U-Boot移植、内核移植、关联技术、常见问题及项目经验几个部分,每个部分用简短的说明和示例支持。</think>以下是对U-BootLinux内核移植的面试回答框架,包含技术要点和实战经验描述: --- ### **一、U-Boot移植核心要点** #### 1. **移植流程** - **硬件适配** - 确认处理器架构(如ARMv7、ARMv8),添加板级支持包(`board/<vendor>/<board>`目录) - 初始化关键硬件:DDR控制器、时钟树、串口调试终端、存储介质(eMMC/NAND) - 示例:为新板卡添加`board/freescale/myboard`,实现`board_init()`和`dram_init()`函数 - **编译配置** ```bash # 选择基础配置模板 make myboard_defconfig # 图形化配置(使能/禁用功能) make menuconfig # 编译生成u-boot.bin make CROSS_COMPILE=aarch64-linux-gnu- -j8 ``` - **启动调试** - 通过串口输出定位故障阶段: ```bash U-Boot SPL 2023.07-rc1 # SPL阶段正常 Trying to boot from MMC # 存储设备检测 DRAM: 1 GiB # DDR初始化成功 ``` #### 2. **高频问题处理** - **DDR初始化失败**:调整`dram_init()`中的时序参数(tRFC、CL值) - **环境变量丢失**:检查`CONFIG_ENV_OFFSET`是否正确设置偏移地址 - **镜像加载异常**:验证U-Boot支持的镜像格式(如`bootm`加载zImage,`booti`加载Image) --- ### **二、Linux内核移植核心要点** #### 1. **移植流程** - **基础配置** ```bash # 选择默认配置(如imx_v7_defconfig) make ARCH=arm imx_v7_defconfig # 图形化配置 make ARCH=arm menuconfig # 编译内核设备树 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage dtbs -j8 ``` - **驱动裁剪策略** - **必保留**:CPU调度、中断控制器、时钟源、串口驱动、存储驱动 - **可裁剪**: ```bash # 移除触摸屏驱动 CONFIG_INPUT_TOUCHSCREEN=n # 禁用USB子系统 CONFIG_USB_SUPPORT=n # 关闭调试符号(节省30%空间) CONFIG_DEBUG_INFO=n ``` #### 2. **启动优化技巧** - **压缩方式**:使用LZ4替换gzip(解压速度提升50%) - **静默启动**:添加内核参数`quiet loglevel=0` - **模块延迟加载**:将非关键驱动(如USB、声卡)编译为模块(`.ko`文件) --- ### **三、关联技术衔接** #### 1. **U-Boot内核交互** - **启动参数传递**: ```bash # 设置根文件系统位置 setenv bootargs 'root=/dev/mmcblk0p2 rw console=ttyS0,115200' # 加载内核设备树 fatload mmc 0:1 0x82000000 zImage fatload mmc 0:1 0x83000000 imx6q-board.dtb bootz 0x82000000 - 0x83000000 ``` #### 2. **系统验证方法** - **启动耗时分析**: ```bash # 内核启动时间戳(dmesg输出) [ 0.000000] Kernel command line: init=/init earlyprintk [ 1.235678] Freeing unused kernel memory: 1024K ``` - **最小系统验证**: 通过`init=/bin/sh`启动到最小shell环境,验证基础功能(挂载根文件系统、运行基础命令) --- ### **、高频面试问题示例** #### 1. **Q:U-Boot如何加载设备树(DTB)?** **A**:通过`fatload`等命令将DTB加载到内存,`bootz`命令格式为: ```bash bootz <kernel_addr> - <dtb_addr> ``` #### 2. **Q:内核启动卡在"Starting kernel..."怎么办?** **A**:按优先级检查: - 内核镜像格式是否正确(ARM32用zImage,ARM64用Image) - 设备树地址是否传递正确(通过`fdt addr`命令验证) - 控制台参数(`console=`)是否与硬件匹配 #### 3. **Q:如何验证裁剪后的内核是否完整?** **A**:通过三级测试: - Level 1:启动到控制台,执行`ls /proc/device-tree`确认设备解析 - Level 2:挂载根文件系统,运行基本命令(ifconfig、mount) - Level 3:压力测试(内存:`memtester`,存储:`dd`读写测试) --- ### **五、项目经验示例** **智能电表项目(基于i.MX6ULL)** 1. **U-Boot移植** - 解决eMMC驱动不兼容问题:修改`drivers/mmc/fsl_esdhc.c`的时钟分频算法 - 优化启动速度:SPL阶段跳过冗余设备扫描,启动时间从3.2秒缩短至1.8秒 2. **内核裁剪** - 从原生4.1.15内核(12MB)裁剪至2.3MB - 保留关键功能:硬件加密引擎驱动(`CONFIG_CRYPTO_DEV_FSL_CAAM`)、看门狗 3. **成果**:通过EMC电磁兼容测试,达到工业级-40℃~85℃运行要求 --- **回答建议**:根据目标岗位调整侧重点: - 嵌入式底层开发:强调硬件调试、启动优化经验 - 系统架构岗位:突出整体移植方法论和稳定性设计 - IoT领域:重点描述低功耗配置和无线驱动适配经验
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值