/** * <Ring 1> Make a available Orange'S FS in the disk. It will * - Write a super block to sector 1. * - Create three special files: dev_tty0, dev_tty1, dev_tty2 * - Create a file cmd.tar * - Create the inode map * - Create the sector map * - Create the inodes of the files * - Create `/', the root directory *****************************************************************************/ PRIVATE void mkfs() { MESSAGE driver_msg; int i, j; /************************/ /* super block */ /************************/ /* get the geometry of ROOTDEV */ struct part_info geo; driver_msg.type = DEV_IOCTL; driver_msg.DEVICE = MINOR(ROOT_DEV); driver_msg.REQUEST = DIOCTL_GET_GEO; driver_msg.BUF = &geo; driver_msg.PROC_NR = TASK_FS; assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER); send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg); printl("{FS} dev size: 0x%x sectors\n", geo.size); int bits_per_sect = SECTOR_SIZE * 8; /* 8 bits per byte */ /* generate a super block */ struct super_block sb; sb.magic = MAGIC_V1; /* 0x111 */ sb.nr_inodes = bits_per_sect; sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE; sb.nr_sects = geo.size; /* partition size in sector */ sb.nr_imap_sects = 1; sb.nr_smap_sects = sb.nr_sects / bits_per_sect + 1; sb.n_1st_sect = 1 + 1 + /* boot sector & super block */ sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects; sb.root_inode = ROOT_INODE; sb.inode_size = INODE_SIZE; struct inode x; sb.inode_isize_off= (int)&x.i_size - (int)&x; sb.inode_start_off= (int)&x.i_start_sect - (int)&x; sb.dir_ent_size = DIR_ENTRY_SIZE; struct dir_entry de; sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de; sb.dir_ent_fname_off = (int)&de.name - (int)&de; memset(fsbuf, 0x90, SECTOR_SIZE); memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE); /* write the super block */ WR_SECT(ROOT_DEV, 1); printl("{FS} devbase:0x%x00, sb:0x%x00, imap:0x%x00, smap:0x%x00\n" " inodes:0x%x00, 1st_sector:0x%x00\n", geo.base * 2, (geo.base + 1) * 2, (geo.base + 1 + 1) * 2, (geo.base + 1 + 1 + sb.nr_imap_sects) * 2, (geo.base + 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects) * 2, (geo.base + sb.n_1st_sect) * 2); /************************/ /* inode map */ /************************/ memset(fsbuf, 0, SECTOR_SIZE); for (i = 0; i < (NR_CONSOLES + 3); i++) fsbuf[0] |= 1 << i; assert(fsbuf[0] == 0x3F);/* 0011 1111 : * || |||| * || |||`--- bit 0 : reserved * || ||`---- bit 1 : the first inode, * || || which indicates `/' * || |`----- bit 2 : /dev_tty0 * || `------ bit 3 : /dev_tty1 * |`-------- bit 4 : /dev_tty2 * `--------- bit 5 : /cmd.tar */ WR_SECT(ROOT_DEV, 2); /************************/ /* secter map */ /************************/ memset(fsbuf, 0, SECTOR_SIZE); int nr_sects = NR_DEFAULT_FILE_SECTS + 1; /* ~~~~~~~~~~~~~~~~~~~|~ | * | `--- bit 0 is reserved * `-------- for `/' */ for (i = 0; i < nr_sects / 8; i++) fsbuf[i] = 0xFF; for (j = 0; j < nr_sects % 8; j++) fsbuf[i] |= (1 << j); WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects); /* zeromemory the rest sector-map */ memset(fsbuf, 0, SECTOR_SIZE); for (i = 1; i < sb.nr_smap_sects; i++) WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i); /* cmd.tar */ /* make sure it'll not be overwritten by the disk log */ assert(INSTALL_START_SECT + INSTALL_NR_SECTS < sb.nr_sects - NR_SECTS_FOR_LOG); int bit_offset = INSTALL_START_SECT - sb.n_1st_sect + 1; /* sect M <-> bit (M - sb.n_1stsect + 1) */ int bit_off_in_sect = bit_offset % (SECTOR_SIZE * 8); int bit_left = INSTALL_NR_SECTS; int cur_sect = bit_offset / (SECTOR_SIZE * 8); RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect); while (bit_left) { int byte_off = bit_off_in_sect / 8; /* this line is ineffecient in a loop, but I don't care */ fsbuf[byte_off] |= 1 << (bit_off_in_sect % 8); bit_left--; bit_off_in_sect++; if (bit_off_in_sect == (SECTOR_SIZE * 8)) { WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect); cur_sect++; RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect); bit_off_in_sect = 0; } } WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect); /************************/ /* inodes */ /************************/ /* inode of `/' */ memset(fsbuf, 0, SECTOR_SIZE); struct inode * pi = (struct inode*)fsbuf; pi->i_mode = I_DIRECTORY; pi->i_size = DIR_ENTRY_SIZE * 5; /* 5 files: * `.', * `dev_tty0', `dev_tty1', `dev_tty2', * `cmd.tar' */ pi->i_start_sect = sb.n_1st_sect; pi->i_nr_sects = NR_DEFAULT_FILE_SECTS; /* inode of `/dev_tty0~2' */ for (i = 0; i < NR_CONSOLES; i++) { pi = (struct inode*)(fsbuf + (INODE_SIZE * (i + 1))); pi->i_mode = I_CHAR_SPECIAL; pi->i_size = 0; pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i); pi->i_nr_sects = 0; } /* inode of `/cmd.tar' */ pi = (struct inode*)(fsbuf + (INODE_SIZE * (NR_CONSOLES + 1))); pi->i_mode = I_REGULAR; pi->i_size = INSTALL_NR_SECTS * SECTOR_SIZE; pi->i_start_sect = INSTALL_START_SECT; pi->i_nr_sects = INSTALL_NR_SECTS; WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects); /************************/ /* `/' */ /************************/ memset(fsbuf, 0, SECTOR_SIZE); struct dir_entry * pde = (struct dir_entry *)fsbuf; pde->inode_nr = 1; strcpy(pde->name, "."); /* dir entries of `/dev_tty0~2' */ for (i = 0; i < NR_CONSOLES; i++) { pde++; pde->inode_nr = i + 2; /* dev_tty0's inode_nr is 2 */ sprintf(pde->name, "dev_tty%d", i); } (++pde)->inode_nr = NR_CONSOLES + 2; sprintf(pde->name, "cmd.tar", i); WR_SECT(ROOT_DEV, sb.n_1st_sect); }
/************************************************************************************************** * mkfs ************************************************************************************************** * <Ring 1> Make an available bzOS FS in the disk. It will * - Write a super block to sector 1. * - Create three special files: dev_tty0, dev_tty1, dev_tty2. * - Create the inode map. * - Create the sector map. * - Create the inodes of the files. * - Create '/', the root directory. *************************************************************************************************/ PRIVATE void mkfs(){ MESSAGE driver_msg; int i, j; int bits_per_sect = SECTOR_SIZE * 8; /* get the geometry of ROOTDEV */ struct part_info geo; driver_msg.type = DEV_IOCTL; driver_msg.DEVICE = MINOR(ROOT_DEV); driver_msg.REQUEST = DIOCTL_GET_GEO; driver_msg.BUF = &geo; driver_msg.PROC_NR = TASK_FS; assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER); send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg); printl("{FS} dev size: %x sectors\n", geo.size); /****************************************************************************************** * Super Block *****************************************************************************************/ struct super_block sb; sb.magic = MAGIC_V1; sb.nr_inodes = bits_per_sect; sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE; sb.nr_sects = geo.size; /* partition size */ sb.nr_imap_sects = 1; sb.nr_smap_sects = sb.nr_sects / bits_per_sect + 1; sb.n_1st_sect = 1 + 1 + /* boot sector & super block */ sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects; sb.root_inode = ROOT_INODE; sb.inode_size = INODE_SIZE; struct inode x; sb.inode_isize_off = (int)&x.i_size - (int)&x; sb.inode_start_off = (int)&x.i_start_sect - (int)&x; sb.dir_ent_size = DIR_ENTRY_SIZE; struct dir_entry de; sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de; sb.dir_ent_fname_off = (int)&de.name - (int)&de; memset(fsbuf, 0x90, SECTOR_SIZE); memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE); /* write the super block using fsbuf */ WR_SECT(ROOT_DEV, 1); /* 这里全是字节偏移量,后面加上00,然后* 2,其实就是(扇区*扇区字节大小) */ printl("{FS} devbase: %x00, sb: %x00, imap: %x00, smap: %x00\n" " inodes: %x00, 1st_sector: %x00\n", geo.base * 2, (geo.base + 1) * 2, (geo.base + 2) * 2, (geo.base + 2 + sb.nr_imap_sects) * 2, (geo.base + 2 + sb.nr_imap_sects + sb.nr_smap_sects) * 2, (geo.base + sb.n_1st_sect) *2 ); /****************************************************************************************** * inode map *****************************************************************************************/ memset(fsbuf, 0, SECTOR_SIZE); /* there are NR_CONSOLES character devices here */ for(i=0; i<NR_CONSOLES + 2; i++){ fsbuf[0] |= 1 << i; } assert(fsbuf[0] == 0x1f);/** * 0001 1111: * bit 0: reserved. * bit 1: the first inode, which indicates '/'. * bit 2: /dev_tty0 * bit 3: /dev_tty1 * bit 4: /dev_tty2 */ WR_SECT(ROOT_DEV, 2); /****************************************************************************************** * sector map *****************************************************************************************/ memset(fsbuf, 0, SECTOR_SIZE); int nr_sects = NR_DEFAULT_FILE_SECTS + 1; /* bit 0 is reserved, root directory */ for(i=0; i<nr_sects / 8; i++){ /* Notify this division */ fsbuf[i] = 0xff; } for(j=0; j<nr_sects % 8; j++){ fsbuf[i] |= (1 << j); } WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects); /* zeromemory the rest sector-map */ memset(fsbuf, 0, SECTOR_SIZE); for(i=1; i<sb.nr_smap_sects; i++){ WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i); } /****************************************************************************************** * inodes *****************************************************************************************/ /* inode of '/' */ memset(fsbuf, 0, SECTOR_SIZE); struct inode* pi = (struct inode*) fsbuf; pi->i_mode = I_DIRECTORY; pi->i_size = DIR_ENTRY_SIZE * 4;/* 4 files: * '.'. * 'dev_tty0', 'dev_tty1', 'dev_tty2' */ pi->i_start_sect = sb.n_1st_sect; pi->i_nr_sects = NR_DEFAULT_FILE_SECTS; /* inode of '/dev_tty0~2' */ for(i=0; i<NR_CONSOLES; i++){ pi = (struct inode*) (fsbuf + (INODE_SIZE * (i + 1))); pi->i_mode = I_CHAR_SPECIAL; pi->i_size = 0; pi->i_start_sect= MAKE_DEV(DEV_CHAR_TTY, i); pi->i_nr_sects = 0; } WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects); /****************************************************************************************** * '/' *****************************************************************************************/ memset(fsbuf, 0, SECTOR_SIZE); struct dir_entry* pde = (struct dir_entry*)fsbuf; pde->inode_nr = 1; strcpy(pde->name, "."); /* dir entries of '/dev_tty0~2' */ for(i=0; i<NR_CONSOLES; i++){ pde ++; pde->inode_nr = i + 2; sprintf(pde->name, "dev_tty%d", i); /* do not use 'vsprintf' */ } WR_SECT(ROOT_DEV, sb.n_1st_sect); }
static void mkfs() { int i; MESSAGE driver_msg; PART_INFO geo; driver_msg.type = DEV_IOCTL; driver_msg.DEVICE = MINOR(ROOT_DEV); driver_msg.REQUEST = DIOCTL_GET_GEO; driver_msg.BUF = &geo; driver_msg.PROC_NR = TASK_FS; send_recv( BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg ); printk("dev size: 0x%x sectors\n", geo.size ); //super block struct d_super_block sb; sb.magic = MAGIC_V1; sb.first_block_table_sect = FIRST_BLOCK_TABLE ; sb.root_inode = ROOT_INODE ; sb.zone_mete_sects = ZONE_METE_SECTS; sb.zone_data_sects = ZONE_DATA_SECTS; struct buffer_head bh ; bh.pdata = (void *)kmalloc( SECTOR_SIZE ); bh.dev = ROOT_DEV; bh.blocknr = FIRST_SUPER_BLOCK; bh.size = 1; memset( bh.pdata, 0x60, SECTOR_SIZE * 2 ); memcpy( bh.pdata, &sb, sizeof(struct d_super_block) ); WR_SECT( &bh ); printk("devbase: 0x%x00, sb:0x%x00, btable:0x%x00, first zone:0x%x00, " "first_zone_mete: 0x%x00, first_zone_data: 0x%x00 \n", geo.base * 2, (geo.base +2) * 2, (geo.base +4) * 2, (geo.base +6) * 2, (geo.base +6) * 2, (geo.base +6 +ZONE_METE_SECTS) *2 ); //block table memset( bh.pdata, 0, SECTOR_SIZE * 2 ); struct d_block_table_entry bt; for( i=0; i<NR_BLOCK_TABLE_ENTRY; i++ ) { bt.block_size = 1 << i; if( i == 0 ) { bt.first_inode_num = 1; } else { struct d_block_table_entry *pbt = (struct d_block_table_entry *)bh.pdata; bt.first_inode_num = pbt[i-1].first_inode_num +pbt[i-1].inode_count ; } bt.free_inode_num = bt.first_inode_num ; bt.inode_count = ZONE_DATA_SECTS / bt.block_size; bt.start_imap_nr = ZONE_ALL_SECTS * i + FIRST_ZONE; bt.start_itable_nr = bt.start_imap_nr + ZONE_IMAP_SECTS; bt.start_data_nr = bt.start_imap_nr + ZONE_METE_SECTS; bt.dev = ROOT_DEV; memcpy( bh.pdata + i * sizeof(struct d_block_table_entry) , &bt, sizeof(struct d_block_table_entry) ); } bh.blocknr = FIRST_BLOCK_TABLE ; WR_SECT( &bh ); //imap memset( bh.pdata, 0, SECTOR_SIZE ); for( i=0; i< (NR_CONSOLES +2); i++ ) ((u8 *)(bh.pdata))[0] |= 1<< i; assert( ((u8 *)(bh.pdata))[0] == 0x1f ); bh.blocknr = FIRST_ZONE ; bh.size = 0; WR_SECT( &bh ); memset( bh.pdata, 0, SECTOR_SIZE ); ((u8 *)(bh.pdata))[0] = 0xff; bh.blocknr = bt.start_imap_nr ; bh.size = 0; WR_SECT( &bh ); memset( bh.pdata, 0, SECTOR_SIZE ); for( i=1; i<bt.inode_count/SECTOR_SIZE + 1; i++ ) { bh.blocknr = FIRST_ZONE + i; WR_SECT( &bh ); } //inodes memset( bh.pdata, 0, SECTOR_SIZE ); struct d_inode *pi = (struct d_inode *)bh.pdata; pi->mode = I_DIRECTORY; pi->size = 0; pi->start_data_sect = FIRST_ZONE + ZONE_METE_SECTS ; pi->next_inode_id = 0; pi->nlinks = 1; pi->bitmap = 1; memcpy( pi->name, "/", sizeof("/") ); for( i=0; i<NR_CONSOLES; i++ ) { pi++; pi->mode = I_CHAR_SPECIAL; pi->size = 0; pi->start_data_sect = MAKE_DEV( DEV_CHAR_TTY, i); pi->next_inode_id = 0; pi->nlinks = 1; pi->bitmap = 0; sprintf( pi->name, "dev_tty%d", i+1 ); } bh.blocknr = FIRST_ZONE + ZONE_IMAP_SECTS ; WR_SECT( &bh ); memset( bh.pdata, 0, SECTOR_SIZE ); char *names[] ={ "hello", "ls", "cat", "touch", "write", "mkdir", "rm" }; const int cmd_cnt = 5; pi = (struct d_inode *)bh.pdata; for( i=0; i<cmd_cnt; i++ ) { pi->mode = I_REGULAR; pi->size = 6; pi->start_data_sect = bt.start_data_nr + i*bt.block_size ; pi->next_inode_id = 0; pi->nlinks = 1; pi->bitmap = 0; sprintf( pi->name, names[i] ); pi++; } bh.blocknr = bt.start_itable_nr; WR_SECT( &bh ); //memset( bh.pdata, 0x99, SECTOR_SIZE ); //bh.blocknr = bt.start_data_nr; //WR_SECT( &bh ); //d_bree_node of "/" memset( bh.pdata, 0, SECTOR_SIZE ); bh.blocknr = FIRST_ZONE + ZONE_METE_SECTS ; struct d_name_value_pair kv_pair[] ={ { ".", 1 }, { "..", 1 }, { "dev_tty1", 2 }, { "dev_tty2", 3 }, { "dev_tty3", 4 }, { names[0], bt.first_inode_num }, { names[1], bt.first_inode_num + 1}, { names[2], bt.first_inode_num + 2}, { names[3], bt.first_inode_num + 3}, { names[4], bt.first_inode_num + 4}, /* { names[5], bt.first_inode_num + 5}, { names[6], bt.first_inode_num + 6}, */ }; btree_new_root( &bh, kv_pair, sizeof(kv_pair)/sizeof(kv_pair[0]) ); WR_SECT( &bh ); kfree( bh.pdata ); }
void mkfs() { MESSAGE driver_msg; int i, j; int bits_per_sect = SECTOR_SIZE * 8; /* 8 bits per byte */ struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; fsbuf = (u8 *)memman_alloc(memman,FSBUF_SIZE); /* get the geometry of ROOTDEV */ struct part_info geo; //driver_msg.type = DEV_IOCTL; //driver_msg.DEVICE = MINOR(ROOT_DEV); //driver_msg.REQUEST = DIOCTL_GET_GEO; //driver_msg.BUF = &geo; //driver_msg.PROC_NR = 0; //TASK_FS //hd_ioctl(&driver_msg); geo.size = 20097; debug("dev size: 0x%x sectors", geo.size); /************************/ /* super block */ /************************/ struct super_block sb; sb.magic = MAGIC_V1; sb.nr_inodes = bits_per_sect; //512 * 8 = 4096个i_node sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE; //i_node所占用的扇区数=4096 * 32 / 512 = 32 sb.nr_sects = geo.size; /* partition size in sector, 这个分区总共有多少个扇区 */ sb.nr_imap_sects = 1; //inode-map所占用的扇区数 sb.nr_smap_sects = sb.nr_sects / bits_per_sect + 1; //secotr-map所占用的扇区数 sb.n_1st_sect = 1 + 1 + /* boot sector & super block */ sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects; //数据区的第一个扇区编号 sb.root_inode = ROOT_INODE; //root directory占用的inode编号 sb.inode_size = INODE_SIZE; struct inode x; sb.inode_isize_off= (int)&x.i_size - (int)&x; //i_size在i-node结构中的偏移 sb.inode_start_off= (int)&x.i_start_sect - (int)&x; //start_sect在i-node结构中的偏移 sb.dir_ent_size = DIR_ENTRY_SIZE; //DIR_ENTRY结构的大小 struct dir_entry de; sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de; //inode_nr在dir_entry中的偏移 sb.dir_ent_fname_off = (int)&de.name - (int)&de; //name在dir_entry中的偏移 memset1(fsbuf, 0x90, SECTOR_SIZE); memcpy1(fsbuf, &sb, SUPER_BLOCK_SIZE); debug("sb.n_1st_sect = %d",sb.n_1st_sect); /* write the super block */ WR_SECT(ROOT_DEV, 1); /************************/ /* inode map */ /************************/ memset1(fsbuf, 0, SECTOR_SIZE); for (i = 0; i < (NR_CONSOLES + 2); i++) fsbuf[0] |= 1 << i; assert(fsbuf[0] == 0x1F);/* 0001 1111 : // * | |||| // * | |||`--- bit 0 : reserved // * | ||`---- bit 1 : the first inode, // * | || which indicates `/' // * | |`----- bit 2 : /dev_tty0 // * | `------ bit 3 : /dev_tty1 // * `-------- bit 4 : /dev_tty2 // */ WR_SECT(ROOT_DEV, 2); /************************/ /* secter map */ /************************/ memset1(fsbuf, 0, SECTOR_SIZE); int nr_sects = NR_DEFAULT_FILE_SECTS + 1; /* ~~~~~~~~~~~~~~~~~~~|~ | * | `--- bit 0 is reserved * `-------- for `/' */ for (i = 0; i < nr_sects / 8; i++) fsbuf[i] = 0xFF; for (j = 0; j < nr_sects % 8; j++) fsbuf[i] |= (1 << j); WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects); /* zeromemory the rest sector-map */ memset1(fsbuf, 0, SECTOR_SIZE); for (i = 1; i < sb.nr_smap_sects; i++) WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i); /************************/ /* inodes */ /************************/ /* inode of `/' */ memset1(fsbuf, 0, SECTOR_SIZE); struct inode * pi = (struct inode*)fsbuf; pi->i_mode = I_DIRECTORY; pi->i_size = DIR_ENTRY_SIZE * 4; /* 4 files: * `.', * `dev_tty0', `dev_tty1', `dev_tty2', */ pi->i_start_sect = sb.n_1st_sect; pi->i_nr_sects = NR_DEFAULT_FILE_SECTS; /* inode of `/dev_tty0~2' */ for (i = 0; i < NR_CONSOLES; i++) { pi = (struct inode*)(fsbuf + (INODE_SIZE * (i + 1))); pi->i_mode = I_CHAR_SPECIAL; pi->i_size = 0; pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i); debug("pi->i_start_sect = %d",MAKE_DEV(DEV_CHAR_TTY, i)); pi->i_nr_sects = 0; } WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects); /************************/ /* `/' */ /************************/ memset1(fsbuf, 0, SECTOR_SIZE); struct dir_entry * pde = (struct dir_entry *)fsbuf; pde->inode_nr = 1; strcpy(pde->name, "."); /* dir entries of `/dev_tty0~2' */ for (i = 0; i < NR_CONSOLES; i++) { pde++; pde->inode_nr = i + 2; /* dev_tty0's inode_nr is 2 */ sprintf(pde->name, "dev_tty%d", i); debug("pde->inode_nr = %d",pde->inode_nr); debug("pde->name = %s",pde->name); } WR_SECT(ROOT_DEV, sb.n_1st_sect); }
/** * <Ring 1> Make a available Orange'S FS in the disk. It will * - Write a super block to sector 1. * - Create three special files: dev_tty0, dev_tty1, dev_tty2 * - Create the inode map * - Create the sector map * - Create the inodes of the files * - Create `/', the root directory *****************************************************************************/ PRIVATE void mkfs() { MESSAGE driver_msg; int i, j; int bits_per_sect = SECTOR_SIZE * 8; /* 8 bits per byte */ /* get the geometry of ROOTDEV */ struct part_info geo; driver_msg.type = DEV_IOCTL; driver_msg.DEVICE = MINOR(ROOT_DEV); driver_msg.REQUEST = DIOCTL_GET_GEO; driver_msg.BUF = &geo; driver_msg.PROC_NR = TASK_FS; assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER); send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg); printl("dev size: 0x%x sectors\n", geo.size); /************************/ /* super block */ /************************/ struct super_block sb; sb.magic = MAGIC_V1; sb.nr_inodes = bits_per_sect; sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE; sb.nr_sects = geo.size; /* partition size in sector */ sb.nr_imap_sects = 1; sb.nr_smap_sects = sb.nr_sects / bits_per_sect + 1; sb.n_1st_sect = 1 + 1 + /* boot sector & super block */ sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects; sb.root_inode = ROOT_INODE; sb.inode_size = INODE_SIZE; struct inode x; sb.inode_isize_off= (int)&x.i_size - (int)&x; sb.inode_start_off= (int)&x.i_start_sect - (int)&x; sb.dir_ent_size = DIR_ENTRY_SIZE; struct dir_entry de; sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de; sb.dir_ent_fname_off = (int)&de.name - (int)&de; memset(fsbuf, 0x90, SECTOR_SIZE); memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE); /* write the super block */ WR_SECT(ROOT_DEV, 1); printl("devbase:0x%x00, sb:0x%x00, imap:0x%x00, smap:0x%x00\n" " inodes:0x%x00, 1st_sector:0x%x00\n", geo.base * 2, (geo.base + 1) * 2, (geo.base + 1 + 1) * 2, (geo.base + 1 + 1 + sb.nr_imap_sects) * 2, (geo.base + 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects) * 2, (geo.base + sb.n_1st_sect) * 2); /************************/ /* inode map */ /************************/ memset(fsbuf, 0, SECTOR_SIZE); for (i = 0; i < (NR_CONSOLES + 2); i++) fsbuf[0] |= 1 << i; assert(fsbuf[0] == 0x1F);/* 0001 1111 : * | |||| * | |||`--- bit 0 : reserved * | ||`---- bit 1 : the first inode, * | || which indicates `/' * | |`----- bit 2 : /dev_tty0 * | `------ bit 3 : /dev_tty1 * `-------- bit 4 : /dev_tty2 */ WR_SECT(ROOT_DEV, 2); /************************/ /* secter map */ /************************/ memset(fsbuf, 0, SECTOR_SIZE); int nr_sects = NR_DEFAULT_FILE_SECTS + 1; /* ~~~~~~~~~~~~~~~~~~~|~ | * | `--- bit 0 is reserved * `-------- for `/' */ for (i = 0; i < nr_sects / 8; i++) fsbuf[i] = 0xFF; for (j = 0; j < nr_sects % 8; j++) fsbuf[i] |= (1 << j); WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects); /* zeromemory the rest sector-map */ memset(fsbuf, 0, SECTOR_SIZE); for (i = 1; i < sb.nr_smap_sects; i++) WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i); /************************/ /* inodes */ /************************/ /* inode of `/' */ memset(fsbuf, 0, SECTOR_SIZE); struct inode * pi = (struct inode*)fsbuf; pi->i_mode = I_DIRECTORY; pi->i_size = DIR_ENTRY_SIZE * 4; /* 4 files: * `.', * `dev_tty0', `dev_tty1', `dev_tty2', */ pi->i_start_sect = sb.n_1st_sect; pi->i_nr_sects = NR_DEFAULT_FILE_SECTS; /* inode of `/dev_tty0~2' */ for (i = 0; i < NR_CONSOLES; i++) { pi = (struct inode*)(fsbuf + (INODE_SIZE * (i + 1))); pi->i_mode = I_CHAR_SPECIAL; pi->i_size = 0; pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i); pi->i_nr_sects = 0; } WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects); /************************/ /* `/' */ /************************/ memset(fsbuf, 0, SECTOR_SIZE); struct dir_entry * pde = (struct dir_entry *)fsbuf; pde->inode_nr = 1; strcpy(pde->name, "."); /* dir entries of `/dev_tty0~2' */ for (i = 0; i < NR_CONSOLES; i++) { pde++; pde->inode_nr = i + 2; /* dev_tty0's inode_nr is 2 */ sprintf(pde->name, "dev_tty%d", i); } WR_SECT(ROOT_DEV, sb.n_1st_sect); }
PRIVATE void mkfs() { MESSAGE driver_msg; int bits_per_sect = SECTOR_SIZE * 8; struct part_info geo; driver_msg.type = DEV_IOCTL; driver_msg.DEVICE = MINOR(ROOT_DEV); driver_msg.REQUEST = DIOCTL_GET_GEO; driver_msg.BUF = &geo; driver_msg.PROC_NR = TASK_FS; assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER); send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg); printl("dev base: 0x%x, dev size: 0x%x sectors\n", geo.base, geo.size); /***********************/ /* super block */ /***********************/ struct super_block sb; sb.magic = MAGIC_V1; sb.nr_inodes = bits_per_sect; sb.nr_sects = geo.size; sb.nr_imap_sects = 1; sb.nr_smap_sects = sb.nr_sects / bits_per_sect + 1; sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE; sb.n_1st_sect = 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects; sb.root_inode = ROOT_INODE; sb.inode_size = INODE_SIZE; sb.inode_isize_off = offsetof(struct inode, i_size); sb.inode_start_off = offsetof(struct inode, i_start_sect); sb.dir_ent_size = DIR_ENTRY_SIZE; sb.dir_ent_inode_off = offsetof(struct dir_entry, inode_nr); sb.dir_ent_fname_off = offsetof(struct dir_entry, name); memset(fsbuf, 0x90, SECTOR_SIZE); memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE); WR_SECT(ROOT_DEV, 1); // write the super block printl( "devbase: 0x%x00, sb: 0x%x00, imap: 0x%x00, smap: 0x%x00\n" " inodes: 0x%x00, 1st_sector: 0x%x00\n", geo.base * 2, (geo.base + 1) * 2, (geo.base + 1 + 1) * 2, (geo.base + 1 + 1 + sb.nr_imap_sects) * 2, (geo.base + 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects) * 2, (geo.base + sb.n_1st_sect) * 2 ); /***********************/ /* inode Map */ /***********************/ memset(fsbuf, 0x0, SECTOR_SIZE); for (int i = 0; i < (NR_CONSOLES + 3); i++) fsbuf[0] |= 1 << i; assert(fsbuf[0] == 0x3F); /* 0011 1111 * || |||`- bit 0 : reserved * || ||`-- bit 1 : the frist inode which indicates '/' * || |`--- bit 2 : /dev_tty0 * || `---- bit 3 : /dev_tty1 * |`------ bit 4 : /dev_tty2 * `------- bit 5 : /cmd.tar */ WR_SECT(ROOT_DEV, 2); /***********************/ /* sector Map */ /***********************/ memset(fsbuf, 0x0, SECTOR_SIZE); int nr_sects = NR_DEFAULT_FILE_SECTS + 1; int i; for (i = 0; i < nr_sects / 8; i++) fsbuf[i] = 0xFF; for (int j = 0; j < nr_sects % 8; j++) fsbuf[i] |= (1 << i); WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects); memset(fsbuf, 0x0, SECTOR_SIZE); for (int i = 1; i < sb.nr_smap_sects; i++) WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i); /* cmd.tar */ int bit_offset = INSTALL_START_SECT - sb.n_1st_sect + 1; // sect M <-> bit (M - sb.n_1stsect + 1) int bit_off_in_sect = bit_offset % (SECTOR_SIZE * 8); int bit_left = INSTALL_NR_SECTS; int cur_sect = bit_offset / (SECTOR_SIZE * 8); RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect); while (bit_left) { int byte_off = bit_off_in_sect / 8; /* this line is ineffecient in a loop, but I don't care */ fsbuf[byte_off] |= 1 << (bit_off_in_sect % 8); bit_left--; bit_off_in_sect++; if (bit_off_in_sect == (SECTOR_SIZE * 8)) { WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect); cur_sect++; RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect); bit_off_in_sect = 0; } } WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect); /***********************/ /* inodes */ /***********************/ memset(fsbuf, 0x0, SECTOR_SIZE); struct inode *pi = (struct inode *)fsbuf; pi->i_mode = I_DIRECTORY; pi->i_size = DIR_ENTRY_SIZE * 5; // 5 files pi->i_start_sect = sb.n_1st_sect; pi->i_nr_sects = NR_DEFAULT_FILE_SECTS; for (int i = 0; i < NR_CONSOLES; i++) { pi = (struct inode *)(fsbuf + (INODE_SIZE * (i + 1))); pi->i_mode = I_CHAR_SPECIAL; pi->i_size = 0; pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i); pi->i_nr_sects = 0; } /* inode of `/cmd.tar' */ pi = (struct inode*)(fsbuf + (INODE_SIZE * (NR_CONSOLES + 1))); pi->i_mode = I_REGULAR; pi->i_size = INSTALL_NR_SECTS * SECTOR_SIZE; pi->i_start_sect = INSTALL_START_SECT; pi->i_nr_sects = INSTALL_NR_SECTS; WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects); /***********************/ /* '/' */ /***********************/ memset(fsbuf, 0x0, SECTOR_SIZE); struct dir_entry *pde = (struct dir_entry *)fsbuf; pde->inode_nr = 1; strcpy(pde->name, "."); for (int i = 0; i < NR_CONSOLES; i++) { pde++; pde->inode_nr = i + 2; sprintf(pde->name, "dev_tty%d", i); } (++pde)->inode_nr = NR_CONSOLES + 2; strcpy(pde->name, "cmd.tar"); WR_SECT(ROOT_DEV, sb.n_1st_sect); }