📄 52.html
字号:
<a name='L196'><i><font color='green'> * 任何空闲时间里都会被激活(当没有其它任务在运行时),因此对于任务0'pause()'仅意味着</font></i>
<a name='L197'><i><font color='green'> * 我们返回来查看是否有其它任务可以运行,如果没有的话我们就回到这里,一直循环执行'pause()'。</font></i>
<a name='L198'><i><font color='green'> */</font></i>
<a name='L199'> <b>for</b> (;;)
<a name='L200'> pause ();
<a name='L201'><font color='red'>}</font>
<a name='L202'>
<a name='L203'><b>static</b> <b>int</b> <a href='../R/553.html' title='Multiple refered from 5 places.'>printf</a> (<b>const</b> <b>char</b> *fmt, ...)
<a name='L204'> <i><font color='green'>// 产生格式化信息并输出到标准输出设备stdout(1),这里是指屏幕上显示。参数'*fmt'指定输出将</font></i>
<a name='L205'> <i><font color='green'>// 采用的格式,参见各种标准C 语言书籍。该子程序正好是vsprintf 如何使用的一个例子。</font></i>
<a name='L206'> <i><font color='green'>// 该程序使用vsprintf()将格式化的字符串放入printbuf 缓冲区,然后用write()将缓冲区的内容</font></i>
<a name='L207'> <i><font color='green'>// 输出到标准设备(1--stdout)。</font></i>
<a name='L208'><font color='red'>{</font>
<a name='L209'> <a href='../S/40.html#L4' title='Defined at 4 in include/stdarg.h.'>va_list</a> args;
<a name='L210'> <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L211'>
<a name='L212'> <a href='../D/1107.html' title='Multiple defined in 2 places.'>va_start</a> (args, fmt);
<a name='L213'> write (1, printbuf, <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = <a href='../S/78.html#L137' title='Defined at 137 in kernel/vsprintf.c.'>vsprintf</a> (printbuf, fmt, args));
<a name='L214'> <a href='../S/40.html#L32' title='Defined at 32 in include/stdarg.h.'>va_end</a> (args);
<a name='L215'> <b>return</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L216'><font color='red'>}</font>
<a name='L217'>
<a name='L218'><b>static</b> <b>char</b> *argv_rc[] =
<a name='L219'><font color='red'>{</font>
<a name='L220'>"/bin/sh", <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a><font color='red'>}</font>; <i><font color='green'>// 调用执行程序时参数的字符串数组。</font></i>
<a name='L221'><b>static</b> <b>char</b> *envp_rc[] =
<a name='L222'><font color='red'>{</font>
<a name='L223'>"HOME=/", <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a><font color='red'>}</font>; <i><font color='green'>// 调用执行程序时的环境字符串数组。</font></i>
<a name='L224'>
<a name='L225'><b>static</b> <b>char</b> *argv[] =
<a name='L226'><font color='red'>{</font>
<a name='L227'>"-/bin/sh", <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a><font color='red'>}</font>; <i><font color='green'>// 同上。</font></i>
<a name='L228'><b>static</b> <b>char</b> *envp[] =
<a name='L229'><font color='red'>{</font>
<a name='L230'>"HOME=/usr/root", <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a><font color='red'>}</font>;
<a name='L231'>
<a name='L232'><b>void</b> <a href='../R/501.html' title='Multiple refered from 3 places.'>init</a> (<b>void</b>)
<a name='L233'><font color='red'>{</font>
<a name='L234'> <b>int</b> pid, <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L235'>
<a name='L236'> <i><font color='green'>// 读取硬盘参数包括分区表信息并建立虚拟盘和安装根文件系统设备。</font></i>
<a name='L237'> <i><font color='green'>// 该函数是在25 行上的宏定义的,对应函数是sys_setup(),在kernel/blk_drv/hd.c,71 行。</font></i>
<a name='L238'> setup ((<b>void</b> *) &drive_info);
<a name='L239'> (<b>void</b>) <a href='../S/87.html#L19' title='Defined at 19 in lib/open.c.'>open</a> ("/dev/tty0", <a href='../S/29.html#L12' title='Defined at 12 in include/fcntl.h.'>O_RDWR</a>, 0); <i><font color='green'>// 用读写访问方式打开设备“/dev/tty0”,</font></i>
<a name='L240'> <i><font color='green'>// 这里对应终端控制台。</font></i>
<a name='L241'> <i><font color='green'>// 返回的句柄号0 -- stdin 标准输入设备。</font></i>
<a name='L242'> (<b>void</b>) dup (0); <i><font color='green'>// 复制句柄,产生句柄1 号 -- stdout 标准输出设备。</font></i>
<a name='L243'> (<b>void</b>) dup (0); <i><font color='green'>// 复制句柄,产生句柄2 号 -- stderr 标准出错输出设备。</font></i>
<a name='L244'> <a href='../S/52.html#L203' title='Defined at 203 in init/main.c.'>printf</a> ("%d buffers = %d bytes buffer space\n\r", <a href='../S/31.html#L64' title='Defined at 64 in include/linux/fs.h.'>NR_BUFFERS</a>, <a href='../S/31.html#L64' title='Defined at 64 in include/linux/fs.h.'>NR_BUFFERS</a> * <a href='../D/23.html' title='Multiple defined in 2 places.'>BLOCK_SIZE</a>); <i><font color='green'>// 打印缓冲区块数和总字节数,每块1024 字节。</font></i>
<a name='L245'> <a href='../S/52.html#L203' title='Defined at 203 in init/main.c.'>printf</a> ("Free mem: %d bytes\n\r", memory_end - main_memory_start); <i><font color='green'>//空闲内存字节数。</font></i>
<a name='L246'> <i><font color='green'>// 下面fork()用于创建一个子进程(子任务)。对于被创建的子进程,fork()将返回0 值,</font></i>
<a name='L247'> <i><font color='green'>// 对于原(父进程)将返回子进程的进程号。所以180-184 句是子进程执行的内容。该子进程</font></i>
<a name='L248'> <i><font color='green'>// 关闭了句柄0(stdin),以只读方式打开/etc/rc 文件,并执行/bin/sh 程序,所带参数和</font></i>
<a name='L249'> <i><font color='green'>// 环境变量分别由argv_rc 和envp_rc 数组给出。参见后面的描述。</font></i>
<a name='L250'> <b>if</b> (!(pid = fork ()))
<a name='L251'> <font color='red'>{</font>
<a name='L252'> close (0);
<a name='L253'> <b>if</b> (<a href='../S/87.html#L19' title='Defined at 19 in lib/open.c.'>open</a> ("/etc/rc", <a href='../S/29.html#L10' title='Defined at 10 in include/fcntl.h.'>O_RDONLY</a>, 0))
<a name='L254'> <a href='../S/92.html#L16' title='Defined at 16 in lib/_exit.c.'>_exit</a> (1); <i><font color='green'>// 如果打开文件失败,则退出(/lib/_exit.c,10)。</font></i>
<a name='L255'> execve ("/bin/sh", argv_rc, envp_rc); <i><font color='green'>// 装入/bin/sh 程序并执行。</font></i>
<a name='L256'> <a href='../S/92.html#L16' title='Defined at 16 in lib/_exit.c.'>_exit</a> (2); <i><font color='green'>// 若execve()执行失败则退出(出错码2,“文件或目录不存在”)。</font></i>
<a name='L257'> <font color='red'>}</font>
<a name='L258'> <i><font color='green'>// 下面是父进程执行的语句。wait()是等待子进程停止或终止,其返回值应是子进程的进程号(pid)。</font></i>
<a name='L259'> <i><font color='green'>// 这三句的作用是父进程等待子进程的结束。&i 是存放返回状态信息的位置。如果wait()返回值不</font></i>
<a name='L260'> <i><font color='green'>// 等于子进程号,则继续等待。</font></i>
<a name='L261'> <b>if</b> (pid > 0)
<a name='L262'> <b>while</b> (pid != wait (&<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>))
<a name='L263'> <i><font color='green'>/* nothing */</font></i> ;
<a name='L264'> <i><font color='green'>// 如果执行到这里,说明刚创建的子进程的执行已停止或终止了。下面循环中首先再创建一个子进程,</font></i>
<a name='L265'> <i><font color='green'>// 如果出错,则显示“初始化程序创建子进程失败”的信息并继续执行。对于所创建的子进程关闭所有</font></i>
<a name='L266'> <i><font color='green'>// 以前还遗留的句柄(stdin, stdout, stderr),新创建一个会话并设置进程组号,然后重新打开</font></i>
<a name='L267'> <i><font color='green'>// /dev/tty0 作为stdin,并复制成stdout 和stderr。再次执行系统解释程序/bin/sh。但这次执行所</font></i>
<a name='L268'> <i><font color='green'>// 选用的参数和环境数组另选了一套(见上面165-167 行)。然后父进程再次运行wait()等待。如果</font></i>
<a name='L269'> <i><font color='green'>// 子进程又停止了执行,则在标准输出上显示出错信息“子进程pid 停止了运行,返回码是i”,然后</font></i>
<a name='L270'> <i><font color='green'>// 继续重试下去…,形成“大”死循环。</font></i>
<a name='L271'> <b>while</b> (1)
<a name='L272'> <font color='red'>{</font>
<a name='L273'> <b>if</b> ((pid = fork ()) < 0)
<a name='L274'> <font color='red'>{</font>
<a name='L275'> <a href='../S/52.html#L203' title='Defined at 203 in init/main.c.'>printf</a> ("Fork failed in init\r\n");
<a name='L276'> <b>continue</b>;
<a name='L277'> <font color='red'>}</font>
<a name='L278'> <b>if</b> (!pid)
<a name='L279'> <font color='red'>{</font>
<a name='L280'> close (0);
<a name='L281'> close (1);
<a name='L282'> close (2);
<a name='L283'> setsid ();
<a name='L284'> (<b>void</b>) <a href='../S/87.html#L19' title='Defined at 19 in lib/open.c.'>open</a> ("/dev/tty0", <a href='../S/29.html#L12' title='Defined at 12 in include/fcntl.h.'>O_RDWR</a>, 0);
<a name='L285'> (<b>void</b>) dup (0);
<a name='L286'> (<b>void</b>) dup (0);
<a name='L287'> <a href='../S/92.html#L16' title='Defined at 16 in lib/_exit.c.'>_exit</a> (execve ("/bin/sh", argv, envp));
<a name='L288'> <font color='red'>}</font>
<a name='L289'> <b>while</b> (1)
<a name='L290'> <b>if</b> (pid == wait (&<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>))
<a name='L291'> <b>break</b>;
<a name='L292'> <a href='../S/52.html#L203' title='Defined at 203 in init/main.c.'>printf</a> ("\n\rchild %d died with code %04x\n\r", pid, <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>);
<a name='L293'> sync ();
<a name='L294'> <font color='red'>}</font>
<a name='L295'> <a href='../S/92.html#L16' title='Defined at 16 in lib/_exit.c.'>_exit</a> (0); <i><font color='green'>/* NOTE! _exit, not exit() */</font></i>
<a name='L296'><font color='red'>}</font>
</pre>
<hr>
<a name='BOTTOM'>
<i><font color='green'>/* [<][>]<a href='#L35'>[^]</a><a href='#L232'>[v]</a><a href='#TOP'>[top]</a>[bottom]<a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -