Files
oldlinux-website/Book-Lite/code-list/html/P7-1.html
2024-03-17 13:59:32 +08:00

3170 lines
125 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name=Generator content="Microsoft Word 14 (filtered)">
<style>
<!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:黑体;
panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
{font-family:黑体;
panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
{font-family:方正小标宋简体;}
@font-face
{font-family:"\@黑体";
panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
{font-family:"\@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:"\@方正小标宋简体";}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
h1
{mso-style-link:"标题 1 Char";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:7.2pt;
text-align:center;
text-indent:-7.2pt;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
h2
{mso-style-link:"标题 2 Char";
margin-top:13.0pt;
margin-right:0cm;
margin-bottom:13.0pt;
margin-left:0cm;
text-align:justify;
text-justify:inter-ideograph;
text-indent:0cm;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
h3
{mso-style-link:"标题 3 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:0cm;
page-break-after:avoid;
font-size:14.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
h4
{mso-style-link:"标题 4 Char";
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:28.8pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-28.8pt;
page-break-after:avoid;
font-size:12.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
h5
{mso-style-link:"标题 5 Char";
margin-top:14.0pt;
margin-right:0cm;
margin-bottom:14.5pt;
margin-left:36.0pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-36.0pt;
line-height:156%;
page-break-after:avoid;
font-size:14.0pt;
font-family:;
font-weight:bold;}
h6
{mso-style-link:"标题 6 Char";
margin-top:12.0pt;
margin-right:0cm;
margin-bottom:3.2pt;
margin-left:43.2pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-43.2pt;
line-height:133%;
page-break-after:avoid;
font-size:12.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
p.MsoHeading7, li.MsoHeading7, div.MsoHeading7
{mso-style-link:"标题 7 Char";
margin-top:12.0pt;
margin-right:0cm;
margin-bottom:3.2pt;
margin-left:50.4pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-50.4pt;
line-height:133%;
page-break-after:avoid;
font-size:12.0pt;
font-family:;
font-weight:bold;}
p.MsoHeading8, li.MsoHeading8, div.MsoHeading8
{mso-style-link:"标题 8 Char";
margin-top:12.0pt;
margin-right:0cm;
margin-bottom:3.2pt;
margin-left:57.6pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-72.0pt;
line-height:133%;
page-break-after:avoid;
font-size:12.0pt;
font-family:"Arial","sans-serif";}
p.MsoHeading9, li.MsoHeading9, div.MsoHeading9
{mso-style-link:"标题 9 Char";
margin-top:12.0pt;
margin-right:0cm;
margin-bottom:3.2pt;
margin-left:64.8pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-79.2pt;
line-height:133%;
page-break-after:avoid;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.MsoIndex1, li.MsoIndex1, div.MsoIndex1
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:10.5pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex2, li.MsoIndex2, div.MsoIndex2
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex3, li.MsoIndex3, div.MsoIndex3
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:31.5pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex4, li.MsoIndex4, div.MsoIndex4
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:42.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex5, li.MsoIndex5, div.MsoIndex5
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:52.5pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex6, li.MsoIndex6, div.MsoIndex6
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:63.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex7, li.MsoIndex7, div.MsoIndex7
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:73.5pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex8, li.MsoIndex8, div.MsoIndex8
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:84.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex9, li.MsoIndex9, div.MsoIndex9
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:94.5pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoToc1, li.MsoToc1, div.MsoToc1
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;
font-weight:bold;}
p.MsoToc2, li.MsoToc2, div.MsoToc2
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.MsoToc3, li.MsoToc3, div.MsoToc3
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:42.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.MsoToc4, li.MsoToc4, div.MsoToc4
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:31.5pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoToc5, li.MsoToc5, div.MsoToc5
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:42.0pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoToc6, li.MsoToc6, div.MsoToc6
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:52.5pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoToc7, li.MsoToc7, div.MsoToc7
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:63.0pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoToc8, li.MsoToc8, div.MsoToc8
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:73.5pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoToc9, li.MsoToc9, div.MsoToc9
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:84.0pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
{mso-style-link:"脚注文本 Char";
margin:0cm;
margin-bottom:.0001pt;
layout-grid-mode:char;
font-size:9.0pt;
font-family:;}
p.MsoCommentText, li.MsoCommentText, div.MsoCommentText
{mso-style-link:"批注文字 Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.5pt;
font-family:;}
p.MsoHeader, li.MsoHeader, div.MsoHeader
{mso-style-link:"页眉 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
layout-grid-mode:char;
border:none;
padding:0cm;
font-size:9.0pt;
font-family:;}
p.MsoFooter, li.MsoFooter, div.MsoFooter
{mso-style-link:"页脚 Char";
margin:0cm;
margin-bottom:.0001pt;
layout-grid-mode:char;
font-size:9.0pt;
font-family:;}
p.MsoIndexHeading, li.MsoIndexHeading, div.MsoIndexHeading
{mso-style-name:"索引标题\,索引类目\,索引类目1\,索引类目2";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.MsoCaption, li.MsoCaption, div.MsoCaption
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.MsoTof, li.MsoTof, div.MsoTof
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:42.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
span.MsoFootnoteReference
{vertical-align:super;}
p.MsoList, li.MsoList, div.MsoList
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.MsoList2, li.MsoList2, div.MsoList2
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.MsoList4, li.MsoList4, div.MsoList4
{margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.MsoDate, li.MsoDate, div.MsoDate
{mso-style-link:"日期 Char";
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:5.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
a:link, span.MsoHyperlink
{mso-style-name:"超链接\,超级链接";
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{color:purple;
text-decoration:underline;}
p
{mso-style-name:"普通\(网站\)\,普通 \(Web\)\,普通 \(Web\)1\,普通 \(Web\)2\,普通 \(Web\)3";
margin-right:0cm;
margin-left:0cm;
font-size:12.0pt;
font-family:;}
pre
{mso-style-name:"HTML 预设格式\,HTML 预先格式化\,HTML 预先格式化1\,HTML 预先格式化2\,HTML 预先格式化3";
mso-style-link:"HTML 预设格式 Char\,HTML 预先格式化 Char\,HTML 预先格式化1 Char\,HTML 预先格式化2 Char\,HTML 预先格式化3 Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:;}
tt
{font-family:;}
p.MsoCommentSubject, li.MsoCommentSubject, div.MsoCommentSubject
{mso-style-link:"批注主题 Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.5pt;
font-family:;
font-weight:bold;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-link:"批注框文本 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:9.0pt;
font-family:;}
p.1, li.1, div.1
{mso-style-name:1;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.a, li.a, div.a
{mso-style-name:;
mso-style-link:"代码程序 Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:;}
span.Char
{mso-style-name:"代码程序 Char";
mso-style-link:;
font-family:;}
p.a0, li.a0, div.a0
{mso-style-name:;
mso-style-link:"图说明 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
span.Char0
{mso-style-name:"图说明 Char";
mso-style-link:;
font-family:;}
p.0, li.0, div.0
{mso-style-name:0;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:36.0pt;
font-family:;
font-weight:bold;}
p.10, li.10, div.10
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:18.0pt;
font-family:;
font-weight:bold;}
p.11, li.11, div.11
{mso-style-name:1;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.a1, li.a1, div.a1
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.3CharChar, li.3CharChar, div.3CharChar
{mso-style-name:"图中文字3 Char Char";
mso-style-link:"图中文字3 Char Char Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
span.3CharCharChar
{mso-style-name:"图中文字3 Char Char Char";
mso-style-link:"图中文字3 Char Char";
font-family:;}
p.post, li.post, div.post
{mso-style-name:post;
margin:0cm;
margin-bottom:.0001pt;
text-align:right;
line-height:11.0pt;
font-size:10.5pt;
font-family:;}
p.3, li.3, div.3
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.3CharChar1CharCharChar
{mso-style-name:"图中文字3 Char Char1 Char Char Char";
font-family:;}
span.3CharChar1CharChar
{mso-style-name:"图中文字3 Char Char1 Char Char";
font-family:;}
p.5Char, li.5Char, div.5Char
{mso-style-name:"图中文字5号 Char";
mso-style-link:"图中文字5号 Char Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
span.5CharChar
{mso-style-name:"图中文字5号 Char Char";
mso-style-link:"图中文字5号 Char";
font-family:;}
p.5CharChar0, li.5CharChar0, div.5CharChar0
{mso-style-name:"图中文字小5号 Char Char";
mso-style-link:"图中文字小5号 Char Char Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
span.5CharCharChar
{mso-style-name:"图中文字小5号 Char Char Char";
mso-style-link:"图中文字小5号 Char Char";
font-family:;}
p.5Char0, li.5Char0, div.5Char0
{mso-style-name:"图中文字小5号 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.5, li.5, div.5
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
layout-grid-mode:char;
font-size:9.0pt;
font-family:;}
p.2, li.2, div.2
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:;}
p.20, li.20, div.20
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.21, li.21, div.21
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.3CharCharCharCharChar, li.3CharCharCharCharChar, div.3CharCharCharCharChar
{mso-style-name:"图中文字3 Char Char Char Char Char";
mso-style-link:"图中文字3 Char Char Char Char Char Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
span.3CharCharCharCharCharChar
{mso-style-name:"图中文字3 Char Char Char Char Char Char";
mso-style-link:"图中文字3 Char Char Char Char Char";
font-family:;}
p.a2, li.a2, div.a2
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.110, li.110, div.110
{mso-style-name:"样式 标题 1 + 居中1";
margin-right:0cm;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
span.1Char
{mso-style-name:"标题 1 Char";
mso-style-link:"标题 1";
font-weight:bold;}
p.22, li.22, div.22
{mso-style-name:"样式 列表 2 + 居中";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.23, li.23, div.23
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.50, li.50, div.50
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.111, li.111, div.111
{mso-style-name:11;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.12, li.12, div.12
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:;}
p.13, li.13, div.13
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.01, li.01, div.01
{mso-style-name:01;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:36.0pt;
font-family:;
font-weight:bold;}
p.112, li.112, div.112
{mso-style-name:11;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:18.0pt;
font-family:;
font-weight:bold;}
p.113, li.113, div.113
{mso-style-name:11;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.14, li.14, div.14
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.3Char1, li.3Char1, div.3Char1
{mso-style-name:"图中文字3 Char1";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
p.post1, li.post1, div.post1
{mso-style-name:post1;
margin:0cm;
margin-bottom:.0001pt;
text-align:right;
line-height:11.0pt;
font-size:10.5pt;
font-family:;}
p.31, li.31, div.31
{mso-style-name:31;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.5Char1, li.5Char1, div.5Char1
{mso-style-name:"图中文字5号 Char1";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.5CharChar1, li.5CharChar1, div.5CharChar1
{mso-style-name:"图中文字小5号 Char Char1";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.5Char10, li.5Char10, div.5Char10
{mso-style-name:"图中文字小5号 Char1";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.51, li.51, div.51
{mso-style-name:51;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.120, li.120, div.120
{mso-style-name:12;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.02, li.02, div.02
{mso-style-name:02;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:36.0pt;
font-family:;
font-weight:bold;}
p.121, li.121, div.121
{mso-style-name:12;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:18.0pt;
font-family:;
font-weight:bold;}
p.122, li.122, div.122
{mso-style-name:12;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.3Char2, li.3Char2, div.3Char2
{mso-style-name:"图中文字3 Char2";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
p.post2, li.post2, div.post2
{mso-style-name:post2;
margin:0cm;
margin-bottom:.0001pt;
text-align:right;
line-height:11.0pt;
font-size:10.5pt;
font-family:;}
p.32, li.32, div.32
{mso-style-name:32;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.5Char2, li.5Char2, div.5Char2
{mso-style-name:"图中文字小5号 Char2";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.52, li.52, div.52
{mso-style-name:52;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.3CharCharCharChar, li.3CharCharCharChar, div.3CharCharCharChar
{mso-style-name:"图中文字3 Char Char Char Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
p.130, li.130, div.130
{mso-style-name:13;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.30, li.30, div.30
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:;}
p.03, li.03, div.03
{mso-style-name:03;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:36.0pt;
font-family:;
font-weight:bold;}
p.131, li.131, div.131
{mso-style-name:13;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:18.0pt;
font-family:;
font-weight:bold;}
p.132, li.132, div.132
{mso-style-name:13;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.33, li.33, div.33
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.3Char3, li.3Char3, div.3Char3
{mso-style-name:"图中文字3 Char3";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
p.post3, li.post3, div.post3
{mso-style-name:post3;
margin:0cm;
margin-bottom:.0001pt;
text-align:right;
line-height:11.0pt;
font-size:10.5pt;
font-family:;}
p.330, li.330, div.330
{mso-style-name:33;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.5Char20, li.5Char20, div.5Char20
{mso-style-name:"图中文字5号 Char2";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.5CharChar2, li.5CharChar2, div.5CharChar2
{mso-style-name:"图中文字小5号 Char Char2";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.5Char3, li.5Char3, div.5Char3
{mso-style-name:"图中文字小5号 Char3";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.53, li.53, div.53
{mso-style-name:53;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.3Char, li.3Char, div.3Char
{mso-style-name:"图中文字3 Char";
mso-style-link:"图中文字3 Char Char5";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
span.3CharChar5
{mso-style-name:"图中文字3 Char Char5";
mso-style-link:"图中文字3 Char";
font-family:;}
p.54, li.54, div.54
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
line-height:9.0pt;
text-autospace:ideograph-numeric;
font-size:9.0pt;
font-family:;}
p.24, li.24, div.24
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.15, li.15, div.15
{mso-style-name:"样式 标题 1 + 居中";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.25, li.25, div.25
{mso-style-name:"样式 标题 2 + 行距\: 单倍行距";
margin-top:13.0pt;
margin-right:0cm;
margin-bottom:13.0pt;
margin-left:28.9pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-28.9pt;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
span.2Char
{mso-style-name:"标题 2 Char";
mso-style-link:"标题 2";
font-family:"Arial","sans-serif";
font-weight:bold;}
p.34, li.34, div.34
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.35, li.35, div.35
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.4, li.4, div.4
{mso-style-name:4;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.40, li.40, div.40
{mso-style-name:4;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.41, li.41, div.41
{mso-style-name:4;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.55, li.55, div.55
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.56, li.56, div.56
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.57, li.57, div.57
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.6, li.6, div.6
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.60, li.60, div.60
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.61, li.61, div.61
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.7, li.7, div.7
{mso-style-name:7;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.70, li.70, div.70
{mso-style-name:7;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.71, li.71, div.71
{mso-style-name:7;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.8, li.8, div.8
{mso-style-name:8;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.9, li.9, div.9
{mso-style-name:9;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.90, li.90, div.90
{mso-style-name:9;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.100, li.100, div.100
{mso-style-name:10;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.101, li.101, div.101
{mso-style-name:10;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.114, li.114, div.114
{mso-style-name:11;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.115, li.115, div.115
{mso-style-name:11;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.116, li.116, div.116
{mso-style-name:11;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.123, li.123, div.123
{mso-style-name:12;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.124, li.124, div.124
{mso-style-name:12;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.133, li.133, div.133
{mso-style-name:13;
mso-style-link:"图说明13 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
span.13Char
{mso-style-name:"图说明13 Char";
mso-style-link:13;
font-family:;}
p.134, li.134, div.134
{mso-style-name:13;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.26, li.26, div.26
{mso-style-name:2;
margin-top:13.0pt;
margin-right:0cm;
margin-bottom:13.0pt;
margin-left:0cm;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
p.36, li.36, div.36
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:14.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
span.3Char0
{mso-style-name:"标题 3 Char";
mso-style-link:"标题 3";
font-family:"Arial","sans-serif";
font-weight:bold;}
p.16, li.16, div.16
{mso-style-name:1;
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.17, li.17, div.17
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.42, li.42, div.42
{mso-style-name:4;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:12.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
span.4Char
{mso-style-name:"标题 4 Char";
mso-style-link:"标题 4";
font-family:"Arial","sans-serif";
font-weight:bold;}
p.a3, li.a3, div.a3
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.27, li.27, div.27
{mso-style-name:2;
margin-top:13.0pt;
margin-right:0cm;
margin-bottom:13.0pt;
margin-left:28.8pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-28.8pt;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
p.a4, li.a4, div.a4
{mso-style-name:;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.18, li.18, div.18
{mso-style-name:1;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.19, li.19, div.19
{mso-style-name:1;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.25pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.25pt;
font-size:10.5pt;
font-family:;}
p.1a, li.1a, div.1a
{mso-style-name:1;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.25pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.25pt;
font-size:10.5pt;
font-family:;}
p.37, li.37, div.37
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.62, li.62, div.62
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
layout-grid-mode:char;
font-size:7.5pt;
font-family:;}
p.a5, li.a5, div.a5
{mso-style-name:;
mso-style-link:"正文代码 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char1
{mso-style-name:"正文代码 Char";
mso-style-link:;
font-family:;}
p.43, li.43, div.43
{mso-style-name:"样式 标题 4 +";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:12.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
p.140, li.140, div.140
{mso-style-name:14;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.25pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.25pt;
font-size:10.5pt;
font-family:;}
p.141, li.141, div.141
{mso-style-name:14;
mso-style-link:"图说明14 Char";
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.25pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.25pt;
font-size:10.5pt;
font-family:;}
span.14Char
{mso-style-name:"图说明14 Char";
mso-style-link:14;
font-family:;}
p.a6, li.a6, div.a6
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.a7, li.a7, div.a7
{mso-style-name:"样式 正文 +";
mso-style-link:"样式 正文 + Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char2
{mso-style-name:"样式 正文 + Char";
mso-style-link:"样式 正文 +";
font-family:"Times New Roman","serif";}
p.a8, li.a8, div.a8
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.a9, li.a9, div.a9
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.aa, li.aa, div.aa
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.ab, li.ab, div.ab
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.ac, li.ac, div.ac
{mso-style-name:;
margin-top:0cm;
margin-right:21.0pt;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
border:none;
padding:0cm;
font-size:9.0pt;
font-family:;}
p.125, li.125, div.125
{mso-style-name:"样式 标题 1 + 居中2";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.ad, li.ad, div.ad
{mso-style-name:"样式 题注 + 宋体 五号 居中";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.1b, li.1b, div.1b
{mso-style-name:1;
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
line-height:240%;
page-break-after:avoid;
font-size:16.0pt;
font-family:;
font-weight:bold;}
p.38, li.38, div.38
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:12.0pt;
font-family:;}
p.63, li.63, div.63
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:7.5pt;
font-family:;}
p.64, li.64, div.64
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
line-height:10.0pt;
layout-grid-mode:char;
font-size:7.5pt;
font-family:;}
p.65, li.65, div.65
{mso-style-name:6;
mso-style-link:"图中文字6号 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:10.0pt;
layout-grid-mode:char;
font-size:7.5pt;
font-family:;}
span.6Char
{mso-style-name:"图中文字6号 Char";
mso-style-link:6;
font-family:;}
p.ae, li.ae, div.ae
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.28, li.28, div.28
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.af, li.af, div.af
{mso-style-name:;
margin-top:6.0pt;
margin-right:0cm;
margin-bottom:0cm;
margin-left:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:14.0pt;
font-family:;}
p.1c, li.1c, div.1c
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:16.0pt;
font-family:;}
p.af0, li.af0, div.af0
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.af1, li.af1, div.af1
{mso-style-name:"样式 题注 + 居中";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.ListTitle, li.ListTitle, div.ListTitle
{mso-style-name:ListTitle;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.FigureTitle, li.FigureTitle, div.FigureTitle
{mso-style-name:FigureTitle;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.TableTitle, li.TableTitle, div.TableTitle
{mso-style-name:TableTitle;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.ProgramTitle, li.ProgramTitle, div.ProgramTitle
{mso-style-name:ProgramTitle;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.RightText, li.RightText, div.RightText
{mso-style-name:RightText;
margin-top:0cm;
margin-right:21.0pt;
margin-bottom:0cm;
margin-left:42.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
border:none;
padding:0cm;
font-size:9.0pt;
font-family:;}
p.af2, li.af2, div.af2
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:9.0pt;
font-family:;}
p.af3, li.af3, div.af3
{mso-style-name:;
mso-style-link:"关键词 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char3
{mso-style-name:"关键词 Char";
mso-style-link:;
font-family:;}
p.af4, li.af4, div.af4
{mso-style-name:;
mso-style-link:"文件名 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char4
{mso-style-name:"文件名 Char";
mso-style-link:;
font-family:;}
p.af5, li.af5, div.af5
{mso-style-name:;
mso-style-link:"选项 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char5
{mso-style-name:"选项 Char";
mso-style-link:;
font-family:;}
p.af6, li.af6, div.af6
{mso-style-name:;
mso-style-link:"命令行 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char6
{mso-style-name:"命令行 Char";
mso-style-link:;
font-family:;}
p.af7, li.af7, div.af7
{mso-style-name:;
mso-style-link:"函数名 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char7
{mso-style-name:"函数名 Char";
mso-style-link:;
font-family:;}
p.af8, li.af8, div.af8
{mso-style-name:;
mso-style-link:"寄存器名 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char8
{mso-style-name:"寄存器名 Char";
mso-style-link:;
font-family:"Times New Roman","serif";}
p.af9, li.af9, div.af9
{mso-style-name:;
mso-style-link:"变量名 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char9
{mso-style-name:"变量名 Char";
mso-style-link:;
font-family:;}
p.58, li.58, div.58
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.59, li.59, div.59
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
layout-grid-mode:char;
font-size:9.0pt;
font-family:;}
p.926, li.926, div.926
{mso-style-name:"样式 代码程序 + 左侧\: 9\.26 厘米";
margin:0cm;
margin-bottom:.0001pt;
layout-grid-mode:char;
font-size:10.0pt;
font-family:;}
span.5Char4
{mso-style-name:"标题 5 Char";
mso-style-link:"标题 5";
font-weight:bold;}
span.6Char0
{mso-style-name:"标题 6 Char";
mso-style-link:"标题 6";
font-family:"Arial","sans-serif";
font-weight:bold;}
span.7Char
{mso-style-name:"标题 7 Char";
mso-style-link:"标题 7";
font-weight:bold;}
span.8Char
{mso-style-name:"标题 8 Char";
mso-style-link:"标题 8";
font-family:"Arial","sans-serif";}
span.9Char
{mso-style-name:"标题 9 Char";
mso-style-link:"标题 9";
font-family:"Arial","sans-serif";}
span.Chara
{mso-style-name:"脚注文本 Char";
mso-style-link:;
font-family:;}
span.Charb
{mso-style-name:"批注文字 Char";
mso-style-link:;
font-family:;}
span.Charc
{mso-style-name:"页眉 Char";
mso-style-link:;
font-family:;}
span.Chard
{mso-style-name:"页脚 Char";
mso-style-link:;
font-family:;}
span.Chare
{mso-style-name:"日期 Char";
mso-style-link:;
font-family:;}
span.HTMLChar
{mso-style-name:"HTML 预设格式 Char\,HTML 预先格式化 Char\,HTML 预先格式化1 Char\,HTML 预先格式化2 Char\,HTML 预先格式化3 Char";
mso-style-link:"HTML 预设格式\,HTML 预先格式化\,HTML 预先格式化1\,HTML 预先格式化2\,HTML 预先格式化3";
font-family:;}
span.Charf
{mso-style-name:"批注主题 Char";
mso-style-link:;
font-family:;
font-weight:bold;}
span.Charf0
{mso-style-name:"批注框文本 Char";
mso-style-link:;
font-family:;}
span.3CharChar1
{mso-style-name:"图中文字3 Char Char1";
font-family:;}
span.3CharChar1Char
{mso-style-name:"图中文字3 Char Char1 Char";
font-family:;}
span.3CharChar11
{mso-style-name:"图中文字3 Char Char11";
font-family:;}
span.5CharCharChar0
{mso-style-name:"图中文字5号 Char Char Char";
font-family:;}
span.5CharCharCharChar
{mso-style-name:"图中文字小5号 Char Char Char Char";
font-family:;}
.MsoChpDefault
{font-size:10.0pt;}
/* Page Definitions */
@page WordSection1
{size:595.3pt 841.9pt;
margin:72.0pt 54.0pt 72.0pt 54.0pt;
layout-grid:15.6pt;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
ol
{margin-bottom:0cm;}
ul
{margin-bottom:0cm;}
-->
</style>
</head>
<body lang=ZH-CN link=blue vlink=purple style='text-justify-trim:punctuation'>
<div class=WordSection1 style='layout-grid:15.6pt'>
<p class=ab><a name="_Toc53320600"><span style='font-family:黑体'>程序</span><span
lang=EN-US>7-1 linux/init/main.c</span></a></p>
<div class=a align=center style='text-align:center'><span lang=EN-US>
<hr size=4 width="100%" align=center>
</span></div>
<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>1</span></u> <b><i>/*</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>2</span></u> <b><i>&nbsp;*&nbsp;
linux/init/main.c</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>3</span></u> <b><i>&nbsp;*</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>4</span></u> <b><i>&nbsp;*&nbsp;
(C) 1991&nbsp; Linus Torvalds</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>5</span></u> <b><i>&nbsp;*/</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>6</span></u> </span></p>
<p class=a><span lang=EN-US style='color:blue'>&nbsp;&nbsp; &nbsp;</span><span
lang=EN-US>// </span>定义宏“<u><span lang=EN-US>__</span></u><span lang=EN-US>LIBRARY<u>__</u></span>”是为了包括定义在<span
lang=EN-US>unistd.h</span>中的内嵌汇编代码等信息。</p>
<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>7</span></u>
#define <u><span style='color:blue'>__LIBRARY__</span></u></span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // *.h</span>头文件所在的默认目录是<span
lang=EN-US>include/</span>,则在代码中就不用明确指明其位置。如果不是<span lang=EN-US>UNIX</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>标准头文件,则需要指明所在的目录,并用双引号括住。<span
lang=EN-US>unistd.h</span>是标准符号常数与类型文件。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>其中定义了各种符号常数和类型,并声明了各种函数。如果还定义了符号<span
lang=EN-US>__LIBRARY__</span>,则还会</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>包含系统调用号和内嵌汇编代码<span
lang=EN-US>syscall0()</span>等。</p>
<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>8</span></u>
#include &lt;unistd.h&gt;</span></p>
<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>9</span></u>
#include &lt;time.h&gt;&nbsp;&nbsp;&nbsp; // </span>时间类型头文件。其中最主要定义了<span
lang=EN-US>tm</span>结构和一些有关时间的函数原形。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>10</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>11</span></u> <b><i>/*</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>12</span></u> <b><i>&nbsp;*
we need this inline - forking from kernel space will result</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>13</span></u> <b><i>&nbsp;*
in NO COPY ON WRITE (!!!), until an execve is executed. This</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>14</span></u> <b><i>&nbsp;*
is no problem, but for the stack. This is handled by not letting</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>15</span></u> <b><i>&nbsp;*
main() use the stack at all after fork(). Thus, no function</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>16</span></u> <b><i>&nbsp;*
calls - which means inline code for fork too, as otherwise we</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>17</span></u> <b><i>&nbsp;*
would use the stack upon exit from 'fork()'.</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>18</span></u> <b><i>&nbsp;*</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>19</span></u> <b><i>&nbsp;*
Actually only pause and fork are needed inline, so that there</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>20</span></u> <b><i>&nbsp;*
won't be any messing with the stack from main(), but we define</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>21</span></u> <b><i>&nbsp;*
some others too.</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>22</span></u> <b><i>&nbsp;*/</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>我们需要下面这些内嵌语句 <span
lang=EN-US>- </span>从内核空间创建进程将导致没有写时复制<span lang=EN-US>(COPY ON WRITE)!!!</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>直到执行一个<span
lang=EN-US>execve</span>调用。这对堆栈可能带来问题。处理方法是在<span lang=EN-US>fork()</span>调用后不让<span
lang=EN-US>main()</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>使用任何堆栈。因此就不能有函数调用<span
lang=EN-US> - </span>这意味着<span lang=EN-US>fork</span>也要使用内嵌的代码,否则我们在从</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * fork()</span>退出时就要使用堆栈了。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; *</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>实际上只有<span
lang=EN-US>pause</span><span lang=EN-US>fork</span>需要使用内嵌方式,以保证从<span
lang=EN-US>main()</span>中不会弄乱堆栈,但是我们同</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>时还定义了其他一些函数。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // Linux</span>在内核空间创建进程时不使用写时复制技术(<span
lang=EN-US>Copy on write</span>)。<span lang=EN-US>main()</span>在移动到用户</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>模式(到任务<span
lang=EN-US>0</span>)后执行内嵌方式的<span lang=EN-US>fork()</span><span lang=EN-US>pause()</span>,因此可保证不使用任务<span
lang=EN-US>0</span>的用户栈。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>在执行<span lang=EN-US>moveto_user_mode()</span>之后,本程序<span
lang=EN-US>main()</span>就以任务<span lang=EN-US>0</span>的身份在运行了。而任务<span
lang=EN-US>0</span>是所</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>有将创建子进程的父进程。当它创建一个子进程时(<span
lang=EN-US>init</span>进程),由于任务<span lang=EN-US>1</span>代码属于内核</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>空间,因此没有使用写时复制功能。此时任务<span
lang=EN-US>0</span>的用户栈就是任务<span lang=EN-US>1</span>的用户栈,即它们共同</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>使用一个栈空间。因此希望在<span
lang=EN-US>main.c</span>运行在任务<span lang=EN-US>0</span>的环境下时不要有对堆栈的任何操作,以</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>免弄乱堆栈。而在再次执行<span
lang=EN-US>fork()</span>并执行过<span lang=EN-US>execve()</span>函数后,被加载程序已不属于内核空间,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>因此可以使用写时复制技术了。请参见<span
lang=EN-US>5.3</span>节“<span lang=EN-US>Linux</span>内核使用内存的方法”内容。</p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面<span lang=EN-US>_syscall0()</span><span
lang=EN-US>unistd.h</span>中的内嵌宏代码。以嵌入汇编的形式调用<span lang=EN-US>Linux</span>的系统调用中断</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // 0x80</span>。该中断是所有系统调用的入口。该条语句实际上是<span
lang=EN-US>int fork()</span>创建进程系统调用。可展</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>开看之就会立刻明白。<span
lang=EN-US>syscall0</span>名称中最后的<span lang=EN-US>0</span>表示无参数,<span
lang=EN-US>1</span>表示<span lang=EN-US>1</span>个参数。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>参见<span lang=EN-US>include/unistd.h</span><span
lang=EN-US>133</span>行。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>23</span></u>
static inline <u><span style='color:blue'>_syscall0</span></u>(int,<u><span
style='color:blue'>fork</span></u>)</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp; &nbsp;// int pause()</span>系统调用:暂停进程的执行,直到收到一个信号。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>24</span></u>
static inline <u><span style='color:blue'>_syscall0</span></u>(int,<u><span
style='color:blue'>pause</span></u>)</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // int setup(void * BIOS)</span>系统调用,仅用于<span
lang=EN-US>linux</span>初始化(仅在这个程序中被调用)。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>25</span></u>
static inline <u><span style='color:blue'>_syscall1</span></u>(int,setup,void
*,BIOS)</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // int sync()</span>系统调用:更新文件系统。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>26</span></u>
static inline <u><span style='color:blue'>_syscall0</span></u>(int,<u><span
style='color:blue'>sync</span></u>)</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>27</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>28</span></u>
#include &lt;linux/tty.h&gt;&nbsp;&nbsp;&nbsp; // tty</span>头文件,定义了有关<span
lang=EN-US>tty_io</span>,串行通信方面的参数、常数。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>29</span></u>
#include &lt;linux/sched.h&gt;&nbsp; // </span>调度程序头文件,定义了任务结构<span lang=EN-US>task_struct</span>、第<span
lang=EN-US>1</span>个初始任务</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>的数据。还有一些以宏的形式定义的有关描述符参数设置和获取的</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>嵌入式汇编函数程序。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>30</span></u>
#include &lt;linux/head.h&gt;&nbsp;&nbsp; // head</span>头文件,定义了段描述符的简单结构,和几个选择符常量。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>31</span></u>
#include &lt;asm/system.h&gt;&nbsp;&nbsp; // </span>系统头文件。以宏形式定义了许多有关设置或修改描述符<span
lang=EN-US>/</span>中断门</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>等的嵌入式汇编子程序。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>32</span></u>
#include &lt;asm/io.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // io</span>头文件。以宏的嵌入汇编程序形式定义对<span
lang=EN-US>io</span>端口操作的函数。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>33</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>34</span></u>
#include &lt;stddef.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>标准定义头文件。定义了<span
lang=EN-US>NULL, offsetof(TYPE, MEMBER)</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>35</span></u>
#include &lt;stdarg.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>标准参数头文件。以宏的形式定义变量参数列表。主要说明了<span
lang=EN-US>-</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>类型<span lang=EN-US>(va_list)</span>和三个宏<span lang=EN-US>(va_start,
va_arg</span><span lang=EN-US>va_end)</span><span lang=EN-US>vsprintf</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// vprintf</span><span lang=EN-US>vfprintf</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>36</span></u>
#include &lt;unistd.h&gt;</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>37</span></u>
#include &lt;fcntl.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>文件控制头文件。用于文件及其描述符的操作控制常数符号的定义。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>38</span></u>
#include &lt;sys/types.h&gt;&nbsp;&nbsp;&nbsp; // </span>类型头文件。定义了基本的系统数据类型。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>39</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>40</span></u>
#include &lt;linux/fs.h&gt;&nbsp;&nbsp;&nbsp;&nbsp; // </span>文件系统头文件。定义文件表结构(<span
lang=EN-US>file,buffer_head,m_inode</span>等)。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>41</span></u> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>其中有定义:<span lang=EN-US>extern int ROOT_DEV</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>42</span></u>
#include &lt;string.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>字符串头文件。主要定义了一些有关内存或字符串操作的嵌入函数。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>43</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>44</span></u>
static char <u><span style='color:blue'>printbuf</span></u>[1024];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>静态字符串数组,用作内核显示信息的缓存。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>45</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>46</span></u>
extern char *<u><span style='color:blue'>strcpy</span></u>();</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>47</span></u>
extern int <u><span style='color:blue'>vsprintf</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>送格式化输出到一字符串中(<span lang=EN-US>vsprintf.c</span><span
lang=EN-US>92</span>行)。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>48</span></u>
extern void <u><span style='color:blue'>init</span></u>(void);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>函数原形,初始化(本程序<span lang=EN-US>168</span>行)。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>49</span></u>
extern void <u><span style='color:blue'>blk_dev_init</span></u>(void);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>块设备初始化子程序(<span lang=EN-US>blk_drv/ll_rw_blk.c,157</span>行)</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>50</span></u>
extern void <u><span style='color:blue'>chr_dev_init</span></u>(void);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>字符设备初始化(<span lang=EN-US>chr_drv/tty_io.c, 347</span>行)</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>51</span></u>
extern void <u><span style='color:blue'>hd_init</span></u>(void);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>硬盘初始化程序(<span lang=EN-US>blk_drv/hd.c,
343</span>行)</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>52</span></u>
extern void <u><span style='color:blue'>floppy_init</span></u>(void);&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>软驱初始化程序(<span lang=EN-US>blk_drv/floppy.c,
457</span>行)</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>53</span></u>
extern void <u><span style='color:blue'>mem_init</span></u>(long start, long <u><span
style='color:blue'>end</span></u>);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// </span>内存管理初始化(<span
lang=EN-US>mm/memory.c, 399</span>行)</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>54</span></u>
extern long <u><span style='color:blue'>rd_init</span></u>(long mem_start, int
length); // </span>虚拟盘初始化<span lang=EN-US>(blk_drv/ramdisk.c,52)</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>55</span></u>
extern long <u><span style='color:blue'>kernel_mktime</span></u>(struct <u><span
style='color:blue'>tm</span></u> * <u><span style='color:blue'>tm</span></u>);&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>计算系统开机启动时间(秒)。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>56</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>内核专用<span lang=EN-US>sprintf()</span>函数。该函数用于产生格式化信息并输出到指定缓冲区<span
lang=EN-US>str</span>中。参数<span lang=EN-US>'*fmt'</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>指定输出将采用的格式,参见标准<span
lang=EN-US>C</span>语言书籍。该子程序正好是<span lang=EN-US>vsprintf</span>如何使用的一个简单</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>例子。函数使用<span
lang=EN-US>vsprintf()</span>将格式化字符串放入<span lang=EN-US>str</span>缓冲区,参见第<span
lang=EN-US>179</span>行上的<span lang=EN-US>printf()</span>函数。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>57</span></u>
static int <u><span style='color:blue'>sprintf</span></u>(char * <u><span
style='color:blue'>str</span></u>, const char *fmt, ...)</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>58</span></u> {</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>59</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>va_list</span></u> args;</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>60</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int i;</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>61</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>62</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>va_start</span></u>(args, fmt);</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>63</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
i = <u><span style='color:blue'>vsprintf</span></u>(<u><span style='color:blue'>str</span></u>,
fmt, args);</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>64</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>va_end</span></u>(args);</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>65</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return i;</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>66</span></u> }</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>67</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>68</span></u> <b><i>/*</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>69</span></u> <b><i>&nbsp;*
This is set up by the setup-routine at boot-time</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>70</span></u> <b><i>&nbsp;*/</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>以下这些数据是在内核引导期间由<span
lang=EN-US>setup.s</span>程序设置的。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面三行分别将指定的线性地址强行转换为给定数据类型的指针,并获取指针所指内容。由于</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>内核代码段被映射到从物理地址零开始的地方,因此这些线性地址正好也是对应的物理地址。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>这些指定地址处内存值的含义请参见第<span
lang=EN-US>6</span>章的表<span lang=EN-US>6-2</span><span lang=EN-US>setup</span>程序读取并保存的参数)。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // drive_info</span>结构请参见下面第<span
lang=EN-US>125</span>行。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>71</span></u>
#define <u><span style='color:blue'>EXT_MEM_K</span></u> (*(unsigned short
*)0x90002)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 1MB</span>以后的扩展内存大小(<span
lang=EN-US>KB</span>)。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>72</span></u>
#define <u><span style='color:blue'>CON_ROWS</span></u> ((*(unsigned short
*)0x9000e) &amp; 0xff)&nbsp; // </span>选定的控制台屏幕行、列数。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>73</span></u>
#define <u><span style='color:blue'>CON_COLS</span></u> (((*(unsigned short
*)0x9000e) &amp; 0xff00) &gt;&gt; 8)</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>74</span></u>
#define <u><span style='color:blue'>DRIVE_INFO</span></u> (*(struct <u><span
style='color:blue'>drive_info</span></u> *)0x90080)&nbsp; // </span>硬盘参数表<span
lang=EN-US>32</span>字节内容。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>75</span></u>
#define <u><span style='color:blue'>ORIG_ROOT_DEV</span></u> (*(unsigned short
*)0x901FC)&nbsp; // </span>根文件系统所在设备号。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>76</span></u>
#define <u><span style='color:blue'>ORIG_SWAP_DEV</span></u> (*(unsigned short
*)0x901FA)&nbsp; // </span>交换文件所在设备号。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>77</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>78</span></u> <b><i>/*</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>79</span></u> <b><i>&nbsp;*
Yeah, yeah, it's ugly, but I cannot find how to do this correctly</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>80</span></u> <b><i>&nbsp;*
and this seems to work. I anybody has more info on the real-time</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>81</span></u> <b><i>&nbsp;*
clock I'd be interested. Most of this was trial and error, and some</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>82</span></u> <b><i>&nbsp;*
bios-listing reading. Urghh.</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>83</span></u> <b><i>&nbsp;*/</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>是啊,是啊,下面这段程序很差劲,但我不知道如何正确地实现,而且好象</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>它还能运行。如果有关于实时时钟更多的资料,那我很感兴趣。这些都是试</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>探出来的,另外还看了一些<span
lang=EN-US>bios</span>程序,呵!</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>84</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>这段宏读取<span lang=EN-US>CMOS</span>实时时钟信息。<span
lang=EN-US>outb_p</span><span lang=EN-US>inb_p</span><span lang=EN-US>include/asm/io.h</span>中定义的端口输入输出宏。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>85</span></u>
#define <u><span style='color:blue'>CMOS_READ</span></u>(addr) ({ \</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>86</span></u> <u><span
style='color:blue'>outb_p</span></u>(0x80|addr,0x70); \&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// 0x70</span>是写地址端口号,<span lang=EN-US>0x80|addr</span>是要读取的<span lang=EN-US>CMOS</span>内存地址。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>87</span></u> <u><span
style='color:blue'>inb_p</span></u>(0x71); \&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// 0x71</span>是读数据端口号。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>88</span></u> })</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>89</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>定义宏。将<span lang=EN-US>BCD</span>码转换成二进制数值。<span
lang=EN-US>BCD</span>码利用半个字节(<span lang=EN-US>4</span>比特)表示一个<span lang=EN-US>10</span>进制数,因此</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>一个字节表示<span
lang=EN-US>2</span><span lang=EN-US>10</span>进制数。<span lang=EN-US>(val)&amp;15</span><span
lang=EN-US>BCD</span>表示的<span lang=EN-US>10</span>进制个位数,而 <span lang=EN-US>(val)&gt;&gt;4</span><span
lang=EN-US>BCD</span>表示</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span><span lang=EN-US>10</span>进制十位数,再乘以<span
lang=EN-US>10</span>。因此最后两者相加就是一个字节<span lang=EN-US>BCD</span>码的实际二进制数值。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>90</span></u>
#define <u><span style='color:blue'>BCD_TO_BIN</span></u>(val)
((val)=((val)&amp;15) + ((val)&gt;&gt;4)*10)</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>91</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp; &nbsp;&nbsp;// </span>该函数取<span lang=EN-US>CMOS</span>实时钟信息作为开机时间,并保存到全局变量<span
lang=EN-US>startup_time(</span><span lang=EN-US>)</span>中。参见后面</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // CMOS</span>内存列表说明。其中调用的函数<span
lang=EN-US>kernel_mktime()</span>用于计算从<span
lang=EN-US>1970</span><span lang=EN-US>1</span><span lang=EN-US>1</span><span
lang=EN-US>0</span>时起到</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>开机当日经过的秒数,作为开机时间(<span
lang=EN-US>kernel/mktime.c 41</span>行)。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>92</span></u>
static void <u><span style='color:blue'>time_init</span></u>(void)</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>93</span></u> {</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>94</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
struct <u><span style='color:blue'>tm</span></u> <u><span style='color:blue'>time</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>时间结构<span lang=EN-US>tm</span>定义在<span lang=EN-US>include/time.h</span>中。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>95</span></u> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // CMOS</span>的访问速度很慢。为了减小时间误差,在读取了下面循环中所有数值后,若此时<span
lang=EN-US>CMOS</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>秒值发生了变化,那么就重新读取所有值。这样内核就能把与<span
lang=EN-US>CMOS</span>时间误差控制在<span lang=EN-US>1</span>秒之内。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>96</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
do {</span></p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>97</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>time</span></u>.tm_sec = <u><span style='color:
blue'>CMOS_READ</span></u>(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>当前时间秒值(均是<span
lang=EN-US>BCD</span>码值)。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>98</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>time</span></u>.tm_min = <u><span style='color:
blue'>CMOS_READ</span></u>(2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>当前分钟值。</p>
<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>99</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>time</span></u>.tm_hour = <u><span
style='color:blue'>CMOS_READ</span></u>(4);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>当前小时值。</p>
<p class=a><u><span lang=EN-US style='color:blue'>100</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>time</span></u>.tm_mday = <u><span
style='color:blue'>CMOS_READ</span></u>(7);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>一月中的当天日期。</p>
<p class=a><u><span lang=EN-US style='color:blue'>101</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>time</span></u>.tm_mon = <u><span style='color:
blue'>CMOS_READ</span></u>(8);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>当前月份(<span
lang=EN-US>1—12</span>)。</p>
<p class=a><u><span lang=EN-US style='color:blue'>102</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>time</span></u>.tm_year = <u><span
style='color:blue'>CMOS_READ</span></u>(9);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>当前年份。</p>
<p class=a><u><span lang=EN-US style='color:blue'>103</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } while (<u><span
style='color:blue'>time</span></u>.tm_sec != <u><span style='color:blue'>CMOS_READ</span></u>(0));</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>104</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>BCD_TO_BIN</span></u>(<u><span style='color:blue'>time</span></u>.tm_sec);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>转换成二进制数值。</p>
<p class=a><u><span lang=EN-US style='color:blue'>105</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>BCD_TO_BIN</span></u>(<u><span style='color:blue'>time</span></u>.tm_min);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>106</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>BCD_TO_BIN</span></u>(<u><span style='color:blue'>time</span></u>.tm_hour);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>107</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>BCD_TO_BIN</span></u>(<u><span style='color:blue'>time</span></u>.tm_mday);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>108</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>BCD_TO_BIN</span></u>(<u><span style='color:blue'>time</span></u>.tm_mon);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>109</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>BCD_TO_BIN</span></u>(<u><span style='color:blue'>time</span></u>.tm_year);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>110</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>time</span></u>.tm_mon--; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
tm_mon</span>中月份范围是<span lang=EN-US>0—11</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>111</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>startup_time</span></u> = <u><span style='color:blue'>kernel_mktime</span></u>(&amp;<u><span
style='color:blue'>time</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>计算开机时间。<span
lang=EN-US>kernel/mktime.c 41</span>行。</p>
<p class=a><u><span lang=EN-US style='color:blue'>112</span></u><span
lang=EN-US> }</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>113</span></u><span
lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面定义一些局部变量。</p>
<p class=a><u><span lang=EN-US style='color:blue'>114</span></u><span
lang=EN-US> static long <u><span style='color:blue'>memory_end</span></u> = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>机器具有的物理内存容量(字节数)。</p>
<p class=a><u><span lang=EN-US style='color:blue'>115</span></u><span
lang=EN-US> static long <u><span style='color:blue'>buffer_memory_end</span></u>
= 0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>高速缓冲区末端地址。</p>
<p class=a><u><span lang=EN-US style='color:blue'>116</span></u><span
lang=EN-US> static long <u><span style='color:blue'>main_memory_start</span></u>
= 0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>主内存(将用于分页)开始的位置。</p>
<p class=a><u><span lang=EN-US style='color:blue'>117</span></u><span
lang=EN-US> static char <u><span style='color:blue'>term</span></u>[32];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>终端设置字符串(环境参数)。</p>
<p class=a><u><span lang=EN-US style='color:blue'>118</span></u><span
lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>读取并执行<span lang=EN-US>/etc/rc</span>文件时所使用的命令行参数和环境参数。</p>
<p class=a><u><span lang=EN-US style='color:blue'>119</span></u><span
lang=EN-US> static char * <u><span style='color:blue'>argv_rc</span></u>[] = { <i>&quot;/bin/sh&quot;</i>,
<u><span style='color:blue'>NULL</span></u> };&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//
</span>调用执行程序时参数的字符串数组。</p>
<p class=a><u><span lang=EN-US style='color:blue'>120</span></u><span
lang=EN-US> static char * <u><span style='color:blue'>envp_rc</span></u>[] = { <i>&quot;HOME=/&quot;</i>,
<u><span style='color:blue'>NULL</span></u> ,<u><span style='color:blue'>NULL</span></u>
}; &nbsp;// </span>调用执行程序时的环境字符串数组。</p>
<p class=a><u><span lang=EN-US style='color:blue'>121</span></u><span
lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>运行登录<span lang=EN-US>shell</span>时所使用的命令行参数和环境参数。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span><span lang=EN-US>122</span>行中<span
lang=EN-US>argv[0]</span>中的字符“<span lang=EN-US>-</span>”是传递给<span lang=EN-US>shell</span>程序<span
lang=EN-US>sh</span>的一个标志。通过识别该标志,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // sh</span>程序会作为登录<span
lang=EN-US>shell</span>执行。其执行过程与在<span lang=EN-US>shell</span>提示符下执行<span
lang=EN-US>sh</span>不一样。</p>
<p class=a><u><span lang=EN-US style='color:blue'>122</span></u><span
lang=EN-US> static char * <u><span style='color:blue'>argv</span></u>[] = { <i>&quot;-/bin/sh&quot;</i>,<u><span
style='color:blue'>NULL</span></u> };&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//
</span>同上。</p>
<p class=a><u><span lang=EN-US style='color:blue'>123</span></u><span
lang=EN-US> static char * <u><span style='color:blue'>envp</span></u>[] = { <i>&quot;HOME=/usr/root&quot;</i>,
<u><span style='color:blue'>NULL</span></u>, <u><span style='color:blue'>NULL</span></u>
};</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>124</span></u><span
lang=EN-US> </span></p>
<p class=a><u><span lang=EN-US style='color:blue'>125</span></u><span
lang=EN-US> struct <u><span style='color:blue'>drive_info</span></u> { char
dummy[32]; } <u><span style='color:blue'>drive_info</span></u>;&nbsp;&nbsp;&nbsp;
// </span>用于存放硬盘参数表信息。</p>
<p class=a><u><span lang=EN-US style='color:blue'>126</span></u><span
lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>内核初始化主程序。初始化结束后将以任务<span
lang=EN-US>0</span><span lang=EN-US>idle</span>任务即空闲任务)的身份运行。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>英文注释含义是“这里确实是<span
lang=EN-US>void</span>,没错。在<span lang=EN-US>startup</span>程序<span lang=EN-US>(head.s)</span>中就是这样假设的”。参见</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // head.s</span>程序第<span
lang=EN-US>136</span>行开始的几行代码。</p>
<p class=a><u><span lang=EN-US style='color:blue'>127</span></u><span
lang=EN-US> void <u><span style='color:blue'>main</span></u>(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<b><i>/* This really IS void, no error here. */</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>128</span></u><span
lang=EN-US>
{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<b><i>/* The startup routine assumes (well, ...) this */</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>129</span></u><span
lang=EN-US> <b><i>/*</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>130</span></u><span
lang=EN-US> <b><i>&nbsp;* Interrupts are still disabled. Do necessary setups,
then</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>131</span></u><span
lang=EN-US> <b><i>&nbsp;* enable them</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>132</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>此时中断仍被禁止着,做完必要的设置后就将其开启。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先保存根文件系统设备号和交换文件设备号,并根据<span
lang=EN-US>setup.s</span>程序中获取的信息设置控制台</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>终端屏幕行、列数环境变量<span
lang=EN-US>TERM</span>,并用其设置初始<span lang=EN-US>init</span>进程中执行<span
lang=EN-US>etc/rc</span>文件和<span lang=EN-US>shell</span>程序</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>使用的环境变量,以及复制内存<span
lang=EN-US>0x90080</span>处的硬盘参数表。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>其中<span lang=EN-US>ROOT_DEV
</span>已在前面包含进的<span lang=EN-US>include/linux/fs.h</span>文件第<span lang=EN-US>206</span>行上被声明为<span
lang=EN-US>extern int</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span><span lang=EN-US>SWAP_DEV</span><span
lang=EN-US>include/linux/mm.h</span>文件内也作了相同声明。这里<span lang=EN-US>mm.h</span>文件并没有显式地列在</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>本程序前部,因为前面包含进的<span
lang=EN-US>include/linux/sched.h</span>文件中已经含有它。</p>
<p class=a><u><span lang=EN-US style='color:blue'>133</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>ROOT_DEV</span></u> = <u><span style='color:blue'>ORIG_ROOT_DEV</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// ROOT_DEV</span>定义在<span lang=EN-US>fs/super.c</span><span lang=EN-US>29</span>行。</p>
<p class=a><u><span lang=EN-US style='color:blue'>134</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>SWAP_DEV</span></u> = <u><span style='color:blue'>ORIG_SWAP_DEV</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// SWAP_DEV</span>定义在<span lang=EN-US>mm/swap.c</span><span lang=EN-US>36</span>行。</p>
<p class=a><u><span lang=EN-US style='color:blue'>135</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>sprintf</span></u>(<u><span style='color:blue'>term</span></u>,
<i>&quot;TERM=con%dx%d&quot;</i>, <u><span style='color:blue'>CON_COLS</span></u>,
<u><span style='color:blue'>CON_ROWS</span></u>);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>136</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>envp</span></u>[1] = <u><span style='color:blue'>term</span></u>;
</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>137</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>envp_rc</span></u>[1] = <u><span style='color:blue'>term</span></u>;</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>138</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>drive_info</span></u> = <u><span style='color:blue'>DRIVE_INFO</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>复制内存<span lang=EN-US>0x90080</span>处的硬盘参数表。</p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>接着根据机器物理内存容量设置高速缓冲区和主内存区的位置和范围。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>高速缓存末端地址<span
lang=EN-US style='font-family:Wingdings'>è</span><span lang=EN-US>buffer_memory_end</span>;机器内存容量<span
lang=EN-US style='font-family:Wingdings'>è</span><span lang=EN-US>memory_end</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>主内存开始地址<span
lang=EN-US>&nbsp; </span><span lang=EN-US style='font-family:Wingdings'>è</span><span
lang=EN-US>main_memory_start</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>139</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>memory_end</span></u> = (1&lt;&lt;20) + (<u><span
style='color:blue'>EXT_MEM_K</span></u>&lt;&lt;10); // </span>内存大小<span
lang=EN-US>=1Mb + </span>扩展内存<span lang=EN-US>(k)*1024</span>字节。</p>
<p class=a><u><span lang=EN-US style='color:blue'>140</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>memory_end</span></u> &amp;= 0xfffff000;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>忽略不到<span lang=EN-US>4Kb</span><span lang=EN-US>1</span>页)的内存数。</p>
<p class=a><u><span lang=EN-US style='color:blue'>141</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>memory_end</span></u> &gt; 16*1024*1024)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>如果内存量超过<span lang=EN-US>16Mb</span>,则按<span lang=EN-US>16Mb</span>计。</p>
<p class=a><u><span lang=EN-US style='color:blue'>142</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>memory_end</span></u> = 16*1024*1024;</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>143</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>memory_end</span></u> &gt; 12*1024*1024)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>如果内存<span lang=EN-US>&gt;12Mb</span>,则设置缓冲区末端<span lang=EN-US>=4Mb</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>144</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>buffer_memory_end</span></u> = 4*1024*1024;</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>145</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (<u><span
style='color:blue'>memory_end</span></u> &gt; 6*1024*1024)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>否则若内存<span lang=EN-US>&gt;6Mb</span>,则设置缓冲区末端<span lang=EN-US>=2Mb</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>146</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>buffer_memory_end</span></u> = 2*1024*1024;</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>147</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;else</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>148</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>buffer_memory_end</span></u> = 1*1024*1024; // </span>否则则设置缓冲区末端<span
lang=EN-US>=1Mb</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>149</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>main_memory_start</span></u> = <u><span style='color:blue'>buffer_memory_end</span></u>;&nbsp;
// </span>主内存起始位置 <span lang=EN-US>= </span>缓冲区末端。</p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果在<span lang=EN-US>Makefile</span>文件中定义了内存虚拟盘符号<span
lang=EN-US>RAMDISK</span>,则初始化虚拟盘。此时主内存将减少。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //</span>参见<span lang=EN-US>kernel/blk_drv/ramdisk.c</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>150</span></u><span
lang=EN-US> #ifdef RAMDISK</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>151</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>main_memory_start</span></u> += <u><span style='color:blue'>rd_init</span></u>(<u><span
style='color:blue'>main_memory_start</span></u>, RAMDISK*1024);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>152</span></u><span
lang=EN-US> #endif</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>以下是内核进行所有方面的初始化工作。阅读时最好跟着调用的程序深入进去看,若实在看</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>不下去了,就先放一放,继续看下一个初始化调用<span
lang=EN-US> -- </span>这是经验之谈<span lang=EN-US style='font-family:Wingdings'>J</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>153</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>mem_init</span></u>(<u><span style='color:blue'>main_memory_start</span></u>,<u><span
style='color:blue'>memory_end</span></u>);&nbsp; // </span>主内存区初始化。(<span
lang=EN-US>mm/memory.c</span><span lang=EN-US>399</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>154</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>trap_init</span></u>();&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>陷阱门(硬件中断向量)初始化。(<span lang=EN-US>kernel/traps.c</span><span lang=EN-US>181</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>155</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>blk_dev_init</span></u>();&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>块设备初始化。<span lang=EN-US>&nbsp;&nbsp;&nbsp; </span><span lang=EN-US>blk_drv/ll_rw_blk.c</span><span
lang=EN-US>157</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>156</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>chr_dev_init</span></u>();&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>字符设备初始化。<span lang=EN-US>&nbsp; </span><span lang=EN-US>chr_drv/tty_io.c</span><span
lang=EN-US>347</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>157</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>tty_init</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
tty</span>初始化。<span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
lang=EN-US>chr_drv/tty_io.c</span><span lang=EN-US>406</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>158</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>time_init</span></u>();&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>设置开机启动时间。(见第<span lang=EN-US>92</span>行)</p>
<p class=a><u><span lang=EN-US style='color:blue'>159</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>sched_init</span></u>();&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>调度程序初始化(加载任务<span lang=EN-US>0</span><span lang=EN-US>tr,ldtr</span><span
lang=EN-US>kernel/sched.c</span><span lang=EN-US>385</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>160</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>buffer_init</span></u>(<u><span style='color:blue'>buffer_memory_end</span></u>);
// </span>缓冲管理初始化,建内存链表等。(<span lang=EN-US>fs/buffer.c</span><span lang=EN-US>348</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>161</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>hd_init</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>硬盘初始化。<span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
lang=EN-US>blk_drv/hd.c</span><span lang=EN-US>343</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>162</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>floppy_init</span></u>();&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>软驱初始化。<span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
lang=EN-US>blk_drv/floppy.c</span><span lang=EN-US>457</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>163</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>sti</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>所有初始化工作都做完了,于是开启中断。</p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面过程通过在堆栈中设置的参数,利用中断返回指令启动任务<span
lang=EN-US>0</span>执行。</p>
<p class=a><u><span lang=EN-US style='color:blue'>164</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<u><span
style='color:blue'>move_to_user_mode</span></u>();&nbsp;&nbsp;&nbsp; // </span>移到用户模式下执行。(<span
lang=EN-US>include/asm/system.h</span>,第<span lang=EN-US>1</span>行)</p>
<p class=a><u><span lang=EN-US style='color:blue'>165</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!<u><span
style='color:blue'>fork</span></u>())
{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><i>/* we count on
this going ok */</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>166</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>init</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>在新建的子进程(任务<span lang=EN-US>1</span><span lang=EN-US>init</span>进程)中执行。</p>
<p class=a><u><span lang=EN-US style='color:blue'>167</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面代码开始以任务<span
lang=EN-US>0</span>的身份运行。</p>
<p class=a><u><span lang=EN-US style='color:blue'>168</span></u><span
lang=EN-US> <b><i>/*</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>169</span></u><span
lang=EN-US> <b><i>&nbsp;*&nbsp;&nbsp; NOTE!!&nbsp;&nbsp; For any other task
'pause()' would mean we have to get a</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>170</span></u><span
lang=EN-US> <b><i>&nbsp;* signal to awaken, but task0 is the sole exception
(see 'schedule()')</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>171</span></u><span
lang=EN-US> <b><i>&nbsp;* as task 0 gets activated at every idle moment (when
no other tasks</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>172</span></u><span
lang=EN-US> <b><i>&nbsp;* can run). For task0 'pause()' just means we go check
if some other</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>173</span></u><span
lang=EN-US> <b><i>&nbsp;* task can run, and if not we return here.</i></b></span></p>
<p class=a><u><span lang=EN-US style='color:blue'>174</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /* </span>注意<span lang=EN-US>!! </span>对于任何其他的任务,<span
lang=EN-US>'pause()'</span>将意味着我们必须等待收到一个信号</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>才会返回就绪态,但任务<span
lang=EN-US>0</span><span lang=EN-US>task0</span>)是唯一例外情况(参见<span lang=EN-US>'schedule()'</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>因为任务<span
lang=EN-US>0</span>在任何空闲时间里都会被激活(当没有其他任务在运行时),因此</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>对于任务<span
lang=EN-US>0'pause()'</span>仅意味着我们返回来查看是否有其他任务可以运行,如果</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>没有的话我们就回到这里,一直循环执行<span
lang=EN-US>'pause()'</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // pause()</span>系统调用(<span
lang=EN-US>kernel/sched.c,144</span>)会把任务<span lang=EN-US>0</span>转换成可中断等待状态,再执行调度函数。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>但是调度函数只要发现系统中没有其他任务可以运行时就会切换到任务<span
lang=EN-US>0</span>,而不依赖于任务<span lang=EN-US>0</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>状态。</p>
<p class=a><u><span lang=EN-US style='color:blue'>175</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(;;)</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>176</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
__asm__(<i>&quot;int $0x80&quot;</i>::<i>&quot;a&quot;</i> (<u><span
style='color:blue'>__NR_pause</span></u>):<i>&quot;ax&quot;</i>);&nbsp; // </span>即执行系统调用<span
lang=EN-US>pause()</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>177</span></u><span
lang=EN-US> }</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>178</span></u><span
lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面函数产生格式化信息并输出到标准输出设备<span
lang=EN-US>stdout(1)</span>,这里是指屏幕上显示。参数<span lang=EN-US>'*fmt'</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>指定输出将采用的格式,参见标准<span
lang=EN-US>C</span>语言书籍。该子程序正好是<span lang=EN-US>vsprintf</span>如何使用的一个简单</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>例子。该程序使用<span
lang=EN-US>vsprintf()</span>将格式化的字符串放入<span lang=EN-US>printbuf</span>缓冲区,然后用<span
lang=EN-US>write()</span>将缓冲</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>区的内容输出到标准设备(<span
lang=EN-US>1--stdout</span>)。<span lang=EN-US>vsprintf()</span>函数的实现见<span
lang=EN-US>kernel/vsprintf.c</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>179</span></u><span
lang=EN-US> static int <u><span style='color:blue'>printf</span></u>(const char
*fmt, ...)</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>180</span></u><span
lang=EN-US> {</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>181</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>va_list</span></u> args;</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>182</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>183</span></u><span
lang=EN-US> </span></p>
<p class=a><u><span lang=EN-US style='color:blue'>184</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>va_start</span></u>(args, fmt);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>185</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>write</span></u>(1,<u><span style='color:blue'>printbuf</span></u>,i=<u><span
style='color:blue'>vsprintf</span></u>(<u><span style='color:blue'>printbuf</span></u>,
fmt, args));</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>186</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>va_end</span></u>(args);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>187</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return i;</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>188</span></u><span
lang=EN-US> }</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>189</span></u><span
lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span><span lang=EN-US>main()</span>中已经进行了系统初始化,包括内存管理、各种硬件设备和驱动程序。<span
lang=EN-US>init()</span>函数</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>运行在任务<span lang=EN-US>0</span><span
lang=EN-US>1</span>次创建的子进程(任务<span lang=EN-US>1</span>)中。它首先对第一个将要执行的程序(<span
lang=EN-US>shell</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>的环境进行初始化,然后以登录<span
lang=EN-US>shell</span>方式加载该程序并执行之。</p>
<p class=a><u><span lang=EN-US style='color:blue'>190</span></u><span
lang=EN-US> void <u><span style='color:blue'>init</span></u>(void)</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>191</span></u><span
lang=EN-US> {</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>192</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int pid,i;</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>193</span></u><span
lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // setup() </span>是一个系统调用。用于读取硬盘参数包括分区表信息并加载虚拟盘(若存在的话)和</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>安装根文件系统设备。该函数用<span
lang=EN-US>25</span>行上的宏定义,对应函数是<span lang=EN-US>sys_setup()</span>,在块设备子目录</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // kernel/blk_drv/hd.c</span><span
lang=EN-US>74</span>行。</p>
<p class=a><u><span lang=EN-US style='color:blue'>194</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setup((void *)
&amp;<u><span style='color:blue'>drive_info</span></u>); </span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面以读写访问方式打开设备“<span
lang=EN-US>/dev/tty0<span
lang=EN-US><span lang=EN-US></span></span><span lang=EN-US>,它对应终端控制台。由于这是第一次打开文件</span></span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>操作,因此产生的文件句柄号(文件描述符)肯定是<span
lang=EN-US>0</span>。该句柄是<span lang=EN-US>UNIX</span>类操作系统默认的控</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>制台标准输入句柄<span
lang=EN-US>stdin</span>。这里再把它以读和写的方式分别打开是为了复制产生标准输出(写)</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>句柄<span lang=EN-US>stdout</span>和标准出错输出句柄<span
lang=EN-US>stderr</span>。函数前面的“<span lang=EN-US>(void)</span>”前缀用于表示强制函数无需</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>返回值。</p>
<p class=a><u><span lang=EN-US style='color:blue'>195</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void) <u><span
style='color:blue'>open</span></u>(<i>&quot;/dev/tty1&quot;</i>,<u><span
style='color:blue'>O_RDWR</span></u>,0);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>196</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void) <u><span
style='color:blue'>dup</span></u>(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>复制句柄,产生句柄<span lang=EN-US>1</span><span lang=EN-US>--stdout</span>标准输出设备。</p>
<p class=a><u><span lang=EN-US style='color:blue'>197</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void) <u><span
style='color:blue'>dup</span></u>(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>复制句柄,产生句柄<span lang=EN-US>2</span><span lang=EN-US>--stderr</span>标准出错输出设备。</p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面打印缓冲区块数和总字节数,每块<span
lang=EN-US>1024</span>字节,以及主内存区空闲内存字节数。</p>
<p class=a><u><span lang=EN-US style='color:blue'>198</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>printf</span></u>(<i>&quot;%d buffers = %d bytes buffer
space\n\r&quot;</i>,<u><span style='color:blue'>NR_BUFFERS</span></u>,</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>199</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>NR_BUFFERS</span></u>*<u><span style='color:blue'>BLOCK_SIZE</span></u>);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>200</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>printf</span></u>(<i>&quot;Free mem: %d bytes\n\r&quot;</i>,<u><span
style='color:blue'>memory_end</span></u>-<u><span style='color:blue'>main_memory_start</span></u>);
</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面<span lang=EN-US>fork()</span>用于创建一个子进程(任务<span
lang=EN-US>2</span>)。对于被创建的子进程,<span lang=EN-US>fork()</span>将返回<span
lang=EN-US>0</span>值,对于</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>原进程(父进程)则返回子进程的进程号<span
lang=EN-US>pid</span>。所以第<span lang=EN-US>202--206</span>行是子进程执行的内容。该子</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>进程关闭了句柄<span
lang=EN-US>0</span><span lang=EN-US>stdin</span>)、以只读方式打开<span lang=EN-US>/etc/rc</span>文件,并使用<span
lang=EN-US>execve()</span>函数将进程自身</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>替换成<span lang=EN-US> /bin/sh</span>程序(即<span
lang=EN-US>shell</span>程序),然后执行 <span lang=EN-US>/bin/sh</span>程序。所携带的参数和环境变量分</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>别由<span lang=EN-US>argv_rc</span><span
lang=EN-US>envp_rc</span>数组给出。关闭句柄<span lang=EN-US>0</span>并立刻打开<span
lang=EN-US> /etc/rc</span>文件的作用是把标准输入</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // stdin</span>重定向到<span
lang=EN-US> /etc/rc</span>文件。这样<span lang=EN-US>shell</span>程序<span lang=EN-US>/bin/sh</span>就可以运行<span
lang=EN-US>rc</span>文件中设置的命令。由</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>于这里<span lang=EN-US>sh</span>的运行方式是非交互式的,因此在执行完<span
lang=EN-US>rc</span>文件中的命令后就会立刻退出,进程<span lang=EN-US>2 </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>也随之结束。关于<span
lang=EN-US>execve()</span>函数说明请参见<span lang=EN-US>fs/exec.c</span>程序,<span
lang=EN-US>207</span>行。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>函数<span lang=EN-US>_exit()</span>退出时的出错码<span
lang=EN-US>1 </span>操作未许可;<span lang=EN-US>2 -- </span>文件或目录不存在。</p>
<p class=a><u><span lang=EN-US style='color:blue'>201</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!(pid=<u><span
style='color:blue'>fork</span></u>())) {</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>202</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>close</span></u>(0);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>203</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (<u><span style='color:blue'>open</span></u>(<i>&quot;/etc/rc&quot;</i>,<u><span
style='color:blue'>O_RDONLY</span></u>,0))</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>204</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>_exit</span></u>(1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>若打开文件失败,则退出<span lang=EN-US>(lib/_exit.c,10)</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>205</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>execve</span></u>(<i>&quot;/bin/sh&quot;</i>,<u><span
style='color:blue'>argv_rc</span></u>,<u><span style='color:blue'>envp_rc</span></u>);&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>替换成<span lang=EN-US>/bin/sh</span>程序并执行。</p>
<p class=a><u><span lang=EN-US style='color:blue'>206</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>_exit</span></u>(2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;// </span><span lang=EN-US>execve()</span>执行失败则退出。</p>
<p class=a><u><span lang=EN-US style='color:blue'>207</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面还是父进程(<span
lang=EN-US>1</span>)执行的语句。<span lang=EN-US>wait()</span>等待子进程停止或终止,返回值应是子进程的进程号</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // (pid)</span>。这三句的作用是父进程等待子进程的结束。<span
lang=EN-US>&amp;i</span>是存放返回状态信息的位置。如果<span lang=EN-US>wait()</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>返回值不等于子进程号,则继续等待。</p>
<p class=a><u><span lang=EN-US style='color:blue'>208</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pid&gt;0)</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>209</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
while (pid != <u><span style='color:blue'>wait</span></u>(&amp;i))</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>210</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<b><i>/* nothing */</i></b>;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/* </span>空循环<span
lang=EN-US> */</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果执行到这里,说明刚创建的子进程的执行已停止或终止了。下面循环中首先再创建一个子</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>进程,如果出错,则显示“初始化程序创建子进程失败”信息并继续执行。对于所创建的子进</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>程将关闭所有以前还遗留的句柄<span
lang=EN-US>(stdin, stdout, stderr)</span>,新创建一个会话并设置进程组号,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>然后重新打开<span
lang=EN-US> /dev/tty0 </span>作为 <span lang=EN-US>stdin</span>,并复制成 <span
lang=EN-US>stdout</span><span lang=EN-US>stderr</span>。再次执行系统解释程序</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // /bin/sh</span>。但这次执行所选用的参数和环境数组另选了一套(见上面<span
lang=EN-US>122--123</span>行)。然后父进</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>程再次运行 <span
lang=EN-US>wait()</span>等待。如果子进程又停止了执行,则在标准输出上显示出错信息“子进程</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // pid</span>停止了运行,返回码是<span
lang=EN-US>i</span>”,然后继续重试下去<span lang=EN-US></span>,形成“大”死循环。</p>
<p class=a><u><span lang=EN-US style='color:blue'>211</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (1) {</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>212</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if ((pid=<u><span style='color:blue'>fork</span></u>())&lt;0) {</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>213</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>printf</span></u>(<i>&quot;Fork failed in
init\r\n&quot;</i>);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>214</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
continue;</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>215</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>216</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (!pid) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>新的子进程。</p>
<p class=a><u><span lang=EN-US style='color:blue'>217</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>close</span></u>(0);<u><span style='color:blue'>close</span></u>(1);<u><span
style='color:blue'>close</span></u>(2);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>218</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>setsid</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>创建一新的会话期,见后面说明。</p>
<p class=a><u><span lang=EN-US style='color:blue'>219</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
(void) <u><span style='color:blue'>open</span></u>(<i>&quot;/dev/tty1&quot;</i>,<u><span
style='color:blue'>O_RDWR</span></u>,0);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>220</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(void) <u><span style='color:blue'>dup</span></u>(0);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>221</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
(void) <u><span style='color:blue'>dup</span></u>(0);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>222</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>_exit</span></u>(<u><span style='color:blue'>execve</span></u>(<i>&quot;/bin/sh&quot;</i>,<u><span
style='color:blue'>argv</span></u>,<u><span style='color:blue'>envp</span></u>));</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>223</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>224</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
while (1)</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>225</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (pid == <u><span style='color:blue'>wait</span></u>(&amp;i))</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>226</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>227</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>printf</span></u>(<i>&quot;\n\rchild %d died with
code %04x\n\r&quot;</i>,pid,i);</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>228</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>sync</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>同步操作,刷新缓冲区。</p>
<p class=a><u><span lang=EN-US style='color:blue'>229</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>230</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>_exit</span></u>(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><i>/*
NOTE! _exit, not exit() */</i></b>&nbsp; /*</span>注意!是<span lang=EN-US>_exit()</span>,非<span
lang=EN-US>exit()*/</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // _exit()</span><span
lang=EN-US>exit()</span>都用于正常终止一个函数。但<span lang=EN-US>_exit()</span>直接是一个<span
lang=EN-US>sys_exit</span>系统调用,而</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // exit()</span>则通常是普通函数库中的一个函数。它会先执行一些清除操作,例如调用执行各终止</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>处理程序、关闭所有标准<span
lang=EN-US>IO</span>等,然后调用<span lang=EN-US>sys_exit</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>231</span></u><span
lang=EN-US> }</span></p>
<p class=a><u><span lang=EN-US style='color:blue'>232</span></u><span
lang=EN-US> </span></p>
<div class=a align=center style='text-align:center'><span lang=EN-US>
<hr size=4 width="100%" align=center>
</span></div>
<p class=30><span lang=EN-US>&nbsp;</span></p>
<p class=MsoNormal><span lang=EN-US>&nbsp;</span></p>
</div>
</body>
</html>