进阶技术:Linux Arm32是如何调用C Main的
前言:
Linux x64通过qemu的rdinit方式调用的C Main,实际上是通过load_elf_binary(加载和解析elf)和start_thread(设置Ip和sp),用缺页异常来调用。那么Arm32里面是如何调用C Main的呢?本篇看下。
概括:
Arm32也是通过load_elf_binary加载被 gcc-arm-linux-gnueabi编译的C Main Demo。同样是也是通过ret_from_fork调用kernel_Init来调用elf_load_binary来操纵elf文件的。这点可以看下堆栈:
* thread #1, stop reason = breakpoint 1.1
* frame #0: 0x802fbc0c vmlinux`load_elf_binary(bprm=0x811cd000) at binfmt_elf.c:824:1
frame #1: 0x8028eeb0 vmlinux`bprm_execve at exec.c:1735:12
frame #2: 0x8028ee38 vmlinux`bprm_execve at exec.c:1776:9
frame #3: 0x8028edf4 vmlinux`bprm_execve at exec.c:1845:11
frame #4: 0x8028ecd8 vmlinux`bprm_execve(bprm=0x811cd000, fd=-100, filename=0x81160000, flags=0) at exec.c:1807:12
frame #5: 0x8028f644 vmlinux`kernel_execve(kernel_filename=<unavailable>, argv=0x80c07714, envp=0x80c077a0) at exec.c:2006:11
frame #6: 0x8083d8d8 vmlinux`run_init_process(init_filename=<unavailable>) at main.c:1438:9 [artificial]
frame #7: 0x80847010 vmlinux`kernel_init(unused=<unavailable>) at main.c:1534:9
frame #8: 0x80100130 vmlinux`ret_from_fork at entry-common.S:146
同样x64和Arm32的用户态入口也是Glibc的_start函数。
那么不同点在哪儿呢?上说过x64设置IP和SP的是start_thread,而Arm32里面则是START_THREAD这个宏定义来设置IP和SP,实质上做的东西是一样的,但是代码不一样,他们都是通过返回到ret_from_fork,然后获取到被设置的regs变量,里面包含了被start_thread OR START_THREAD宏设置的IP和SP。
看下START_THREAD宏定义:
#define START_THREAD COMPAT_START_THREAD
#define COMPAT_START_THREAD(ex, regs, new_ip, new_sp) \
compat_start_thread(regs, new_ip, new_sp, ex->e_machine == EM_X86_64)
void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp, bool x32)
{
start_thread_common(regs, new_ip, new_sp,
x32 ? __USER_CS : __USER32_CS,
__USER_DS, __USER_DS);
}
static inline void start_thread_common(struct pt_regs *regs, unsigned long pc)
{
s32 previous_syscall = regs->syscallno;
memset(regs, 0, sizeof(*regs));
regs->syscallno = previous_syscall;
regs->pc = pc;
if (system_uses_irq_prio_masking())
regs->pmr_save = GIC_PRIO_IRQON;
}
最后的start_thread_common设置了PC也就上面的IP。Glibc库的入口_start函数。这一点也可以验证下:
arm-linux-gnueabi-gcc -static -o hello hello.c
readelf -s hello
3127: 00010418 0 FUNC GLOBAL DEFAULT 4 _start
在以下地方下断点
linux-source-5.15.0版本b binfmt_elf.c:1325也可以br s --file binfmt_elf.c --line 1325
c运行到此处,在c几次让START_TRHEAD宏运行完
如下:
p/x *regs
(pt_regs) $7 = {
uregs = {
[13] = 0x7e952f10
[14] = 0x00000000
[15] = 0x00010418
[16] = 0x00000010
[17] = 0x00000000
}
我们看到[15]=后面就是10418,也就是上面Glibc的入口_start函数。
结尾:
这里还有几个问题:
ret_from_fork是否同xx64一样被_schedule和schedule调度。
Arm32的_start调用是否也是缺页异常。
关于这两点下篇再看看。
作者:江湖评谈(jianghupt)公众号同名。欢迎关注我,带你了解进阶技术。

进阶技术:Linux Arm32是如何调用C Main的的更多相关文章
- Java都有什么进阶技术
Java都有什么进阶技术? 看到有人给题主推荐<代码整洁之道>,评论有人说那不是JAVA进阶的书- 私以为,一些人对JAVA进阶的理解片面了,JAVA不过也是一门语言,提升和进阶还是内 ...
- linux下c程序调用reboot函数实现直接重启【转】
转自:http://www.blog.chinaunix.net/uid-20564848-id-73878.html linux下c程序调用reboot函数实现直接重启 当然你也可以直接调用syst ...
- Linux平台下Java调用C函数
JNI是Java native interface的简写,可以译作Java原生接口.Java可以通过JNI调用C/C++的库,这对于那些对性能要求比较高的Java程序无疑是一个 福音. 使用JNI也是 ...
- WCF技术剖析之十:调用WCF服务的客户端应该如何进行异常处理
原文:WCF技术剖析之十:调用WCF服务的客户端应该如何进行异常处理 在前面一片文章(服务代理不能得到及时关闭会有什么后果?)中,我们谈到及时关闭服务代理(Service Proxy)在一个高并发环境 ...
- 在linux下sh批处理文件调用java的方法
解密 java -classpath collection-impl-0.0.1.jar com.ai.toptea.collection.message.DESEncrypt 1EFE4663895 ...
- Linux(centos 6.5) 调用java脚本以及定时运行的脚本实例及配置文件具体解释
Linux(centos 6.5) 调用java脚本以及定时运行的脚本实例 一.调用java程序脚本(默认已经搭建好了Java环境) 1.jdk 安装路径 /usr/jdk/jdk1.7/-- 2.j ...
- 史上最全的Java高级技术点,全是Java高级进阶技术,几乎包含了Java后端的所有知识点
史上最全的Java高级技术点,全是Java高级进阶技术,几乎包含了Java后端的所有知识点 1
- windows和linux环境下java调用C++代码-JNI技术
最近部门做安卓移动开发的需要调C++的代码,困难重重,最后任务交给了我,查找相关资料,没有一个教程能把不同环境(windows,linux)下怎么调用说明白的,自己在实现的过程中踩了几个坑,在这里总结 ...
- Linux系统调用和库函数调用的区别
Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions).系统调用实际上就是指最底层的一个调用,在linux程序设计里面就是底层调用的意思 ...
- linux系统调用和库函数调用的区别(转)
Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions).可以参考<Linux程序设计>(英文原版为<Beginning ...
随机推荐
- Nginx负载均衡策略的介绍与调优
工作中经常会用到nginx负载均衡这一块,下面对nginx负载均衡策略做个总结.本人在工作中最常用到的负载均衡策略是轮询策略. 在一般情况下,Web中间件最大的作用就是负责对请求进行分发,也就是我们常 ...
- 2021-2022 ICPC, NERC, Northern Eurasia Onsite (Unrated, Online Mirror, ICPC Rules, Teams Preferred) J. Job Lookup
题意 n个节点,n<=200,你需要构造这n个几点成为一棵树,并且这棵树的中序遍历为1-n; 你构造树的节点之间的最短路构成一个n×n的最短距离矩阵d: 同时给你n×n的权重矩阵c:最最小的Σd ...
- NC-UClient下载安装应用详解
aliases: [] tags : " #NC " summary: [UClient下载安装NCC应用详解] product: [NCX] author : [yaenli] ...
- WebKit策略:<foreignObject>可用于绘制svg中的html标签,但与<use>搭配不生效
在<svg>里面可以利用<foreignObject>绘制html标签,原本是我在iconfont采用Font class方式引入svg的无奈之举. 起初的设计是所有icon先 ...
- Java-数组工具类Arrays
java.util.Arrays是一个与数组相关的工具类,里面提供了大量静态方法,用来实现数组常见的操作. toSting方法 public static String toString(数组):将参 ...
- Windows之应用安装程序 —— winget
大家都用过Linux中的应用程序安装工具,如yum.apt.rpm等工具进行安装自己想要的一些工具或则软件之类的,当然Linux操作系统还是很强大的有很多类似的命令来安装我们所需要的程序,但是wind ...
- JSON提取器中串联一个接口的多个值传给下个接口(compute concatenation var的实际使用场景)
实际场景:某功能在前端支持选择多条数据后点击提交,表现在接口是,一次传了多个Id. 问题:需要将上个接口的多个Id串联,传给提交接口. 处理方式:通过JSON提取器勾选:compute concate ...
- CentOS Linux 的安装
CentOS Linux 的安装 作者:Grey 原文地址: 博客园:CentOS Linux 的安装 CSDN:CentOS Linux 的安装 说明 本安装说明是基于 Windows 10 下 V ...
- WeetCode3 暴力递归->记忆化搜索->动态规划
笔者这里总结的是一种套路,这种套路笔者最先是从左程云的b站视频学习到的 本文进行简单总结 系列文章目录和关于我 一丶动态规划的思想 使用dp数组记录之前状态计算的最佳结果,找出当前状态和之前状态的关系 ...
- 【数据库】E-R图相关知识、手动自动绘制方法及工具推荐
一.知识 1.介绍 E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体.属性和联系的方法,用来描述现实世界的概念模型. 2.组成 (1)实体(Entit ...