Linux内核如何装载和启动一个可执行程序

作者:王鹤楼
原创作品转载请注明出处 《Linux内核分析》MOOC课程
http://mooc.study.163.com/course/USTC-1000029000

一、可执行文件的创建

预处理、,汇编、编译 和链接

//预处理:(.c -> .cpp)
gcc -E -o hello.cpp hello.c -m32
//汇编:(.cpp -> .s )
gcc -x cpp-output -S -o hello.s hello.cpp -m32
//编译:(.s -> .o 二进制目标代码)
gcc -x assembler -c hello.s -o hello.o -m32
//链接:(.o -> a.out)共享库
gcc -o hello hello.o -m32

二、 ELF文件分三种类型

1、目标文件(通常是.o);
2、可执行文件(我们的运行文件)
3、动态库(.so)

三、可执行文件一般分成4个部分

1、elf文件头 ,这个文件是对elf文件整体信息的描述,在32位系统下是56的字节,在64位系统下是64个字节。
2、elf文件头 ,这个文件是对elf文件整体信息的描述,在32位系统下是56的字节,在64位系统下是64个字节。
3、 elf的主题,对于可执行文件来说,最主要的就是数据段和代码段
4、 section表,对可执行文件来说,没有用,在链接的时候有用,是对代码段数据段在链接是的一种描述。

四、实验

进入到实验楼环境执行

cd LinuxKernel
rm -rf menu
git clone https://github.com/mengning/menu.git
cd menu
mv test_exec.c test.c
make rootfs
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s

另起一shell设置断点

//启动gdb
gdb
//加载符号表
file ../linux-3.18.6/vmlinux
//设置端口
target remote:1234
//设置断点
b sys_execve
b load_elf_binary
b start_thread
b do_execve
c

这里写图片描述

进入到start_thread后打印new_ip的地址为0x8048d0a
这里写图片描述

用readelf -h hello打印出可执行程序hello的头信息,入口址址为0x8048d0a
这里写图片描述

五、总结

程序加载通过do_execve()完成,而do_execve()执行过程:
1) 首查找被执行的文件,如果找到文件,则读取文件的前128个字节。 用于判断文件的格式。 开头的4个字节,称为魔数。通过对魔数的判断可以确定文件的格式和类型。
2) 读取128个字节的文件头部后,调用search_binary_handle去搜索和匹配合适的可执行文件装载处理过程。通过文件头部的魔数确定文件的格式,并调用相应的装载处理过程。比如ELF可执行文件的装载处理过程叫做load_elf_binary();a.out可执行文件的装载过程叫做load_aout_binary;而装载可执行脚本程序的处理过程叫做load_script()
3)当load_elf_binary()执行完毕,返回至do_execve()再返回至sys_execve()时, 上面的第5步已经把系统调用返回地址改成了被装载的ELF程序的入口地址了。所以当sys_execve()系统调用从内核态返回到用户态时,EIP寄存器直接跳转到ELF程序的入口地址,于是新的程序开始执行,ELF可执行文件装载完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值