Exemplo n.º 1
0
/**
 * <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);
}
Exemplo n.º 2
0
/**************************************************************************************************
 * 					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);

}
Exemplo n.º 3
0
Arquivo: fs.c Projeto: qpig/sfs
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 );
}
Exemplo n.º 4
0
Arquivo: fs.c Projeto: jjhlzn/haribote
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);
}
Exemplo n.º 5
0
/**
 * <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);
}
Exemplo n.º 6
0
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);
}