热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux加载一个可执行程序并启动的过程

原创作品转载请注明出处+《Linux内核分析》MOOC课程http:mooc.study.163.comcourseUSTC-1000029000作者:严哲璟以shell下执行ls

原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

作者:严哲璟

以shell下执行ls命令为例介绍Linux通过fork()和execve()类函数的执行程序启动过程:

父进程为shell,命令为ls,目录为/bin/ls  

当输入ls时,shell进程通过fork()创建一个新的子进程,fork()进程,以及新建堆栈等之前已经说明,子进程有机会执行的时候,在ret_from_fork()开始,返回到子进程的用户堆栈中,执行其余的子进程的代码.

在这些子进程需要执行的代码中,有execve(/bin/ls,ls,NULL),ls是列出当前路径的目录的一个可执行文件,同理如./a.out等

为加载此可执行文件到内存中执行,关键的地方在于,execve返回之后,执行的代码变成了需要加载的可执行文件的代码,下面详细说明它是如何做到的.

首先 execve()函数是系统调用,陷入内核,调用do_execve_common()函数,此函数的作用是加载需要执行的可执行文件的ELF头,因为后面需要将可执行文件的信息压入代码段以及将PC指向可执行文件的起点

1430static int do_execve_common(struct filename *filename,
1431				struct user_arg_ptr argv,
1432				struct user_arg_ptr envp)
1433{
1434	struct linux_binprm *bprm;
1435	struct file *file;
1436	struct files_struct *displaced;
1437	int retval;
1438
1439	if (IS_ERR(filename))
1440		return PTR_ERR(filename);
1441
1442	/*
1443	 * We move the actual failure in case of RLIMIT_NPROC excess from
1444	 * set*uid() to execve() because too many poorly written programs
1445	 * don‘t check setuid() return code.  Here we additionally recheck
1446	 * whether NPROC limit is still exceeded.
1447	 */
1448	if ((current->flags & PF_NPROC_EXCEEDED) &&
1449	    atomic_read(¤t_user()->processes) > rlimit(RLIMIT_NPROC)) {
1450		retval = -EAGAIN;
1451		goto out_ret;
1452	}
1453
1454	/* We‘re below the limit (still or again), so we don‘t want to make
1455	 * further execve() calls fail. */
1456	current->flags &= ~PF_NPROC_EXCEEDED;
1457
1458	retval = unshare_files(&displaced);
1459	if (retval)
1460		goto out_ret;
1461
1462	retval = -ENOMEM;
1463	bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
1464	if (!bprm)
1465		goto out_files;
1466
1467	retval = prepare_bprm_creds(bprm);
1468	if (retval)
1469		goto out_free;
1470
1471	check_unsafe_exec(bprm);
1472	current->in_execve = 1;
1473
1474	file = do_open_exec(filename);
1475	retval = PTR_ERR(file);
1476	if (IS_ERR(file))
1477		goto out_unmark;
1478
1479	sched_exec();
1480
1481	bprm->file = file;
1482	bprm->filename = bprm->interp = filename->name;
1483
1484	retval = bprm_mm_init(bprm);
1485	if (retval)
1486		goto out_unmark;
1487
1488	bprm->argc = count(argv, MAX_ARG_STRINGS);
1489	if ((retval = bprm->argc) <0)
1490		goto out;
1491
1492	bprm->envc = count(envp, MAX_ARG_STRINGS);
1493	if ((retval = bprm->envc) <0)
1494		goto out;
1495
1496	retval = prepare_binprm(bprm);
1497	if (retval <0)
1498		goto out;
1499
1500	retval = copy_strings_kernel(1, &bprm->filename, bprm);
1501	if (retval <0)
1502		goto out;
1503
1504	bprm->exec = bprm->p;
1505	retval = copy_strings(bprm->envc, envp, bprm);
1506	if (retval <0)
1507		goto out;
1508
1509	retval = copy_strings(bprm->argc, argv, bprm);
1510	if (retval <0)
1511		goto out;
1512
1513	retval = exec_binprm(bprm)

Linux加载一个可执行程序并启动的过程


推荐阅读
  • 安全3AAuthentication:认证Authorzation:授权Accouting|Audition:审计用户管理用户:UID:0,不一定是root,root的uid非0时 ... [详细]
  • 1.数据准备#测试数组vectorc(5,34,65,36,67,3,6,43,69,59,25,785,10,11,14)vector##[1]53465366736436959 ... [详细]
  • packagetest;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOE ... [详细]
  • ARToolKitunity
    ARToolKit为开源的AR库,相对于高通和easyAr有几点特点:1)开源2)识别项目可以动态添加(详细在后)3)识别文件可以本地生成4)目前只能识别图片(目前为.jpg格式) ... [详细]
  • 【实践】基于RTThread的智慧路灯案例实验分享
    之前分享了基于LiteOS的智慧农业案例实验分享基于LiteOS的智慧农业案例实验分享,阅读量挺不错,看样子大家都挺喜欢这种实验。那咱们就再来一个类似的实验:基于RT-Thread ... [详细]
  • UDP协议开发
    UDP是用户数据报协议(UserDatagramProtocol,UDP)的简称,其主要作用是将网络数据流量压缩成数据报形式,提供面向事务的简单信息传送服务。与TCP协议不同,UD ... [详细]
  • 利用ipv6技术,废旧笔记本变成server
    如果你家的路由器已经get到了ipv6地址,并且你家的电脑也获取了有效的ipv6地址,在广域网的设备可以访问到。那恭喜你,再配合我这个dd ... [详细]
  • 目录结构如下:Nginx基础知识NginxHTTP服务器的特色及优点Nginx的主要企业功能Nginx作为web服务器的主要应用场景包括:Nginx的安装安装环境 ... [详细]
  • rbac 4表 常规设计
    rbac4表常规设计设计模型:1、管理员表(users)Schema::create('users',function(Blueprint$table){$tabl ... [详细]
  • phpstorm使用和配置技巧
    1.使用phpstorm的过程中,有时光标不小心变成了方块状,怎么修复回来呢?见下图,去掉“Useblockcare ... [详细]
  • webpack 配置IP 和端口号
    最近在用webpack搭建本地服务器的时候,因为不想总是用localhost来跑,所以对webpack.config.js进行了配置,如下devServer:{publicPath ... [详细]
  • 第38天:Python decimal 模块
    by程序员野客在我们开发工作中浮点类型的使用还是比较普遍的,对于一些涉及资金金额的计算更是不能有丝毫误差,Python的decimal模块为浮点型精确计算提供了支持。1简介deci ... [详细]
  • win10如何将现有的桌面壁纸找出来
    直接在地址栏输入“C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Themes”,将用户名替换为本机当前用户名,然后按下回车键即可。P ... [详细]
  • 题目:Givenanintegerarray,youneedtofindone continuoussubarray thatifyouonlysortthissubarrayin ... [详细]
  • Jmeter的聚合报告
       ... [详细]
author-avatar
最苦的等待2502915147
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有