北京航天泰睿科技有限公司
嵌入式linux笔试题目
一、 简答题:
1. 请写出实现后面几个功能的Linux命令:显示文件,拷贝,删除
Ls ls -la: -l查看文件所有的信息,-a查看所有的文件,包括隐藏的文件。
Cp /mnt/a.c /opt/
Rm /mnt/a.c
2. do„„while和while„„do有什么区别?
do„„while至少执行一次循环体,while„„do先判断循环条件再执行循环体。
3. Linux系统下.ko文件是什么文件?.so文件是什么文件?
.so 文件是动态链接库文件,相当于 win下的 .dll 文件。
.ko 是内核模块文件,是内核加载的某个模块,一般是驱动程序。
4. 如何使用vi进行块拷贝、粘贴、删除的操作
yy:复制鼠标当前所在行
dd:删除鼠标当前所在行
nyy/dd:复制/删除鼠标所在行开始的n行
p:粘贴复制内容到鼠标所在行
G:移动到文件尾(大写)
u:取消前一个动作(大写)
:q :退出
:w :保存
:wq :保存退出
:q! :强行退出
:w 文件名:另存为 如::w hello
:set nu :显示行号
:set nonu:取消行号
5. 在Linux系统中,用来存放系统所需要的配置文件和子目录的目录是。
/etc :该目录下存放各种配置文件。对于PC上的linux系统,/etc目录下的目录,文件非常多。
6. 如何使用gcc得到宏展开的中间代码
Gcc -E *.i *.c
-c:编译成把源文件目标代码,不做连接的动作。
-s:把源文件编译成汇编代码,不做汇编和连接的动作。
-E:只把源文件进行预处理之后的结果输出来。不做编译,汇编,连接的动作。
7. 如何使用gdb调试多进程
答:最常用的是attach方法,
首先写程序时在子进程中调用sleep函数休眠30-60秒,将程序编译成可执行文件,后台运行可执行文件,ps -fu root查看进程号,gdb,attach进程号,再使用stop暂停子进程,设置一些断点和一些watch,break设置断点,list命令察看源代码,step单步运行,next运行下一步,continue继续运行,print打印变量信息。
8. 用户进程间通信主要哪几种方式
管道、信号、消息队列、共享内存、信号量、套接字。
线程同步的方法主要有:互斥锁(mutex)和信号量
9. 解释命令ls -amore具体含义。
A:输出所有文件,包括隐藏文件,m:横向输出文件名,并且中间以,号分开,r:列出子目录下的文件,o与-l相似,输出文件的详细信息,不输出组信息。
10. LINUX中的管道指什么,重定向又指什么
管道是linux中很重要的一种通信方式,它是把一个程序的输出直接连接到另一个程序的输入。
11. 请写出下列代码的输出内容
#include “stdio.h”
main()
{
int a,b,c,d;
a=10;
b=a++;
c=++a;
d=10*a++;
printf("b,c,d:%d,%d,%d",b,c,d);
return 0;}
A:13 b:10 c:12 d:120
B,c,d:10,12,120
12. 编写一个函数int charnum(char fn[10]),该函数以只读方式打开文件fn,,通过统计,返回文件中字符的个数,请使用while循环实现计数功能。 请勿修改主函数main和其他函数中的任何内容,仅在函数charnum的花括号中填写若干语句。
文件kt7_2.cpp的内容如下:
#include
#include
#include
int charnum(char fn[10]);
voidmain()
{
intnum;
num=charnum("abc.txt");
cout
}
Int charnum(char fn[10])
{
fstream file;
file.open(fn,ios::in);
if(!file)
{cout
abort();}
char ch;
int i=0;
while(!file.eof())
{file.get(ch);
i++;}
file.close();
return i-1;
}
二、编程题
13. 如果有一个简单的Test项目目录如下:
# tree Test
Test
|-- common.h
|-- main.cpp
|-- test.cpp
`-- test.h
1)使用wildcard、patsubst函数编写一个C++项目的Makefile文件
2)使用automake、autoconfig编写一个支持configure选项的configure.in脚本
14. 编写一个hello world程序,要求以创建进程的方式打印Hello World!
#include
#include
#include
#include
Main()
{
Pid_t result;
Result = fork();
If(result == -1)
{perror(fork);exit();}
Else if (result == 0) {printf(“hello wold”);}
if (result == 0) {printf(“hello wold”);}
}
15. 打开一个文件,并读取从第100字节开始的50字节数据。
#include
#include
#include
#define MAX_LEN 4096
int main(int argc, char **argv)
{
int fd, i;
char buf[MAX_LEN];
for(i=0; i
{
buf[i]=0;
}
if(argc!=2)
{
printf("Invalid argument!\n");
exit(1);
}
if((fd=open((char*)argv[1], O_RDONLY))==-1)
{
perror("Open failed");
exit(1);
}
lseek(fd, 100, SEEK_SET);
if(read(fd, buf, 50)!=50)
{
perror("Read error");
exit(1);
}
printf("%s\n", buf);
return 0; }
16. 编写一对socket程序,要求类似于network echo procotol。
Client每隔1秒把自己的IP地址轮流循环发送给一个Server.
Server接到IP后,在屏幕上打印对方IP;然后把自己的IP发送回去。 Client收到回复后,在屏幕上打印对方IP。
程序一直运行,直到用户退出。各自分类统计接收到的各IP的数据包的个数。
注意:Client可以向多个Server发送请求,Server也可以接收多个Client请求。
17.请描述Linux下程序开发到执行的工作流程(结合自己的项目经历)。
开发arm-linux程序至少需要三种系统:
Windows系统。
主要用来文件传送和一些简单的文本文件编辑。这个系统其实并非必需,只是因为目前PC机上最流行的系统仍然是Windows系统,我们的很多关于PC的文件和数据的操作习惯都是在Windows系统上养成的,已经对其形成了严重的依赖,所以Windows系统扮演着的“辅助开发系统”的角色。 PC-Linux系统。
在此系统上安装arm-Linux交叉编译器后,就可以对代码文本文件进行编译,生成可在
arm-Linux系统中运行可执行程序。此系统被称为“Linux宿主机”,我们对Linux程序的开发工作(包括代码编写、调试和编译生成可执行文件)基本上就是在此系统上进行的。
Arm-Linux系统。
Arm-Linux程序运行的平台。此系统的硬件载体是一块小型的嵌入式arm板,我们在Linux宿主机上开发好程序并编译生成arm-linux可执行程序后,将可执行程序文件传送到嵌入式arm板中,然后就可以在arm板上直接运行此程序了。
18. 结合自己的学习或工作感受简述Linux与Windows编程的区别,嵌入式Linux与Windows的嵌入式OS(如XPE、WinCE)的区别。
1. 尝试论述中断产生,到中断处理结束的详细过程7’
设备控制器或其他系统产生一个中断,处理器结束当前指令的执行,处理器发送中断应答信号,处理器将PSW和PC压入堆栈,根据中断,处理器加载新的PC值,保存剩余的处理状态,处理中断,恢复处理状态信息,恢复PC和PSW
2. 试阐述何时可能会导致进程切换,以及进程切换的详细过程8'
1、时钟中断,进程允许执行的时间片结束导致进程切换
2、IO中断
3、内存失效
4、发生错误或异常,进程被转换到退出状态
5、系统调用,比如打开文件,通常导致进程为阻塞状态
1.解释命令ls -a | more具体含义.
ls -a 是将当前目录下的文件名输出到终端,而加入后面的| more 是将输出结果分页显示
2.LINUX中的管道指什么重定向又指什么
3.GCC -g -o test.elf test.c的具体含义
将test.c 文件编译输出为test.elf 带上调试信息,可以用GDB调试用
4.浅述GCC编译器在编译时都有哪几个过程
要经历四个相互关联的步骤:预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。 预处理(Preprocessing):命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。 编译(Compilation):接着调用cc进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。 汇编(Assembly):汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.s为后缀的汇编语言源代码文件和汇编.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。 连接(Linking):当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当位置,同时,该程序所调用到的库函数也从各自所在的档案库中连到合适的地方。
6.说明uclinux 和linux的区别
uclinux不具有的功能: 1). 没有存储管理单元 2). 不能运行时增加进程栈 3). 不支持分页 4). 可执行程序不是elf, 而是flat 5). 不能用fork, 而是用vfork 6). RAMDISK 7 解释下面一组GDB命令的含义.
break 94 设置断定,让程序在执行到第94行之前停止 run 运行准备调试的程序 info line 121 查看第121行设置的断点的信息
8.什么是链接脚本,其作用是什么 请编写一个简单的链接脚本
链接脚本主要用于规定如何把输入文件内的section放入输出文件内, 并控制输出文件内各部分在程序地址空间内的布局.
实例:以下脚本将输出文件的text section定位在0×10000, data section定位在0×8000000: SECTIONS { . = 0×10000; .text : { *(.text) } . = 0×8000000; .data : { *(.data) } .bss : { *(.bss) } } 解释一下上述的例子: . = 0×10000 : 把定位器符号置为0×10000 (若不指定, 则该符号的初始值为0). .text : { *(.text) } : 将所有(*符号代表任意输入文件)输入文件的.text section合并成一个.text section, 该section的地址由定位器符号的值指定, 即0×10000. . = 0×8000000 :把定位器符号置为0×8000000 .data : { *(.data) } : 将所有输入文件的.data section合并成一个.data section, 该section的地址被置为0×8000000. .bss : { *(.bss) } : 将所有输入文件的.bss section合并成一个.bss section,该section的地址被置为0×8000000+.data section的大小. 连接器每读完一个section描述后, 将定位器符号的值*增加*该section的大小. 注意: 此处没有考虑对齐约束.
9.编写一个SHELL脚本程序,将当前目录及其子目录中所有后缀为.O类型文件的文件名输出到用户指定的文件中.
ls -a | *.o >result.txt
10.请写出5个LINUX基本系统调用的函数名称. 包括与设备文件的交互和与普通文件的交互的系统调用(open, close, ioctl, create, unlink, . . . );与进程相关的系统调用又包括进程控制系统调用(fork, exit, getpid, . . . ),
11.描述LINUX中字符设备驱动的基本编写框架. 根据struct file_operations 的数据结构,填充里面的如:open,write,close,ioctl等函数并进行模块的初始化和退出
12.编写一个hello world程序,要求以创建进程的方式打印hello world.编写hello.c文件如下
#include ""stdio.h "
int main()
{
fork();
printf("hello world!/n");
exit(0);
} 编译hello.c生成hello可执行文件在shell中执行#fork hello 便可以看到打印结果
13.浅谈bootloader,kelnel,filesystem三者之间的关系.
嵌入式是linux启动过程如下。 bootloader->kernel->filesystem->application 先是bootloader,它是linux-kernel移植的基石,Bootloader是在系统启动之后、Kernel运行之前所执行的第一段代码,其任务是为调用Kernel准备必要的软硬件环境。完成bootlaoder的移植后,就是kernel的移植。主要包括添加特定模块的驱动,针对具体要求对内核进行配置。这里有两点要注意:一是有些参数要与所用的bootloader向对应,如nand的分区参数。二是bootlaoder对特定模块的驱动在进入kernel后便会有kernel接管,并有kernel重新驱动文件系统主要是建立根文件和一些系统功能的实现,如bash。用busybox很容易搞定。
3. Linux系统下.ko文件是什么文件?.so文件是什么文件?
Linux下面文件名不代表什么。但是从常识上讲,.ko代码是驱动编译成的格式, .so文件一般是动态库文件
4. 二维数组AA [ 3 ][ 7 ]的另外一种表示方法:
*(AA[3]+7) *(*(AA+1)+7)
5. 请写出下列代码的输出内容
#include “stdio.h”
main()
{
int a,b,c,d;
a=10;
b=a++;
c=++a;
d=10*a++;
printf("b,c,d:%d,%d,%d",b,c,d);
return 0;
}
输出结果为:b, c, d: 10, 12, 120
嵌入式面试题
一、ANSI C/C++部分
简答题
1、 如何在C中为一个数组分配空间?
2、 如何初始化一个指针数组?
3、 s[10]的另外一种表达方式是什么?
4、 对(-1.2345)取整是多少?
5、 如何让局部变量具有全局变量的生命期?
6、 C中的常量字符串应在何时定义?
7、 如何在两个.C文件中引用对方的变量?
8、 a+++++b所表示的是什么意思?有什么问题?
问答题
1、下面x,y,*p的值是多少,有什么问题?
int x,y,z = 2;
int *p = &z; x = sizeof(*p); y = x/*p;
2、 一般使用malloc是,需要进行强制类型转换,如:
char *s;s = (char *)malloc(21);
下面中???该如何填写,才可以正确执行强制类型转换?
int (* monthp)[31]; monthp = (???)malloc(31);
3、 指针和数组的区别是什么?用一个简单的声明把它区分开。
指针和数组的声明在什么情况下是相同的?
4、 C语言的左值(lalue)和右值(rvalue)的含义是什么?
5、 说明C语言中术语“声明“ ”定义“ ”原型“ 的含义?
6、 编写一个函数,输入一个整形数,可以选择按照8/10/16进制输出字符串;
7 下面是一个16*16的黑白图标:
static unsigned short stopwatch[] = { 16个数 };
如何修改声明,可以使之在源代码中形象的表现出图像的摸样?
分析题
本题假设下面代码中的变量都合法,调用外部的函数都正确,回答几个问题:
这些代码意图要干什么? 是否有问题? 如果有问题,该如何修改,或者如何避免类是错误的发生? 如果没有问题,如果有输出,输出时什么? 1./* x =2 ,y = 3,z=? */ if(x == 0) if(y == 0) z = -1: else z = x+y;
int is_gb2312_char(char c1,char c2) { }
if (c1>=0xal &&c2>=0xal) return 1; else return 0; 二、POSIX方面的知识
简答题 。下面的题目必须全部答对才给分;
1、 在UNIX环境中,编译流程是什么?
2、 一般UNIX的程序有多少段,举一个实际的例子说明。
3、 系统调用和库函数调用有什么区别。
在linux2.4.xx上的glibc和newlib(一种嵌入式C库)的系统调用有什么不同?
4、 列出你所知道的2个内存跟踪库
设计一个内存跟踪方案,为什么选择这个方案
综合编程题
1、 有一个8MB的文件,编写一个copy程序,拷贝这个文件,并计算所需要的时间,指出是哪些代码或函数造成速度瓶颈。
提示:如果只是用read/write调用,不是一个好的实现。
三、编译器与调试器
1、 如何使用gcc得到宏展开的中间代码
2、 如何通过gcc在命令行中传入宏定义
3、 在哪一级优化的情况下,内联函数才真正的内联到代码中
4、 gdb的watch命令如何使用,有何缺点
5、 gdb中使用什么命令可以显示调用的栈帧,如何查看某个栈帧上的局部变量
6、 如何使用gdb调试多线程
四、 Makefile
如果有一个简单的Test项目目录如下:
#tree test
test
|-common.h
|-main.cpp
|-test.cpp
|-test.h
使用wildcard、patsubst函数编写一个C++项目的Makefile文件