20135202闫佳歆--week 7 Linux内核如何装载和启动一个可执行程序--实验及总结

week 7 实验:Linux内核如何装载和启动一个可执行程序

1.环境搭建:

rm menu -rf
git clone https://github.com/megnning/menu.git
cd menu
ls
mv test_exec.c test.c
vi test.c   // 可以看到增加了一个exec的程序,只比fork程序多了一个execlp
vi Makefile // 查看Makefile的更改,加入了hello
make rootfs

enter description here
执行exec后,出现了hello world,这其实是加载了一个新的程序hello。

2.使用gdb跟踪

qemu -kernel ../linux-3.18.6/arch/x86/boot/bzImage -initrd ../rootfs.img -s -S
gdb
file ../linux-3.18.6/vmlinux
target remote:1234

b sys_execve    //可以先停在sys_execve然后再设置其他断点
b load_elf_binary
b start_thread

enter description here

enter description here
以上两图为设置断点。
先设置sys_execve后,在menuOS里执行系统调用exec,会停在如图所示代码,找到第一个断点

enter description here
找到了第二个断点

enter description here
给新栈的栈底指针赋值

enter description here
找到了第三个断点start_thread

enter description here
查看附近的代码:给新栈的赋值。

执行到start_thread的时候有一个问题:
new ip到底是指向哪里的?
用po(print object)指令:

po new_ip
可以看到一个地址:0x80495ba

enter description here

readelf -h hello
找到hello这个可执行程序的入口地址。
这是一个静态编译的可执行文件。

enter description here

new ip是返回用户态的第一条指令的地址。

3.实验总结

1. execve()系统调用,实质是运行的sys_execve()函数。
2. sys_execve中有do_execve(),读取128个字节的文件头部。
3. 调用search_binary_handle()去搜索和匹配合适的可执行文件装载处理过程。
4. ELF被load_elf_binary()装载。
load_elf_binary函数中调用了start_thread函数,创建新进程的堆栈,有pt_regs栈底指针,更重要的是修改eip,即程序执行入口。
5. 函数返回至do_execve(),又返回至sys_execve()。
6. 新的程序开始执行,ELF可执行文件装载完成。

4.知识总结

请走博客 20135202闫佳歆-week7 可执行程序的装载-学习笔记

posted @ 2016-04-06 23:48  20135202闫佳歆  阅读(344)  评论(0编辑  收藏  举报