首页 > 系统相关 >进阶技术:Linux Arm32是如何调用C Main的

进阶技术:Linux Arm32是如何调用C Main的

时间:2023-02-09 14:57:15浏览次数:44  
标签:进阶 thread Arm32 frame elf regs vmlinux start Linux

前言:

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)公众号同名。欢迎关注我,带你了解高阶技术。
image

标签:进阶,thread,Arm32,frame,elf,regs,vmlinux,start,Linux
From: https://www.cnblogs.com/tangyanzhi1111/p/17103953.html

相关文章

  • linux centos中利用命令行发送邮件
     001、date|mail-s"Subject"[email protected]##发送一个日期    002、date|mail-aa.ped-s"Subject"[email protected]......
  • Linux 系统管理 07——文件系统与 LVM
    一、创建文件系统mkfs、mkswap命令1、mkfs命令(1)作用:创建文件系统(格式化)MakeFilesystem(2)格式:mkfs  –t  文件系统类型  分区设备      (mkfs.文......
  • linux命令大全
    linux的目录结构有四个home:家,不同用户的家root:超级管理员root的家etc:存放配置文件usr:存放共享的资源命令格式:命令[选项][参数]ls命令-a显示所有......
  • glsl进阶学习8
    我们来画出平躺着的圆环//SDFfloatvalue1=sqrt(x*x+y*y)-r1;floatvalue2=sqrt(value1*value1+z*z)-r2;returnvalue2;但是。。这个东西怎么旋转平移喃。。我还需要再......
  • glsl进阶学习5
    看了一位老师傅的水波纹shader大概讲的是距离P的距离关联一些距离时间因素作为sin(r)中的r 然后得到z这个z用颜色来表达 感觉又多了一点3维函数的感觉之前都考虑的是......
  • glsl进阶学习 一
    shadertoy上面的环境 一开始会有一个逻辑尺寸和画布尺寸的比值uv先来尝试一个plane这主要计算一个t P是平面上一个点另一个点是光线与平面交点叫P1吧P1=o+dt  t是......
  • Linux下Zookeeper安装和启动
    Zookeeper安装0.环境Inteli5-1240016GBMemoryUbuntu20.04.5LTSLinux5.15.0-52-generic1.下载官网速度太慢,可以在清华镜像下载https://mirrors.tuna.tsinghu......
  • Linux查看配置信息
    1.安装inxisudoapt-getinstallinxi2.输出报告inxi-Fx注意F大写......
  • linux 安装jdk
    cd/usr/local/wgethttps://mirrors.huaweicloud.com/java/jdk/11+28/jdk-11_linux-x64_bin.tar.gztar-zxvfjdk-11_linux-x64_bin.tar.gzvim/etc/profileexpor......
  • linux
    linux​​linux启动流程​​​​linux系统目录详解​​linux启动流程linux系统目录详解可分享(shareable)不可分享(unshareable)静态的(static)/usr存放软件/opt第三方软件/et......