����9-4 linux/kernel/blk_drv/ramdisk.c


  1 /*

  2  *  linux/kernel/blk_drv/ramdisk.c

  3  *

  4  *  Written by Theodore Ts'o, 12/2/91

  5  */

    /* ��Theodore Ts'o���ƣ�12/2/91

     */

    // Theodore Ts'o (Ted Ts'o)��Linux�����е��������Linux�����緶Χ�ڵ�����Ҳ������

    // ��Ĺ��͡�����Linux����ϵͳ������ʱ�����ͻ��ż��������ΪLinux�ķ�չ�ṩ�˵�����

    // ���б�����maillist�����ڱ�����������������Linux��ftp������վ�㣨tsx-11.mit.edu����

    // ����������Ϊ���Linux�û��ṩ��������Linux�����������֮һ�������ʵ����ext2

    // �ļ�ϵͳ�����ļ�ϵͳ�ѳ�ΪLinux��������ʵ�ϵ��ļ�ϵͳ��׼����������Ƴ���ext3�ļ�

    // ϵͳ�����������ļ�ϵͳ���ȶ��ԡ��ɻָ��Ժͷ���Ч�ʡ���Ϊ�������Ƴ磬��97�ڣ�2002

    // ��5�£���LinuxJournal�ڿ�������Ϊ�˷�����������������˲ɷá�Ŀǰ��ΪIBM Linux

    // �������Ĺ��������������й�LSB (Linux Standard Base)�ȷ���Ĺ����������ĸ�����ҳ�ǣ�

    // http://thunk.org/tytso/)

  6

  7 #include <string.h>       // �ַ���ͷ�ļ�����Ҫ������һЩ�й��ַ���������Ƕ�뺯����

  8

  9 #include <linux/config.h> // �ں�����ͷ�ļ�������������Ժ�Ӳ�����ͣ�HD_TYPE����ѡ�

 10 #include <linux/sched.h>  // ���ȳ���ͷ�ļ�������������ṹtask_struct������0�����ݣ�

                              // ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣

 11 #include <linux/fs.h>     // �ļ�ϵͳͷ�ļ��������ļ����ṹ��file��m_inode���ȡ�

 12 #include <linux/kernel.h> // �ں�ͷ�ļ�������һЩ�ں˳��ú�����ԭ�Ͷ��塣

 13 #include <asm/system.h>   // ϵͳͷ�ļ������������û��޸�������/�ж��ŵ�Ƕ��ʽ���ꡣ

 14 #include <asm/segment.h>  // �β���ͷ�ļ����������йضμĴ���������Ƕ��ʽ��ຯ����

 15 #include <asm/memory.h>   // �ڴ濽��ͷ�ļ�������memcpy()Ƕ��ʽ���꺯����

 16

    // ����RAM�����豸�ŷ��ų��������������������豸�ű����ڰ���blk.h�ļ�֮ǰ�����塣

    // ��Ϊblk.h�ļ���Ҫ�õ�������ų���ֵ��ȷ��һЩ�е������������źͺꡣ

 17 #define MAJOR_NR 1

 18 #include "blk.h"

 19

    // ���������ڴ��е���ʼλ�á���λ�û��ڵ�52���ϳ�ʼ������rd_init()��ȷ�����μ��ں�

    // ��ʼ������init/main.c����124�С�'rd'��'ramdisk'����д��

 20 char    *rd_start;                       // ���������ڴ��еĿ�ʼ��ַ��

 21 int     rd_length = 0;                   // ��������ռ�ڴ��С���ֽڣ���

 22

    // �����̵�ǰ���������������

    // �ú����ij���ṹ��Ӳ�̵�do_hd_request()�������ƣ��μ�hd.c��294�С��ڵͼ����豸

    // �ӿں���ll_rw_block()�����������̣�rd������������ӵ� rd��������֮�󣬾ͻ��

    // �øú����� rd��ǰ��������д������ú������ȼ��㵱ǰ��������ָ������ʼ������Ӧ��

    // ���������ڴ����ʼλ��addr ��Ҫ�����������Ӧ���ֽڳ���ֵ len��Ȼ�������������

    // ��������в���������д����WRITE���Ͱ���������ָ�������е�����ֱ�Ӹ��Ƶ��ڴ�λ��

    // addr�������Ƕ�������֮�����ݸ�����ɺ󼴿�ֱ�ӵ��� end_request() �Ա���������

    // ������������Ȼ����ת��������ʼ����ȥ������һ�����������û�����������˳���

 23 void do_rd_request(void)

 24 {

 25         int     len;

 26         char    *addr;

 27

    // ���ȼ��������ĺϷ��ԣ�����û�����������˳����μ�blk.h����127�У���Ȼ�������

    // �����������������ʼ�����������ڴ��ж�Ӧ�ĵ�ַaddr��ռ�õ��ڴ��ֽڳ���ֵlen��

    // �¾�����ȡ���������е���ʼ������Ӧ���ڴ���ʼλ�ú��ڴ泤�ȡ�����sector << 9��ʾ

    // sector * 512��������ֽ�ֵ��CURRENT������Ϊ (blk_dev[MAJOR_NR].current_request)��

 28         INIT_REQUEST;

 29         addr = rd_start + (CURRENT->sector << 9);

 30         len = CURRENT->nr_sectors << 9;

    // �����ǰ�����������豸�Ų�Ϊ1���߶�Ӧ�ڴ���ʼλ�ô���������ĩβ��������������

    // ����ת�� repeat ��ȥ������һ���������������� repeat �����ں� INIT_REQUEST �ڣ�

    // λ�ں�Ŀ�ʼ�����μ�blk.h�ļ���127�С�

 31         if ((MINOR(CURRENT->dev) != 1) || (addr+len > rd_start+rd_length)) {

 32                 end_request(0);

 33                 goto repeat;

 34         }

    // Ȼ�����ʵ�ʵĶ�д�����������д���WRITE�������������л����������ݸ��Ƶ���ַ

    // addr��������Ϊlen�ֽڡ�����Ƕ����READ������addr��ʼ���ڴ����ݸ��Ƶ�������

    // �������У�����Ϊlen�ֽڡ�������ʾ������ڣ�������

 35         if (CURRENT-> cmd == WRITE) {

 36                 (void ) memcpy(addr,

 37                               CURRENT->buffer,

 38                               len);

 39         } else if (CURRENT->cmd == READ) {

 40                 (void) memcpy(CURRENT->buffer,

 41                               addr,

 42                               len);

 43         } else

 44                 panic("unknown ramdisk-command");

    // Ȼ����������ɹ��������ø��±�־���������������豸����һ�����

 45         end_request(1);

 46         goto repeat;

 47 }

 48

 49 /*

 50  * Returns amount of memory which needs to be reserved.

 51  */

    /* �����ڴ�������ramdisk������ڴ��� */

    // �����̳�ʼ��������

    // �ú������������������豸�������������ָ��ָ��do_rd_request()��Ȼ��ȷ��������

    // �������ڴ��е���ʼ��ַ��ռ���ֽڳ���ֵ���������������������㡣��󷵻��������ȡ�

    // ��linux/Makefile�ļ������ù�RAMDISKֵ��Ϊ��ʱ����ʾϵͳ�лᴴ��RAM�������豸��

    // ����������µ��ں˳�ʼ�������У��������ͻᱻ���ã�init/main.c��L151�У����ú���

    // �ĵ�2������length�ᱻ��ֵ��RAMDISK * 1024����λΪ�ֽڡ�

 52 long rd_init(long mem_start, int length)

 53 {

 54         int     i;

 55         char    *cp;

 56

 57         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;  // do_rd_request()��

 58         rd_start = (char *) mem_start;                  // ����16MBϵͳ��ֵΪ4MB��

 59         rd_length = length;                             // ���������򳤶�ֵ��

 60         cp = rd_start;

 61         for (i=0; i < length; i++)                      // �������㡣

 62                 *cp++ = '\0';

 63         return(length);

 64 }

 65

 66 /*

 67  * If the root device is the ram disk, try to load it.

 68  * In order to do this, the root device is originally set to the

 69  * floppy, and we later change it to be ram disk.

 70  */

    /*

     * ������ļ�ϵͳ�豸(root device)��ramdisk�Ļ������Լ�������

     * root deviceԭ����ָ�����̵ģ����ǽ����ij�ָ��ramdisk��

     */

    //// ���԰Ѹ��ļ�ϵͳ���ص��������С�

    // �ú��������ں����ú���setup()��hd.c��156�У��б����á����⣬1���̿� = 1024�ֽڡ�

    // ��75���ϵı���block=256��ʾ���ļ�ϵͳӳ���ļ����洢��boot�̵�256���̿鿪ʼ����

 71 void rd_load(void)

 72 {

 73         struct buffer_head *bh;         // ���ٻ����ͷָ�롣

 74         struct super_block      s;      // �ļ�������ṹ��

 75         int             block = 256;    /* Start at block 256 */ /* ��ʼ��256�̿� */

 76         int             i = 1;

 77         int             nblocks;        // �ļ�ϵͳ�̿�������

 78         char            *cp;            /* Move pointer */

 79        

    // ���ȼ�������̵���Ч�Ժ������ԡ����ramdisk�ij���Ϊ�㣬���˳���������ʾramdisk

    // �Ĵ�С�Լ��ڴ���ʼλ�á������ʱ���ļ��豸���������豸����Ҳ�˳���

 80         if (!rd_length)

 81                 return;

 82         printk("Ram disk: %d bytes, starting at 0x%x\n", rd_length,

 83                 (int) rd_start);

 84         if (MAJOR(ROOT_DEV) != 2)

 85                 return;

    // Ȼ������ļ�ϵͳ�Ļ����������������̿�256+1��256��256+2������block+1��ָ������

    // �ij����顣breada() ���ڶ�ȡָ�������ݿ飬���������Ҫ���Ŀ飬Ȼ�󷵻غ������ݿ��

    // ������ָ�롣�������NULL�����ʾ���ݿ鲻�ɶ���fs/buffer.c��322����Ȼ��ѻ�������

    // �Ĵ��̳����飨d_super_block�Ǵ��̳�����ṹ�����Ƶ�s�����У����ͷŻ������� ����

    // ���ǿ�ʼ�Գ��������Ч�Խ����жϡ� ������������ļ�ϵͳħ�����ԣ���˵�����ص�����

    // �鲻��MINIX�ļ�ϵͳ�������˳����й�MINIX������Ľṹ��μ��ļ�ϵͳһ�����ݡ�

 86         bh = breada(ROOT_DEV,block+1,block,block+2,-1);

 87         if (!bh) {

 88                 printk("Disk error while looking for ramdisk!\n");

 89                 return;

 90         }

 91         *((struct d_super_block *) &s) = *((struct d_super_block *) bh->b_data);

 92         brelse(bh);

 93         if (s.s_magic != SUPER_MAGIC)

 94                 /* No ram disk image present, assume normal floppy boot */

                    /* ������û��ramdiskӳ���ļ����˳�ȥִ��ͨ������������ */

 95                 return;

    // Ȼ��������ͼ���������ļ�ϵͳ���뵽�ڴ����������С�����һ���ļ�ϵͳ��˵���䳬����

    // �ṹ�� s_nzones �ֶ��б��������߼����������Ϊ����������һ���߼����к��е����ݿ�

    // �������ֶ�s_log_zone_sizeָ��������ļ�ϵͳ�е����ݿ�����nblocks �͵��� (�߼���

    // �� * 2^(ÿ���ο����Ĵη�))����nblocks = (s_nzones * 2^s_log_zone_size)���������

    // �ļ�ϵͳ�����ݿ����������ڴ��������������ɵĿ��������������ִ�м��ز�������ֻ

    // ����ʾ������Ϣ�����ء�

 96         nblocks = s.s_nzones << s.s_log_zone_size;

 97         if (nblocks > (rd_length >> BLOCK_SIZE_BITS)) {

 98                 printk("Ram disk image too big!  (%d blocks, %d avail)\n",

 99                         nblocks, rd_length >> BLOCK_SIZE_BITS);

100                 return;

101         }

    // �����������������ɵ����ļ�ϵͳ�����ݿ�������������ʾ�������ݿ���Ϣ������cpָ��

    // �ڴ���������ʼ����Ȼ��ʼִ��ѭ�������������ϸ��ļ�ϵͳӳ���ļ����ص��������ϡ�

    // �ڲ��������У����һ����Ҫ���ص��̿�������2�飬���Ǿ����ó�ǰԤ������breada()��

    // �����ʹ��bread()�������е����ȡ�����ڶ��̹����г���I/O�������󣬾�ֻ�ܷ�����

    // �ع��̷��ء�����ȡ�Ĵ��̿��ʹ��memcpy()�����Ӹ��ٻ������и��Ƶ��ڴ���������Ӧ

    // λ�ô���ͬʱ��ʾ�Ѽ��صĿ�������ʾ�ַ����еİ˽�����'\010'��ʾ��ʾһ���Ʊ�����

102         printk("Loading %d bytes into ram disk... 0000k",

103                 nblocks << BLOCK_SIZE_BITS);

104         cp = rd_start;

105         while (nblocks) {

106                 if (nblocks > 2)                // ����ȡ��������2������ó�ǰԤ����

107                         bh = breada(ROOT_DEV, block, block+1, block+2, -1);

108                 else                            // ����͵����ȡ��

109                         bh = bread(ROOT_DEV, block);

110                 if (!bh) {

111                         printk("I/O error on block %d, aborting load\n",

112                                 block);

113                         return;

114                 }

115                 (void) memcpy(cp, bh->b_data, BLOCK_SIZE);       // ���Ƶ�cp����

116                 brelse(bh);

117                 printk("\010\010\010\010\010%4dk",i);        // ��ӡ���ؿ����ֵ��

118                 cp += BLOCK_SIZE;                            // ������ָ��ǰ�ơ�

119                 block++;

120                 nblocks--;

121                 i++;

122         }

    // ��boot���д�256�̿鿪ʼ���������ļ�ϵͳ������Ϻ�������ʾ��done��������Ŀǰ

    // ���ļ��豸���޸ij������̵��豸��0x0101����󷵻ء�

123         printk("\010\010\010\010\010done \n");

124         ROOT_DEV=0x0101;

125 }

126