您的位置:首页 > 运维架构 > Linux

学习Linux(28)Linux系统与helloworld

2020-07-20 18:08 78 查看

裸机执行helloworld

第一步;进行源代码的编写,其中关键的点在于printf函数的实现,它需要依赖单片机的串口驱动程序。
第二步: 借助一些集成开发环境进行程序的编译。一键编译,无需学习编译链接相关知识。
第三步: 借助烧录工具烧录到具体芯片上。一键烧录,无需学习芯片的flash和各种各样启动方式。
第四步: 上电启动开发板,串口输出“Hello World”字符串。

Linux执行helloworld

GCC编译过程

Linux kernel 内核处理
https://blog.csdn.net/a363344923/article/details/45063137

gilbc 库处理

实体执行代码部分

总体上整个程序的编译执行过程,可以按图片从上到下的顺序,分为四大部分的内容:
第一部分,上面浅绿色外框部分为程序的编译。
第二部分,浅黄色外框部分为Linux内核提供的服务。
第三部分,橘色外框部分为glibc库提供的服务。
第四部分,浅灰色外框部分,为用户程序。
下面针对每个子步骤做进一步的讲解:
1.预处理hello.c,主要是处理程序里面的文件包含、处理宏定义、条件编译。
2.把c文件编译成为汇编文件(.s),其中进行了词法分析,语法分析,语义分析、生成中间代码、对代码进行优化等工作。
3.把汇编文件(.s)编译成可重定位文件(.o)。
4.把可重定位文件(.o)链接成为可执行文件,其中链接可分为静态链接和动态链接
静态链接:在编译阶段就会把所有用到的库打包到自己的可执行程序中,其优点是具有较好的兼容性,不依赖外部环境,但是生成的程序比较大。
动态链接:在应用程序运行时,链接器去加载外部的共享库,并完成共享库和动态编译程序之间的链接。不同的程序可以共用代码库,节省内存空间。
1.控制台输入./hello命令后,Shell会创建一个新的进程来执行该程序。fork()函数就是用于创建一个新的进程的。这里的进程可以先简单理解为程序的容器。
2.exeve()函数可以理解为向上一步新建的进程,填充一个可执行程序(hello)。
3.sys_execve()函数为linux系统调用,被exeve()函数调用,这里的系统调用可以理解为是操作系统系统开放给用户的最底层接口。
4.do_exeve()函数是sys_execve()函数的核心。
5.load_elf_binary()函数会去文件系统中读取hello程序到内存,然后判断它是否是动态链接的可执行程序,如果不是,则进一步判断是否是静态链接的文件。
10. ld-linux-xx.so是glibc库中的动态连接器。如果hello程序是动态链接程序,该动态链接器会去加载共享库,并完成共享库和程序的链接工作, 然后准备真正开始执行hell程序。
1.相反,如果hello程序是静态编译的程序,则无需再加载链接共享库,直接开始准备执行hello程序。
第10和11步分别执行之后.都会开始执行hello程序,_start是程序的真正入口,而该符号在glibc中。也就是说程序的真正入口在glibc。
2.__libc_start_main()也是glibc中的函数,用于在执行用户程序前进行一些初始化工作。
3.调用用户程序中的mian()函数,开始执行printf打印函数。
4.程序执行完了之后,调用glibc库中的_exit()函数,来结束当前进程。
整个过程粗略分析完了,对比裸机和linux系统下的“Hello World”,很明显可以看到操作系统为我们做了大量的工作, 甚至为了节省内存空间,还把程序的链接这种非常基础性的工作,交给了glibc中的动态连接器来完成。 避免静态链接的那种低效的开发方式,这是裸机开发难以做到的。

GCC 预处理C文件
/usr/lib/gcc/x86_64-linux-gnu/7/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu hello.c -o hello.i -mtune=generic -march=x86-64 -fstack-protector-strong -Wformat -Wformat-security

GCC 编译C文件
/usr/lib/gcc/x86_64-linux-gnu/7/cc1 -fpreprocessed hello.i -quiet -dumpbase hello.i -mtune=generic -march=x86-64 -auxbase-strip hello.s -version -o hello.s -fstack-protector-strong -Wformat -Wformat-security

GCC 编译汇编成可重定位文件
as -v --64 -o hello.o hello.s

GCC 链接可重定位文件
/usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/ccA7s8CX.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o hello /usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/…/lib -L/lib/x86_64-linux-gnu -L/lib/…/lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/…/lib -L/usr/lib/gcc/x86_64-linux-gnu/7/…/…/… hello.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/x86_64-linux-gnu/crtn.o

collect2 封装ld连接器

静态链接
/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/…/lib/:/lib/x86_64-linux-gnu/:/lib/…/lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/…/lib/:/usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS=’-o’ ‘hello_static’ ‘-v’ ‘-static’ ‘-mtune=generic’ ‘-march=x86-64’
/usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/ccLyWKu2.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lc --build-id -m elf_x86_64 --hash-style=gnu --as-needed -static -z relro -o hello_static /usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginT.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/…/lib -L/lib/x86_64-linux-gnu -L/lib/…/lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/…/lib -L/usr/lib/gcc/x86_64-linux-gnu/7/…/…/… hello.o --start-group -lgcc -lgcc_eh -lc --end-group /usr/lib/gcc/x86_64-linux-gnu/7/crtend.o /usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/x86_64-linux-gnu/crtn.o

编译出来的差异

Hankin
2020.07.15

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: