Exemple #1
0
/*
 * filesystem operations
 */
static s32_t cpiofs_mount(struct mount * m, char * dev, s32_t flag)
{
	struct blkdev * blk;
	struct cpio_newc_header header;

	if(dev == NULL)
		return EINVAL;

	blk = (struct blkdev *)m->m_dev;
	if(!blk)
		return EACCES;

	if(get_blkdev_total_size(blk) <= sizeof(struct cpio_newc_header))
		return EINTR;

	if(bio_read(blk, (u8_t *)(&header), 0, sizeof(struct cpio_newc_header)) != sizeof(struct cpio_newc_header))
		return EIO;

	if(strncmp((const char *)(header.c_magic), (const char *)"070701", 6) != 0)
		return EINVAL;

	m->m_flags = (flag & MOUNT_MASK) | MOUNT_RDONLY;
	m->m_root->v_data = 0;
	m->m_data = NULL;

	return 0;
}
Exemple #2
0
static s32_t devfs_lookup(struct vnode * dnode, char * name, struct vnode * node)
{
	struct device * dev;
	struct chrdev * chr;
	struct blkdev * blk;

	dev = search_device(name);
	if(dev == NULL)
		return -1;

	if(dev->type == CHAR_DEVICE)
	{
		chr = (struct chrdev *)(dev->priv);

		node->v_type = VCHR;
		node->v_size = 0;
	}
	else if(dev->type == BLOCK_DEVICE)
	{
		blk = (struct blkdev *)(dev->priv);

		node->v_type = VBLK;
		node->v_size = get_blkdev_total_size(blk);
	}
	else
	{
		return -1;
	}

	node->v_data = (void *)dev;
	node->v_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;

	return 0;
}
Exemple #3
0
/*
 * filesystem operations
 */
static s32_t fatfs_mount(struct mount_t * m, char * dev, s32_t flag)
{
	struct fatfs_mount_data * md;
	struct blkdev_t * blk;
	struct fat_boot_sector fbs;
	u32_t sector_size;
	u32_t tmp;

	if(dev == NULL)
		return EINVAL;

	blk = (struct blkdev_t *)m->m_dev;
	if(!blk || !blk->info)
		return ENODEV;

	if(get_blkdev_total_size(blk) <= sizeof(struct fat_boot_sector))
		return EINTR;

	if(block_read(blk, (u8_t *)(&fbs), 0, sizeof(struct fat_boot_sector)) != sizeof(struct fat_boot_sector))
		return EIO;

	/*
	 * check both signature (0x55, 0xaa)
	 */
	if((fbs.signature[0] != 0x55) || fbs.signature[1] != 0xaa)
		return EINVAL;

	/* the logical sector size (bytes 11-12) is a power of two, at least 512 */
	sector_size = (fbs.bytes_per_sector[1] << 8) | fbs.bytes_per_sector[0];
	if( (sector_size < 512) || (!is_power_of_2(sector_size)) )
		return EINVAL;

	/* the cluster size (byte 13) is a power of two */
	if(! is_power_of_2(fbs.sectors_per_cluster))
		return EINVAL;

	/* the number of reserved sectors (bytes 14-15) is nonzero */
	tmp = (fbs.reserved_sectors[1] << 8) | fbs.reserved_sectors[0];
	if(tmp == 0)
		return EINVAL;

	/* the number of fats (byte 16) is nonzero */
	if(fbs.num_of_fats == 0x00)
		return EINVAL;

	/* the number of root directory entries (bytes 17-18) must be sector aligned */
	tmp = (fbs.root_entries[1] << 8) | fbs.root_entries[0];
	if(tmp % (sector_size / sizeof(struct fat_dirent)) != 0)
		return EINVAL;

	/* the sector per track (byte 24-25) is nonzero */
	tmp = (fbs.sectors_per_track[1] << 8) | fbs.sectors_per_track[0];
	if(tmp == 0)
		return EINVAL;

	/* the number of heads (byte 26-27) is nonzero */
	tmp = (fbs.num_of_heads[1] << 8) | fbs.num_of_heads[0];
	if(tmp == 0)
		return EINVAL;

	md = malloc(sizeof(struct fatfs_mount_data));
	if(!md)
		return ENOMEM;

	/* determine the type of fat */
	if( strncmp((const s8_t *)fbs.x.fat12.fs_type, (const s8_t *)"FAT12   ", 8) == 0 )
	{
		md->type = FAT_TYPE_FAT12;
	}
	else if( strncmp((const s8_t *)fbs.x.fat16.fs_type, (const s8_t *)"FAT16   ", 8) == 0 )
	{
		md->type = FAT_TYPE_FAT16;
	}
	else if( strncmp((const s8_t *)fbs.x.fat32.fs_type, (const s8_t *)"FAT32   ", 8) == 0 )
	{
		md->type = FAT_TYPE_FAT32;
	}
	else
	{
		free(md);
		return EINVAL;
	}

	/* build mount data */
	switch(md->type)
	{
	case FAT_TYPE_FAT12:
		md->sector_size = sector_size;
		md->sectors_per_cluster = fbs.sectors_per_cluster;
		md->cluster_size = md->sectors_per_cluster * md->sector_size;
		tmp = ((fbs.hidden_sectors[3] << 24) | (fbs.hidden_sectors[2] << 16) | (fbs.hidden_sectors[1] << 8) | (fbs.hidden_sectors[0] << 0));
		md->fat_start = tmp + ((fbs.reserved_sectors[1] << 8) | (fbs.reserved_sectors[0] << 0));
		md->root_start = md->fat_start + (fbs.num_of_fats * ((fbs.sectors_per_fat[1] << 8) | (fbs.sectors_per_fat[0] << 0)));
		md->data_start = md->root_start + ( ((fbs.root_entries[1] << 8) | (fbs.root_entries[0] << 0)) / (sector_size / sizeof(struct fat_dirent)) );

		tmp = ((fbs.total_sectors[1] << 8) | (fbs.total_sectors[0] << 0));
		if(tmp == 0)
			tmp = ((fbs.big_total_sectors[3] << 24) | (fbs.big_total_sectors[2] << 16) | (fbs.big_total_sectors[1] << 8) | (fbs.big_total_sectors[0] << 0));

		if(tmp == 0)
		{
			free(md);
			return EINVAL;
		}

		md->last_cluster = (tmp - md->data_start) / md->sectors_per_cluster + 2;
		md->free_scan = 2;
		md->fat_mask = 0x00000fff;
		md->fat_eof = 0xffffffff & 0x00000fff;
		break;

	case FAT_TYPE_FAT16:
		md->sector_size = sector_size;
		md->sectors_per_cluster = fbs.sectors_per_cluster;
		md->cluster_size = md->sectors_per_cluster * md->sector_size;
		tmp = ((fbs.hidden_sectors[3] << 24) | (fbs.hidden_sectors[2] << 16) | (fbs.hidden_sectors[1] << 8) | (fbs.hidden_sectors[0] << 0));
		md->fat_start = tmp + ((fbs.reserved_sectors[1] << 8) | (fbs.reserved_sectors[0] << 0));
		md->root_start = md->fat_start + (fbs.num_of_fats * ((fbs.sectors_per_fat[1] << 8) | (fbs.sectors_per_fat[0] << 0)));
		md->data_start = md->root_start + ( ((fbs.root_entries[1] << 8) | (fbs.root_entries[0] << 0)) / (sector_size / sizeof(struct fat_dirent)) );

		tmp = ((fbs.total_sectors[1] << 8) | (fbs.total_sectors[0] << 0));
		if(tmp == 0)
			tmp = ((fbs.big_total_sectors[3] << 24) | (fbs.big_total_sectors[2] << 16) | (fbs.big_total_sectors[1] << 8) | (fbs.big_total_sectors[0] << 0));

		if(tmp == 0)
		{
			free(md);
			return EINVAL;
		}

		md->last_cluster = (tmp - md->data_start) / md->sectors_per_cluster + 2;
		md->free_scan = 2;
		md->fat_mask = 0x0000ffff;
		md->fat_eof = 0xffffffff & 0x0000ffff;
		break;

	case FAT_TYPE_FAT32:
		md->sector_size = sector_size;
		md->sectors_per_cluster = fbs.sectors_per_cluster;
		md->cluster_size = md->sectors_per_cluster * md->sector_size;
		tmp = ((fbs.hidden_sectors[3] << 24) | (fbs.hidden_sectors[2] << 16) | (fbs.hidden_sectors[1] << 8) | (fbs.hidden_sectors[0] << 0));
		md->fat_start = tmp + ((fbs.reserved_sectors[1] << 8) | (fbs.reserved_sectors[0] << 0));
		md->root_start = md->fat_start + (fbs.num_of_fats * ((fbs.x.fat32.sectors_per_fat_32[3] << 24) | (fbs.x.fat32.sectors_per_fat_32[2] << 16) | (fbs.x.fat32.sectors_per_fat_32[1] << 8) | (fbs.x.fat32.sectors_per_fat_32[0] << 0)));

		md->data_start = md->root_start + 1;

		break;

	default:
		free(md);
		return EINVAL;
	}

	md->io_buf = malloc(md->cluster_size);
	if(!md->io_buf)
	{
		free(md);
		return ENOMEM;
	}

	md->fat_buf = malloc(md->sector_size * 2);
	if(!md->fat_buf)
	{
		free(md->io_buf);
		free(md);
		return ENOMEM;
	}

	md->dir_buf = malloc(md->sector_size);
	if(!md->dir_buf)
	{
		free(md->fat_buf);
		free(md->io_buf);
		free(md);
		return ENOMEM;
	}

	md->blk = blk;
	m->m_flags = flag & MOUNT_MASK;
	m->m_data = md;

	// for debug
	switch(md->type)
	{
	case FAT_TYPE_FAT12:
		break;
	case FAT_TYPE_FAT16:
		break;
	case FAT_TYPE_FAT32:
		break;
	default:
		break;
	}

	LOG("sector size: %ld\r\n", md->sector_size);
	LOG("sectors per cluster: %ld\r\n", md->sectors_per_cluster);
	LOG("cluster size: %ld\r\n", md->cluster_size);

	LOG("fat start: %ld\r\n", md->fat_start);
	LOG("root start: %ld\r\n", md->root_start);
	LOG("data start: %ld\r\n", md->data_start);

	LOG("last cluster: %ld\r\n", md->last_cluster);
	LOG("free scan: %ld\r\n", md->free_scan);

	LOG("fat mask: 0x%08x\r\n", md->fat_mask);
	LOG("fat eof: 0x%08x\r\n", md->fat_eof);

	return 0;
}