【无标题】

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

一、实验步骤

与上一课的实验步骤基本相同,在shell中依次运行以下命令,并编译运行

cd LinuxKernel

rm menu -rf

cd menu

mv test_exec.c test.c

make rootfs

在这里插入图片描述
在这里插入图片描述

重新回到shell窗口,cd LinuxKernel回退到LinuxKernel目录,使用下面的命令启动内核

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img 

-s -S

水平分割一个新的shell窗口出来,使用下面的命令启动gdb调试

gdb

(gdb) file linux-3.18.6/vmlinux

(gdb) target remote:1234

在这里插入图片描述

并在系统调用sys_execve的入口处设置断点

(gdb) b sys_execve

在QEMU窗口中输入exec,系统就会停在上面设置的断点处:

同理可以设置以下断点

b load_elf_binary

b start_thread

从而追踪内核代码。
在这里插入图片描述

在这里插入图片描述

二、理解Linux系统加载可执行程序所需处理过程

理论:理解编译链接的过程和ELF可执行文件格式
在这里插入图片描述

我们都知道,C语言的执行都必须经过预处理、编译、汇编、链接和执行等过程。这次实验我们就通过 GDB 来跟踪分析一个 execve 系统调用内核处理函数 sys_execve,深入理解 Linux 操作系统装载链接和运行可执行程序的过程。

还是以 hello_world.c 程序为例,搞清楚可执行程序是如何生成的:

#include <stdio.h>
int main()
{
    printf("hello, world!\n");
    return 0;
}

1.预处理,处理代码中的宏定义和 include 文件,并做语法检查

gcc -E hello_world.c -o hello_world.i

2.编译,生成汇编代码

gcc -S hello_world.i -o hello_world.s

3.汇编,生成 ELF 格式的目标代码

gcc -c hello_world.s -o hello_world.o

4.链接,生成可执行代码

gcc hello_world.o -o hello_world

5.执行程序

./hello_world hello, world!</span>

2、静态链接和动态链接

静态连接库就是把(lib)文件中用到的函数代码直接链接进目标程序,程序运行的时候不再需要其它的库文件;动态链接就是把调用的函数所在文件模块(DLL)和调用函数在文件中的位置等信息链接进目标程序,程序运行的时候再从DLL中寻找相应函数代码,因此需要相应DLL文件的支持.
静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值