跟我一起写操作系统

    返回首页    发表留言
本文作者:李德强
          第二节 磁盘分区与挂载
 
 

        在文件系统章节我们已经学过硬盘分区的相关知识,在这里我们只是利用磁盘读写来对硬盘进行分区和操作。首先来看一下硬盘的扇区规划:1G大小的磁盘空间需要0x200000个扇区,一个字节的每一个bit位表示一个扇区,则需要0x200000/8=0x40000个字节,40000个字节本身需要使用0x40000 / 0x200 = 0x200个扇区来存储,所以bitmap的大小为0x200,HDA_BITMAP_SIZE+2是因为0号扇区为启动扇区,1号扇区为分区表扇区。

//hda1 bitmap为0x200个扇区,可表示1GB
#define HDA1_BITMAP_START        (2)
#define HDA1_SIZE                (0x200000)
#define HDA1_START               (HDA1_BITMAP_START + (HDA1_SIZE / 8 / 0x200))
//hda2 bitmap为0x400个扇区,可表示2GB
#define HDA2_BITMAP_START        (HDA1_START + HDA1_SIZE)
#define HDA2_SIZE                (0x400000)
#define HDA2_START               (HDA2_BITMAP_START + (HDA2_SIZE / 8 / 200))
//hda3 swap交换分区 bitmap为0x100个扇区,每个bit表示8个连续扇区,共可表示4GB
#define HDA3_BITMAP_START        (HDA2_START + HDA2_SIZE)
#define HDA3_SIZE                (0x800000)
#define HDA3_START               (HDA3_BITMAP_START + 0x100)

        创建分区表,并将其写入磁盘。其中type为0表示普通分区用于存储长期数据,type为0表示swap分区,用于数据交换。写入分区表的操作只要做一次,写入成功以后就直接从硬盘中读入分区表即可,而不需要每次都重写分区表:

//hda1 data type == 0x00
sys_var->pts[0].device = 0x01;
sys_var->pts[0].boot = 0x01;
sys_var->pts[0].id = 0x01;
sys_var->pts[0].type = 0x00;
sys_var->pts[0].bitmap_start = HDA1_BITMAP_START;
sys_var->pts[0].start = HDA1_START;
sys_var->pts[0].size = HDA1_SIZE;
//hda2 data type == 0x00
sys_var->pts[1].device = 0x02;
sys_var->pts[1].boot = 0x00;
sys_var->pts[1].id = 0x02;
sys_var->pts[1].type = 0x00;
sys_var->pts[1].bitmap_start = HDA2_BITMAP_START;
sys_var->pts[1].start = HDA2_START;
sys_var->pts[1].size = HDA2_SIZE;
//hda3 swap type == 0x1
sys_var->pts[2].device = 0x03;
sys_var->pts[2].boot = 0x00;
sys_var->pts[2].id = 0x03;
sys_var->pts[2].type = 0x1;
sys_var->pts[2].bitmap_start = HDA3_BITMAP_START;
sys_var->pts[2].start = HDA3_START;
sys_var->pts[2].size = HDA3_SIZE;
write_sector(1, (u8*) sys_var->pts);
printf("[ OK ] Create hda partition table.\n");

        载入分区表:

read_sector(1, (u8*) sys_var->pts);
printf("[ OK ] Load hda partition table.\n");
printf("\tDevice Boot Id Type Start End Sectors\n");
sys_var->pt_count = 0;
for (int i = 0; i < HD_PT_COUT; i++)
{
        if (sys_var->pts[i].device == 0)
        {
                break;
        }
        sys_var->pt_count++;
        printf("\thda%d   %d    %d  %d    %x %x %x\n", sys_var->pts[i].device,                         sys_var->pts[i].boot, 
        sys_var->pts[i].id, 
        sys_var->pts[i].type, 
        sys_var->pts[i].start, 
        sys_var->pts[i].start + sys_var->pts[i].size - 1, 
        sys_var->sys_var->pts[i].boot, 
        sys_var->pts[i].id, 
        sys_var->pts[i].type, 
        sys_var->pts[i].start, 
        sys_var->pts[i].start + sys_var->pts[i].size - 1, 
        sys_var->pts[i].size);
}

        格式化分区,清空每个分区头部位图的值,与写入分区表一样只需要格式化一次即可,除非在以后的使用过程中有特殊需要才对分区重新格式化:

u8* empty = malloc(0x200);
for (int i = 0; i < 0x200; i++)
{
        empty[i] = 0;
}
for (int i = 0; i < sys_var->pt_count; i++)
{
        if (sys_var->pts[i].type != 0x1)
        {
                u32 bitmap_size = sys_var->pts[i].size / 8 / 0x200;
                for (int j = 0; j < bitmap_size / 0x200; j++)
                {
                        write_sector(sys_var->pts[i].bitmap_start + j, empty);
                }
                s_fs fs_root;
                u8 *p = (u8*) &fs_root;
                for (int i = 0; i < 0x200; i++)
                {
                        p[i] = 0;
                }
                fs_root.owner = uid;
                fs_root.group = gid;
                fs_root.mode = mode;
                fs_root.dot = hda_alloc(sys_var->pts[i].device);
                fs_root.dotdot = fs_root.dot;
                str_copy("/", fs_root.name);
                write_sector(fs_root.dot, (u8 *) &fs_root);
                printf("[ OK ] Format hda%d start: %d size: %d sectors.\n", 
                sys_var->pts[i].device, 
                sys_var->pts[i].start, 
                sys_var->pts[i].size);
        }
}
free(empty);

        值得注意的是在格式化分区时,需要对其写入根目录“/”。这样在内核程序mount此分区时才能找到其根目录并将其挂载到挂载点上。

        最后编译运行程序并查看运行结果:


 

        源代码的下载地址为:

https            https://github.com/magicworldos/lidqos.git 
git              git@github.com:magicworldos/lidqos.git 
subverion        https://github.com/magicworldos/lidqos 
branch           v0.28

    返回首页    返回顶部
  看不清?点击刷新

 

  Copyright © 2015-2018 问渠网 辽ICP备15013245号