⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 56.html

📁 linux 0.11中文版 有注释
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<a name='L99'><b>extern</b> <b>void</b> <a href='../S/59.html#L103' title='Defined at 103 in kernel/blk_drv/ramdisk.c.'>rd_load</a> (<b>void</b>);
<a name='L100'>
<a name='L101'><i><font color='green'>/* This may be used only once, enforced by 'static int callable' */</font></i>
<a name='L102'><i><font color='green'>/* 下面该函数只在初始化时被调用一次。用静态变量callable 作为可调用标志。*/</font></i>
<a name='L103'><i><font color='green'>// 该函数的参数由初始化程序init/main.c 的init 子程序设置为指向0x90080 处,此处存放着setup.s</font></i>
<a name='L104'><i><font color='green'>// 程序从BIOS 取得的2 个硬盘的基本参数表(32 字节)。硬盘参数表信息参见下面列表后的说明。</font></i>
<a name='L105'><i><font color='green'>// 本函数主要功能是读取CMOS 和硬盘参数表信息,用于设置硬盘分区结构hd,并加载RAM 虚拟盘和</font></i>
<a name='L106'><i><font color='green'>// 根文件系统。</font></i>
<a name='L107'><b>int</b> <a href='../R/678.html' title='Multiple refered from 2 places.'>sys_setup</a> (<b>void</b> *BIOS)
<a name='L108'><font color='red'>{</font>
<a name='L109'>  <b>static</b> <b>int</b> callable = 1;
<a name='L110'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>, drive;
<a name='L111'>  <b>unsigned</b> <b>char</b> cmos_disks;
<a name='L112'>  <b>struct</b> partition *p;
<a name='L113'>  <b>struct</b> buffer_head *bh;
<a name='L114'>
<a name='L115'><i><font color='green'>// 初始化时callable=1,当运行该函数时将其设置为0,使本函数只能执行一次。</font></i>
<a name='L116'>  <b>if</b> (!callable)
<a name='L117'>      <b>return</b> -1;
<a name='L118'>    callable = 0;
<a name='L119'><i><font color='green'>// 如果没有在config.h 中定义硬盘参数,就从0x90080 处读入。</font></i>
<a name='L120'><font color='darkred'>#ifndef</font> HD_TYPE
<a name='L121'>  <b>for</b> (drive = 0; drive &lt; 2; drive++)
<a name='L122'>    <font color='red'>{</font>
<a name='L123'>      hd_info[drive].cyl = *(<b>unsigned</b> <b>short</b> *) BIOS;    <i><font color='green'>// 柱面数。</font></i>
<a name='L124'>      hd_info[drive].head = *(<b>unsigned</b> <b>char</b> *) (2 + BIOS);      <i><font color='green'>// 磁头数。</font></i>
<a name='L125'>      hd_info[drive].wpcom = *(<b>unsigned</b> <b>short</b> *) (5 + BIOS);    <i><font color='green'>// 写前预补偿柱面号。</font></i>
<a name='L126'>      hd_info[drive].ctl = *(<b>unsigned</b> <b>char</b> *) (8 + BIOS);       <i><font color='green'>// 控制字节。</font></i>
<a name='L127'>      hd_info[drive].lzone = *(<b>unsigned</b> <b>short</b> *) (12 + BIOS);   <i><font color='green'>// 磁头着陆区柱面号。</font></i>
<a name='L128'>      hd_info[drive].sect = *(<b>unsigned</b> <b>char</b> *) (14 + BIOS);     <i><font color='green'>// 每磁道扇区数。</font></i>
<a name='L129'>      BIOS += 16;               <i><font color='green'>// 每个硬盘的参数表长16 字节,这里BIOS 指向下一个表。</font></i>
<a name='L130'>    <font color='red'>}</font>
<a name='L131'><i><font color='green'>// setup.s 程序在取BIOS 中的硬盘参数表信息时,如果只有1 个硬盘,就会将对应第2 个硬盘的</font></i>
<a name='L132'><i><font color='green'>// 16 字节全部清零。因此这里只要判断第2 个硬盘柱面数是否为0 就可以知道有没有第2 个硬盘了。</font></i>
<a name='L133'>  <b>if</b> (hd_info[1].cyl)
<a name='L134'>      <a href='../S/56.html#L63' title='Defined at 63 in kernel/blk_drv/hd.c.'>NR_HD</a> = 2;                <i><font color='green'>// 硬盘数置为2。</font></i>
<a name='L135'>  <b>else</b>
<a name='L136'>    <a href='../S/56.html#L63' title='Defined at 63 in kernel/blk_drv/hd.c.'>NR_HD</a> = 1;
<a name='L137'><font color='darkred'>#endif</font>
<a name='L138'><i><font color='green'>// 设置每个硬盘的起始扇区号和扇区总数。其中编号i*5 含义参见本程序后的有关说明。</font></i>
<a name='L139'>  <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; <a href='../S/56.html#L63' title='Defined at 63 in kernel/blk_drv/hd.c.'>NR_HD</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L140'>    <font color='red'>{</font>
<a name='L141'>      hd[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> * 5].start_sect = 0; <i><font color='green'>// 硬盘起始扇区号。</font></i>
<a name='L142'>      hd[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> * 5].nr_sects = hd_info[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>].head * hd_info[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>].sect * hd_info[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>].cyl;  <i><font color='green'>// 硬盘总扇区数。</font></i>
<a name='L143'>    <font color='red'>}</font>
<a name='L144'>
<a name='L145'><i><font color='green'>/*</font></i>
<a name='L146'><i><font color='green'>We querry CMOS about hard disks : it could be that</font></i>
<a name='L147'><i><font color='green'>we have a SCSI/ESDI/etc controller that is BIOS</font></i>
<a name='L148'><i><font color='green'>compatable with ST-506, and thus showing up in our</font></i>
<a name='L149'><i><font color='green'>BIOS table, but not register compatable, and therefore</font></i>
<a name='L150'><i><font color='green'>not present in CMOS.</font></i>
<a name='L151'><i><font color='green'></font></i>
<a name='L152'><i><font color='green'>Furthurmore, we will assume that our ST-506 drives</font></i>
<a name='L153'><i><font color='green'>&lt;if any&gt; are the primary drives in the system, and</font></i>
<a name='L154'><i><font color='green'>the ones reflected as drive 1 or 2.</font></i>
<a name='L155'><i><font color='green'></font></i>
<a name='L156'><i><font color='green'>The first drive is stored in the high nibble of CMOS</font></i>
<a name='L157'><i><font color='green'>byte 0x12, the second in the low nibble. This will be</font></i>
<a name='L158'><i><font color='green'>either a 4 bit drive type or 0xf indicating use byte 0x19</font></i>
<a name='L159'><i><font color='green'>for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.</font></i>
<a name='L160'><i><font color='green'></font></i>
<a name='L161'><i><font color='green'>Needless to say, a non-zero value means we have</font></i>
<a name='L162'><i><font color='green'>an AT controller hard disk for that drive.</font></i>
<a name='L163'><i><font color='green'></font></i>
<a name='L164'><i><font color='green'></font></i>
<a name='L165'><i><font color='green'>*/</font></i>
<a name='L166'><i><font color='green'>/*</font></i>
<a name='L167'><i><font color='green'>* 我们对CMOS 有关硬盘的信息有些怀疑:可能会出现这样的情况,我们有一块SCSI/ESDI/等的</font></i>
<a name='L168'><i><font color='green'>* 控制器,它是以ST-506 方式与BIOS 兼容的,因而会出现在我们的BIOS 参数表中,但却又不</font></i>
<a name='L169'><i><font color='green'>* 是寄存器兼容的,因此这些参数在CMOS 中又不存在。</font></i>
<a name='L170'><i><font color='green'>* 另外,我们假设ST-506 驱动器(如果有的话)是系统中的基本驱动器,也即以驱动器1 或2</font></i>
<a name='L171'><i><font color='green'>* 出现的驱动器。</font></i>
<a name='L172'><i><font color='green'>* 第1 个驱动器参数存放在CMOS 字节0x12 的高半字节中,第2 个存放在低半字节中。该4 位字节</font></i>
<a name='L173'><i><font color='green'>* 信息可以是驱动器类型,也可能仅是0xf。0xf 表示使用CMOS 中0x19 字节作为驱动器1 的8 位</font></i>
<a name='L174'><i><font color='green'>* 类型字节,使用CMOS 中0x1A 字节作为驱动器2 的类型字节。</font></i>
<a name='L175'><i><font color='green'>* 总之,一个非零值意味着我们有一个AT 控制器硬盘兼容的驱动器。</font></i>
<a name='L176'><i><font color='green'>*/</font></i>
<a name='L177'>
<a name='L178'><i><font color='green'>// 这里根据上述原理来检测硬盘到底是否是AT 控制器兼容的。有关CMOS 信息请参见4.2.3.1 节。</font></i>
<a name='L179'>  <b>if</b> ((cmos_disks = <a href='../S/56.html#L34' title='Defined at 34 in kernel/blk_drv/hd.c.'>CMOS_READ</a> (0x12)) &amp; 0xf0)
<a name='L180'>    <b>if</b> (cmos_disks &amp; 0x0f)
<a name='L181'>      <a href='../S/56.html#L63' title='Defined at 63 in kernel/blk_drv/hd.c.'>NR_HD</a> = 2;
<a name='L182'>    <b>else</b>
<a name='L183'>      <a href='../S/56.html#L63' title='Defined at 63 in kernel/blk_drv/hd.c.'>NR_HD</a> = 1;
<a name='L184'>  <b>else</b>
<a name='L185'>    <a href='../S/56.html#L63' title='Defined at 63 in kernel/blk_drv/hd.c.'>NR_HD</a> = 0;
<a name='L186'><i><font color='green'>// 若NR_HD=0,则两个硬盘都不是AT 控制器兼容的,硬盘数据结构清零。</font></i>
<a name='L187'><i><font color='green'>// 若NR_HD=1,则将第2 个硬盘的参数清零。</font></i>
<a name='L188'>  <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = <a href='../S/56.html#L63' title='Defined at 63 in kernel/blk_drv/hd.c.'>NR_HD</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; 2; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L189'>    <font color='red'>{</font>
<a name='L190'>      hd[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> * 5].start_sect = 0;
<a name='L191'>      hd[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> * 5].nr_sects = 0;
<a name='L192'>    <font color='red'>}</font>
<a name='L193'><i><font color='green'>// 读取每一个硬盘上第1 块数据(第1 个扇区有用),获取其中的分区表信息。</font></i>
<a name='L194'><i><font color='green'>// 首先利用函数bread()读硬盘第1 块数据(fs/buffer.c,267),参数中的0x300 是硬盘的主设备号</font></i>
<a name='L195'><i><font color='green'>// (参见列表后的说明)。然后根据硬盘头1 个扇区位置0x1fe 处的两个字节是否为'55AA'来判断</font></i>
<a name='L196'><i><font color='green'>// 该扇区中位于0x1BE 开始的分区表是否有效。最后将分区表信息放入硬盘分区数据结构hd 中。</font></i>
<a name='L197'>  <b>for</b> (drive = 0; drive &lt; <a href='../S/56.html#L63' title='Defined at 63 in kernel/blk_drv/hd.c.'>NR_HD</a>; drive++)
<a name='L198'>    <font color='red'>{</font>
<a name='L199'>      <b>if</b> (!(bh = <a href='../S/6.html#L397' title='Defined at 397 in fs/buffer.c.'>bread</a> (0x300 + drive * 5, 0)))
<a name='L200'>        <font color='red'>{</font>                       <i><font color='green'>// 0x300, 0x305 逻辑设备号。</font></i>
<a name='L201'>          <a href='../S/73.html#L30' title='Defined at 30 in kernel/printk.c.'>printk</a> ("Unable to read partition table of drive %d\n\r", drive);
<a name='L202'>          <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("");
<a name='L203'>        <font color='red'>}</font>
<a name='L204'>      <b>if</b> (bh-&gt;b_data[510] != 0x55 || (<b>unsigned</b> <b>char</b>) bh-&gt;b_data[511] != 0xAA)
<a name='L205'>        <font color='red'>{</font>                       <i><font color='green'>// 判断硬盘信息有效标志'55AA'。</font></i>
<a name='L206'>          <a href='../S/73.html#L30' title='Defined at 30 in kernel/printk.c.'>printk</a> ("Bad partition table on drive %d\n\r", drive);
<a name='L207'>          <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("");
<a name='L208'>        <font color='red'>}</font>
<a name='L209'>      p = 0x1BE + (<b>void</b> *) bh-&gt;b_data;  <i><font color='green'>// 分区表位于硬盘第1 扇区的0x1BE 处。</font></i>
<a name='L210'>      <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 1; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; 5; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++, p++)
<a name='L211'>        <font color='red'>{</font>
<a name='L212'>          hd[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> + 5 * drive].start_sect = p-&gt;start_sect;
<a name='L213'>          hd[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> + 5 * drive].nr_sects = p-&gt;nr_sects;
<a name='L214'>        <font color='red'>}</font>
<a name='L215'>      <a href='../S/6.html#L377' title='Defined at 377 in fs/buffer.c.'>brelse</a> (bh);              <i><font color='green'>// 释放为存放硬盘块而申请的内存缓冲区页。</font></i>
<a name='L216'>    <font color='red'>}</font>
<a name='L217'>  <b>if</b> (<a href='../S/56.html#L63' title='Defined at 63 in kernel/blk_drv/hd.c.'>NR_HD</a>)                    <i><font color='green'>// 如果有硬盘存在并且已读入分区表,则打印分区表正常信息。</font></i>
<a name='L218'>    <a href='../S/73.html#L30' title='Defined at 30 in kernel/printk.c.'>printk</a> ("Partition table%s ok.\n\r", (<a href='../S/56.html#L63' title='Defined at 63 in kernel/blk_drv/hd.c.'>NR_HD</a> &gt; 1) ? "s" : "");
<a name='L219'>  <a href='../S/59.html#L103' title='Defined at 103 in kernel/blk_drv/ramdisk.c.'>rd_load</a> ();                   <i><font color='green'>// 加载(创建)RAMDISK(kernel/blk_drv/ramdisk.c,71)。</font></i>
<a name='L220'>  <a href='../S/19.html#L354' title='Defined at 354 in fs/super.c.'>mount_root</a> ();                <i><font color='green'>// 安装根文件系统(fs/super.c,242)。</font></i>
<a name='L221'>  <b>return</b> (0);
<a name='L222'><font color='red'>}</font>
<a name='L223'>
<a name='L224'><i><font color='green'>//// 判断并循环等待驱动器就绪。</font></i>
<a name='L225'><i><font color='green'>// 读硬盘控制器状态寄存器端口HD_STATUS(0x1f7),并循环检测驱动器就绪比特位和控制器忙位。</font></i>
<a name='L226'><b>static</b> <b>int</b> <a href='../S/56.html#L262' title='Refered from 262 in kernel/blk_drv/hd.c.'>controller_ready</a> (<b>void</b>)

⌨️ 快捷键说明

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