Linux内核如何装载和启动一个可执行程序
Linux内核如何装载和启动一个可执行程序
攥写人:杨光 学号:20135233
( *原创作品转载请注明出处*)
( 学习课程:《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-100
知识点总结:
***预处理:gcc –E –o hello.cpp hello.c -m32 (
负责把include的文件包含进来,宏替换)
***编 译:gcc -x cpp-output –S hello.s –o hello.cpp -m32(gcc –S调用ccl,编译成汇编代码)
***汇 编:gcc -x assembler –c hello.s –o hello.o; (gcc -c 调用as,得到二进制文件)
***链 接:gcc –o hello hello.o ;gcc -o (调用ld形成目标可执行文件)
***可执行文件格式的发展过程:
-> PE
A.out -> COFF
-> ELF
***ELF中的三种主要的目标文件
- 可重定位文件:保存代码和适当的数据,用来和其他object文件一起创建一个可执行文件或一个共享文件。主要是.o文件。
- 可执行文件:保存一个用来执行的程序,指出了exec(BA_OS)如何来创建程序进程映象,怎么把文件加载出来以及从哪里开始执行。
- 共享文件:保存着代码和数据用来被以下两个链接器链接。一是链接编译器,可以和其他的可重定位和共享文件创建其他的object文件;二是动态链接器,联合一个可执行文件和其他 共享文件来创建一个进程映象。主要是.so文件。
***静态链接的ELF可执行文件与进程的地址空间
Entry point address:入口地址一般为0x8048000开始
其原因是:32位x86的系统有4G的进程地址空间(前面的1G供内核用;之后的3G用户态可访问)当一个ELF可执行文件要加载到内存中时,先把代码段和数据段加载到当中。开始加载时,前面 的都是ELF格式的头部信息,大小不尽相同,根据头部大小可确定程序的实际入口,当启动一个刚加载过可执行文件的进程时,就可从这个位置开始执行。
一般静态链接会将所有的代码放在同一个代码段;动态链接的进程会有多个代码段。
实验要求:
-
理解编译链接的过程和ELF可执行文件格式,详细内容参考本周第一节;
-
编程使用exec*库函数加载一个可执行文件,动态链接分为可执行程序装载时动态链接和运行时动态链接,编程练习动态链接库的这两种使用方式,详细内容参考本周第二节;
-
使用gdb跟踪分析一个execve系统调用内核处理函数sys_execve ,验证您对Linux系统加载可执行程序所需处理过程的理解,详细内容参考本周第三节;推荐在实验楼Linux虚拟机环境下完成实验。
-
特别关注新的可执行程序是从哪里开始执行的?为什么execve系统调用返回后新的可执行程序能顺利执行?对于静态链接的可执行程序和动态链接的可执行程序execve系统调用返回时会有什么不同?
实验过程:
进入实验楼环境,使用rm menu -rf命令 删除原来的menu,clone新的menu
make rootfs命令,重新编译加载内核
使用exec命令
之后使用 -s -S冻结内核
开启gdb调试
设置断点,并进行跟踪