8.html

来自「linux 0.11中文版 有注释」· HTML 代码 · 共 573 行 · 第 1/4 页

HTML
573
字号
<html>
<head>
<title>fs/exec.c</title>
<meta name='robots' content='noindex,nofollow'>
<meta name='generator' content='GLOBAL-5.4.1'>
</head>
<body text='#191970' bgcolor='#f5f5dc' vlink='gray'>
<a name='TOP'><h2><a href='../mains.html'>root</a>/<a href='../files/98.html'>fs</a>/exec.c</h2>
<i><font color='green'>/* [&lt;][&gt;]<a href='#L70'>[^]</a><a href='#L294'>[v]</a>[top]<a href='#BOTTOM'>[bottom]</a><a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
<hr>
<h2>DEFINITIONS</h2>
This source file includes following definitions.
<ol>
<li><a href='#L70' title='Defined at 70.'>create_tables</a>
<li><a href='#L115' title='Defined at 115.'>count</a>
<li><a href='#L166' title='Defined at 166.'>copy_strings</a>
<li><a href='#L248' title='Defined at 248.'>change_ldt</a>
<li><a href='#L294' title='Defined at 294.'>do_execve</a>
</ol>
<hr>
<pre>
<a name='L1'><i><font color='green'>/*</font></i>
<a name='L2'><i><font color='green'>* linux/fs/exec.c</font></i>
<a name='L3'><i><font color='green'>*</font></i>
<a name='L4'><i><font color='green'>* (C) 1991 Linus Torvalds</font></i>
<a name='L5'><i><font color='green'>*/</font></i>
<a name='L6'>
<a name='L7'><i><font color='green'>/*</font></i>
<a name='L8'><i><font color='green'>* #!-checking implemented by tytso.</font></i>
<a name='L9'><i><font color='green'>*/</font></i>
<a name='L10'><i><font color='green'>/*</font></i>
<a name='L11'><i><font color='green'>* #!开始的程序检测部分是由tytso 实现的。</font></i>
<a name='L12'><i><font color='green'>*/</font></i>
<a name='L13'>
<a name='L14'><i><font color='green'>/*</font></i>
<a name='L15'><i><font color='green'>* Demand-loading implemented 01.12.91 - no need to read anything but</font></i>
<a name='L16'><i><font color='green'>* the header into memory. The inode of the executable is put into</font></i>
<a name='L17'><i><font color='green'>* "current-&gt;executable", and page faults do the actual loading. Clean.</font></i>
<a name='L18'><i><font color='green'>*</font></i>
<a name='L19'><i><font color='green'>* Once more I can proudly say that linux stood up to being changed: it</font></i>
<a name='L20'><i><font color='green'>* was less than 2 hours work to get demand-loading completely implemented.</font></i>
<a name='L21'><i><font color='green'>*/</font></i>
<a name='L22'><i><font color='green'>/*</font></i>
<a name='L23'><i><font color='green'>* 需求时加载是于1991.12.1 实现的 - 只需将执行文件头部分读进内存而无须</font></i>
<a name='L24'><i><font color='green'>* 将整个执行文件都加载进内存。执行文件的i 节点被放在当前进程的可执行字段中</font></i>
<a name='L25'><i><font color='green'>* ("current-&gt;executable"),而页异常会进行执行文件的实际加载操作以及清理工作。</font></i>
<a name='L26'><i><font color='green'>*</font></i>
<a name='L27'><i><font color='green'>* 我可以再一次自豪地说,linux 经得起修改:只用了不到2 小时的工作时间就完全</font></i>
<a name='L28'><i><font color='green'>* 实现了需求加载处理。</font></i>
<a name='L29'><i><font color='green'>*/</font></i>
<a name='L30'>
<a name='L31'><font color='darkred'>#include</font> &lt;<a href='28.html'>errno.h</a>&gt;              <i><font color='green'>// 错误号头文件。包含系统中各种出错号。(Linus 从minix 中引进的)。</font></i>
<a name='L32'><font color='darkred'>#include</font> &lt;<a href='42.html'>string.h</a>&gt;             <i><font color='green'>// 字符串头文件。主要定义了一些有关字符串操作的嵌入函数。</font></i>
<a name='L33'><font color='darkred'>#include</font> &lt;<a href='43.html'>sys/stat.h</a>&gt;           <i><font color='green'>// 文件状态头文件。含有文件或文件系统状态结构stat{}和常量。</font></i>
<a name='L34'><font color='darkred'>#include</font> &lt;<a href='21.html'>a.out.h</a>&gt;              <i><font color='green'>// a.out 头文件。定义了a.out 执行文件格式和一些宏。</font></i>
<a name='L35'>
<a name='L36'><font color='darkred'>#include</font> &lt;<a href='31.html'>linux/fs.h</a>&gt;           <i><font color='green'>// 文件系统头文件。定义文件表结构(file,buffer_head,m_inode 等)。</font></i>
<a name='L37'><font color='darkred'>#include</font> &lt;<a href='36.html'>linux/sched.h</a>&gt;        <i><font color='green'>// 调度程序头文件,定义了任务结构task_struct、初始任务0 的数据,</font></i>
<a name='L38'><i><font color='green'>// 还有一些有关描述符参数设置和获取的嵌入式汇编函数宏语句。</font></i>
<a name='L39'><font color='darkred'>#include</font> &lt;<a href='34.html'>linux/kernel.h</a>&gt;       <i><font color='green'>// 内核头文件。含有一些内核常用函数的原形定义。</font></i>
<a name='L40'><font color='darkred'>#include</font> &lt;<a href='35.html'>linux/mm.h</a>&gt;           <i><font color='green'>// 内存管理头文件。含有页面大小定义和一些页面释放函数原型。</font></i>
<a name='L41'><font color='darkred'>#include</font> &lt;<a href='24.html'>asm/segment.h</a>&gt;        <i><font color='green'>// 段操作头文件。定义了有关段寄存器操作的嵌入式汇编函数。</font></i>
<a name='L42'>
<a name='L43'><b>extern</b> <b>int</b> <a href='../S/67.html#L187' title='Defined at 187 in kernel/exit.c.'>sys_exit</a> (<b>int</b> exit_code);    <i><font color='green'>// 程序退出系统调用。</font></i>
<a name='L44'><b>extern</b> <b>int</b> <a href='../S/15.html#L299' title='Defined at 299 in fs/open.c.'>sys_close</a> (<b>int</b> fd);  <i><font color='green'>// 文件关闭系统调用。</font></i>
<a name='L45'>
<a name='L46'><i><font color='green'>/*</font></i>
<a name='L47'><i><font color='green'>* MAX_ARG_PAGES defines the number of pages allocated for arguments</font></i>
<a name='L48'><i><font color='green'>* and envelope for the new program. 32 should suffice, this gives</font></i>
<a name='L49'><i><font color='green'>* a maximum env+arg of 128kB !</font></i>
<a name='L50'><i><font color='green'>*/</font></i>
<a name='L51'><i><font color='green'>/*</font></i>
<a name='L52'><i><font color='green'>* MAX_ARG_PAGES 定义了新程序分配给参数和环境变量使用的内存最大页数。</font></i>
<a name='L53'><i><font color='green'>* 32 页内存应该足够了,这使得环境和参数(env+arg)空间的总合达到128kB!</font></i>
<a name='L54'><i><font color='green'>*/</font></i>
<a name='L55'><font color='darkred'>#define</font> <a href='../R/123.html' title='Multiple refered from 6 places.'>MAX_ARG_PAGES</a> 32
<a name='L56'>
<a name='L57'><i><font color='green'>/*</font></i>
<a name='L58'><i><font color='green'>* create_tables() parses the env- and arg-strings in new user</font></i>
<a name='L59'><i><font color='green'>* memory and creates the pointer tables from them, and puts their</font></i>
<a name='L60'><i><font color='green'>* addresses on the "stack", returning the new stack pointer value.</font></i>
<a name='L61'><i><font color='green'>*/</font></i>
<a name='L62'><i><font color='green'>/*</font></i>
<a name='L63'><i><font color='green'>* create_tables()函数在新用户内存中解析环境变量和参数字符串,由此</font></i>
<a name='L64'><i><font color='green'>* 创建指针表,并将它们的地址放到"堆栈"上,然后返回新栈的指针值。</font></i>
<a name='L65'><i><font color='green'>*/</font></i>
<a name='L66'><i><font color='green'>//// 在新用户堆栈中创建环境和参数变量指针表。</font></i>
<a name='L67'><i><font color='green'>// 参数:p - 以数据段为起点的参数和环境信息偏移指针;argc - 参数个数;envc -环境变量数。</font></i>
<a name='L68'><i><font color='green'>// 返回:堆栈指针。</font></i>
<a name='L69'><b>static</b> <b>unsigned</b> <b>long</b> *
<a name='L70'><a href='../S/8.html#L520' title='Refered from 520 in fs/exec.c.'>create_tables</a> (<b>char</b> *p, <b>int</b> argc, <b>int</b> envc)
<a name='L71'><font color='red'>{</font>
<a name='L72'>  <b>unsigned</b> <b>long</b> *argv, *envp;
<a name='L73'>  <b>unsigned</b> <b>long</b> *sp;
<a name='L74'>
<a name='L75'><i><font color='green'>// 堆栈指针是以4 字节(1 节)为边界寻址的,因此这里让sp 为4 的整数倍。</font></i>
<a name='L76'>  sp = (<b>unsigned</b> <b>long</b> *) (0xfffffffc &amp; (<b>unsigned</b> <b>long</b>) p);
<a name='L77'><i><font color='green'>// sp 向下移动,空出环境参数占用的空间个数,并让环境参数指针envp 指向该处。</font></i>
<a name='L78'>  sp -= envc + 1;
<a name='L79'>  envp = sp;
<a name='L80'><i><font color='green'>// sp 向下移动,空出命令行参数指针占用的空间个数,并让argv 指针指向该处。</font></i>
<a name='L81'><i><font color='green'>// 下面指针加1,sp 将递增指针宽度字节值。</font></i>
<a name='L82'>  sp -= argc + 1;
<a name='L83'>  argv = sp;
<a name='L84'><i><font color='green'>// 将环境参数指针envp 和命令行参数指针以及命令行参数个数压入堆栈。</font></i>
<a name='L85'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> ((<b>unsigned</b> <b>long</b>) envp, --sp);
<a name='L86'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> ((<b>unsigned</b> <b>long</b>) argv, --sp);
<a name='L87'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> ((<b>unsigned</b> <b>long</b>) argc, --sp);
<a name='L88'><i><font color='green'>// 将命令行各参数指针放入前面空出来的相应地方,最后放置一个NULL 指针。</font></i>
<a name='L89'>  <b>while</b> (argc-- &gt; 0)
<a name='L90'>    <font color='red'>{</font>
<a name='L91'>      <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> ((<b>unsigned</b> <b>long</b>) p, argv++);
<a name='L92'>      <b>while</b> (<a href='../D/821.html' title='Multiple defined in 2 places.'>get_fs_byte</a> (p++)) <i><font color='green'>/* nothing */</font></i> ; <i><font color='green'>// p 指针前移4 字节。</font></i>
<a name='L93'>    <font color='red'>}</font>
<a name='L94'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (0, argv);
<a name='L95'><i><font color='green'>// 将环境变量各指针放入前面空出来的相应地方,最后放置一个NULL 指针。</font></i>
<a name='L96'>  <b>while</b> (envc-- &gt; 0)
<a name='L97'>    <font color='red'>{</font>
<a name='L98'>      <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> ((<b>unsigned</b> <b>long</b>) p, envp++);
<a name='L99'>      <b>while</b> (<a href='../D/821.html' title='Multiple defined in 2 places.'>get_fs_byte</a> (p++)) <i><font color='green'>/* nothing */</font></i> ;
<a name='L100'>    <font color='red'>}</font>
<a name='L101'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (0, envp);
<a name='L102'>  <b>return</b> sp;                    <i><font color='green'>// 返回构造的当前新堆栈指针。</font></i>
<a name='L103'><font color='red'>}</font>
<a name='L104'>
<a name='L105'><i><font color='green'>/*</font></i>
<a name='L106'><i><font color='green'>* count() counts the number of arguments/envelopes</font></i>
<a name='L107'><i><font color='green'>*/</font></i>
<a name='L108'><i><font color='green'>/*</font></i>
<a name='L109'><i><font color='green'>* count()函数计算命令行参数/环境变量的个数。</font></i>
<a name='L110'><i><font color='green'>*/</font></i>
<a name='L111'><i><font color='green'>//// 计算参数个数。</font></i>
<a name='L112'><i><font color='green'>// 参数:argv - 参数指针数组,最后一个指针项是NULL。</font></i>
<a name='L113'><i><font color='green'>// 返回:参数个数。</font></i>
<a name='L114'><b>static</b> <b>int</b>
<a name='L115'><a href='../R/414.html' title='Multiple refered from 56 places.'>count</a> (<b>char</b> **argv)
<a name='L116'><font color='red'>{</font>
<a name='L117'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0;
<a name='L118'>  <b>char</b> **tmp;
<a name='L119'>
<a name='L120'>  <b>if</b> (tmp = argv)
<a name='L121'>    <b>while</b> (<a href='../S/24.html#L32' title='Defined at 32 in include/asm/segment.h.'>get_fs_long</a> ((<b>unsigned</b> <b>long</b> *) (tmp++)))
<a name='L122'>      <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++;
<a name='L123'>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?