Ejemplo n.º 1
0
/* 将inode写入到分区part */
void inode_sync(struct partition* part, struct inode* inode, void* io_buf) {	 // io_buf是用于硬盘io的缓冲区
   uint8_t inode_no = inode->i_no;
   struct inode_position inode_pos;
   inode_locate(part, inode_no, &inode_pos);	       // inode位置信息会存入inode_pos
   ASSERT(inode_pos.sec_lba <= (part->start_lba + part->sec_cnt));
   
   /* 硬盘中的inode中的成员inode_tag和i_open_cnts是不需要的,
    * 它们只在内存中记录链表位置和被多少进程共享 */
   struct inode pure_inode;
   memcpy(&pure_inode, inode, sizeof(struct inode));

   /* 以下inode的三个成员只存在于内存中,现在将inode同步到硬盘,清掉这三项即可 */
   pure_inode.i_open_cnts = 0;
   pure_inode.write_deny = false;	 // 置为false,以保证在硬盘中读出时为可写
   pure_inode.inode_tag.prev = pure_inode.inode_tag.next = NULL;

   char* inode_buf = (char*)io_buf;
   if (inode_pos.two_sec) {	    // 若是跨了两个扇区,就要读出两个扇区再写入两个扇区
   /* 读写硬盘是以扇区为单位,若写入的数据小于一扇区,要将原硬盘上的内容先读出来再和新数据拼成一扇区后再写入  */
      ide_read(part->my_disk, inode_pos.sec_lba, inode_buf, 2);	// inode在format中写入硬盘时是连续写入的,所以读入2块扇区

   /* 开始将待写入的inode拼入到这2个扇区中的相应位置 */
      memcpy((inode_buf + inode_pos.off_size), &pure_inode, sizeof(struct inode));
   
   /* 将拼接好的数据再写入磁盘 */
      ide_write(part->my_disk, inode_pos.sec_lba, inode_buf, 2);
   } else {			    // 若只是一个扇区
      ide_read(part->my_disk, inode_pos.sec_lba, inode_buf, 1);
      memcpy((inode_buf + inode_pos.off_size), &pure_inode, sizeof(struct inode));
      ide_write(part->my_disk, inode_pos.sec_lba, inode_buf, 1);
   }
}
Ejemplo n.º 2
0
/* 在part分区内的pdir目录内寻找名为name的文件或目录,
 * 找到后返回true并将其目录项存入dir_e,否则返回false */
bool search_dir_entry(struct partition* part, struct dir* pdir, \
		     const char* name, struct dir_entry* dir_e) {
   uint32_t block_cnt = 140;	 // 12个直接块+128个一级间接块=140块

   /* 12个直接块大小+128个间接块,共560字节 */
   uint32_t* all_blocks = (uint32_t*)sys_malloc(48 + 512);
   if (all_blocks == NULL) {
      printk("search_dir_entry: sys_malloc for all_blocks failed");
      return false;
   }

   uint32_t block_idx = 0;
   while (block_idx < 12) {
      all_blocks[block_idx] = pdir->inode->i_sectors[block_idx];
      block_idx++;
   }
   block_idx = 0;

   if (pdir->inode->i_sectors[12] != 0) {	// 若含有一级间接块表
      ide_read(part->my_disk, pdir->inode->i_sectors[12], all_blocks + 12, 1);
   }
/* 至此,all_blocks存储的是该文件或目录的所有扇区地址 */

   /* 写目录项的时候已保证目录项不跨扇区,
    * 这样读目录项时容易处理, 只申请容纳1个扇区的内存 */
   uint8_t* buf = (uint8_t*)sys_malloc(SECTOR_SIZE);
   struct dir_entry* p_de = (struct dir_entry*)buf;	    // p_de为指向目录项的指针,值为buf起始地址
   uint32_t dir_entry_size = part->sb->dir_entry_size;
   uint32_t dir_entry_cnt = SECTOR_SIZE / dir_entry_size;   // 1扇区内可容纳的目录项个数

   /* 开始在所有块中查找目录项 */
   while (block_idx < block_cnt) {		  
   /* 块地址为0时表示该块中无数据,继续在其它块中找 */
      if (all_blocks[block_idx] == 0) {
	 block_idx++;
	 continue;
      }
      ide_read(part->my_disk, all_blocks[block_idx], buf, 1);

      uint32_t dir_entry_idx = 0;
      /* 遍历扇区中所有目录项 */
      while (dir_entry_idx < dir_entry_cnt) {
	 /* 若找到了,就直接复制整个目录项 */
	 if (!strcmp(p_de->filename, name)) {
	    memcpy(dir_e, p_de, dir_entry_size);
	    sys_free(buf);
	    sys_free(all_blocks);
	    return true;
	 }
	 dir_entry_idx++;
	 p_de++;
      }
      block_idx++;
      p_de = (struct dir_entry*)buf;  // 此时p_de已经指向扇区内最后一个完整目录项了,需要恢复p_de指向为buf
      memset(buf, 0, SECTOR_SIZE);	  // 将buf清0,下次再用
   }
   sys_free(buf);
   sys_free(all_blocks);
   return false;
}
Ejemplo n.º 3
0
Archivo: bc.c Proyecto: evilzone/CSE506
// Fault any disk block that is read or written in to memory by
// loading it from disk.
// Hint: Use ide_read and BLKSECTS.
static void
bc_pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
	int r;

	// Check that the fault was within the block cache region
	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("page fault in FS: eip %08x, va %08x, err %04x",
		      utf->utf_rip, addr, utf->utf_err);

	// Sanity check the block number.
	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	// Allocate a page in the disk map region, read the contents
	// of the block from the disk into that page, and mark the
	// page not-dirty (since reading the data from disk will mark
	// the page dirty).
	//
	// LAB 5: Your code here

	void *dst_addr = (void *) ROUNDDOWN(addr, BLKSIZE);
	r = sys_page_alloc(thisenv->env_id, dst_addr, PTE_U | PTE_P | PTE_W);

	// Project addition --> Transparent disk decryption (called only if disk block
	// is encrypted). Bitmap block has been left out of encryption, bitmap block data is tightly
	// bound in other routines, so can't encrypt.
	 if(blockno == 2)
	     ide_read(blockno * BLKSECTS, dst_addr, BLKSECTS);
	else if (blockno == 1) /* || (blockno == 2)) */
	 {
		 if(!s_encrypted)
			 ide_read(blockno * BLKSECTS, dst_addr, BLKSECTS);
		 else
		 {
			 r = transparent_disk_decrypt(blockno, dst_addr);
			 if(r)
				 return;

		 }

	 }
	 else 
	 { 
		 r = transparent_disk_decrypt(blockno, dst_addr);
		 if(r)
			 return;
	 }

	// panic("bc_pgfault not implemented");

	// Check that the block we read was allocated. (exercise for
	// the reader: why do we do this *after* reading the block
	// in?)
	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);
}
Ejemplo n.º 4
0
void ide_delay(uint8_t channel)
{
  /* Each call delays 100 ns */
  ide_read(channel, IDE_REGISTER_STATUS);
  ide_read(channel, IDE_REGISTER_STATUS);
  ide_read(channel, IDE_REGISTER_STATUS);
  ide_read(channel, IDE_REGISTER_STATUS);
}
Ejemplo n.º 5
0
Archivo: elf.c Proyecto: cjc96/cjcPA
uint32_t loader() {
	Elf32_Ehdr *elf;
	Elf32_Phdr *ph = NULL;

	uint8_t buf[4096];

#ifdef HAS_DEVICE
	ide_read(buf, ELF_OFFSET_IN_DISK, 4096);
#else
	ramdisk_read(buf, ELF_OFFSET_IN_DISK, 4096);
#endif

	elf = (void*)buf;

	/* fix the magic number with the correct one */
	const uint32_t elf_magic = 0x464c457f;
	uint32_t *p_magic = (void *)buf;
	nemu_assert(*p_magic == elf_magic);
	/* Load each program segment */
	int i;
	for(i=0;i<elf->e_phnum;i++ ) {
		/* Scan the program header table, load each segment into memory */
		ph=(void *)(elf->e_phoff + i * elf->e_phentsize + buf);
		if(ph->p_type == PT_LOAD) {
		//Log("success");
#ifdef IA32_PAGE
			/* Record the program break for future use. */
			extern uint32_t brk;
			uint32_t new_brk = ph->p_vaddr + ph->p_memsz - 1;
     		if(brk < new_brk) { brk = new_brk; }
			uint32_t pa=mm_malloc(ph->p_vaddr,ph->p_memsz);
#endif  
#ifndef HAS_DEVICE
			ramdisk_read((void*)pa, ELF_OFFSET_IN_DISK + ph->p_offset, ph->p_filesz); 
#else
			ide_read((void*)pa, ELF_OFFSET_IN_DISK + ph->p_offset, ph->p_filesz);
#endif
			memset((void*)(pa + ph->p_filesz), 0, ph->p_memsz - ph->p_filesz);
		}
	}

	volatile uint32_t entry = elf->e_entry;

#ifdef IA32_PAGE
	mm_malloc(KOFFSET - STACK_SIZE, STACK_SIZE);

#ifdef HAS_DEVICE
	create_video_mapping();
#endif

	write_cr3(get_ucr3());
#endif

	return entry;
}
Ejemplo n.º 6
0
/* 在分区链表中找到名为part_name的分区,并将其指针赋值给cur_part */
static bool mount_partition(struct list_elem* pelem, int arg) {
   char* part_name = (char*)arg;
   struct partition* part = elem2entry(struct partition, part_tag, pelem);
   if (!strcmp(part->name, part_name)) {
      cur_part = part;
      struct disk* hd = cur_part->my_disk;

      /* sb_buf用来存储从硬盘上读入的超级块 */
      struct super_block* sb_buf = (struct super_block*)sys_malloc(SECTOR_SIZE);

      /* 在内存中创建分区cur_part的超级块 */
      cur_part->sb = (struct super_block*)sys_malloc(sizeof(struct super_block));
      if (cur_part->sb == NULL) {
	 PANIC("alloc memory failed!");
      }

      /* 读入超级块 */
      memset(sb_buf, 0, SECTOR_SIZE);
      ide_read(hd, cur_part->start_lba + 1, sb_buf, 1);   

      /* 把sb_buf中超级块的信息复制到分区的超级块sb中。*/
      memcpy(cur_part->sb, sb_buf, sizeof(struct super_block)); 

      /**********     将硬盘上的块位图读入到内存    ****************/
      cur_part->block_bitmap.bits = (uint8_t*)sys_malloc(sb_buf->block_bitmap_sects * SECTOR_SIZE);
      if (cur_part->block_bitmap.bits == NULL) {
	 PANIC("alloc memory failed!");
      }
      cur_part->block_bitmap.btmp_bytes_len = sb_buf->block_bitmap_sects * SECTOR_SIZE;
      /* 从硬盘上读入块位图到分区的block_bitmap.bits */
      ide_read(hd, sb_buf->block_bitmap_lba, cur_part->block_bitmap.bits, sb_buf->block_bitmap_sects);   
      /*************************************************************/

      /**********     将硬盘上的inode位图读入到内存    ************/
      cur_part->inode_bitmap.bits = (uint8_t*)sys_malloc(sb_buf->inode_bitmap_sects * SECTOR_SIZE);
      if (cur_part->inode_bitmap.bits == NULL) {
	 PANIC("alloc memory failed!");
      }
      cur_part->inode_bitmap.btmp_bytes_len = sb_buf->inode_bitmap_sects * SECTOR_SIZE;
      /* 从硬盘上读入inode位图到分区的inode_bitmap.bits */
      ide_read(hd, sb_buf->inode_bitmap_lba, cur_part->inode_bitmap.bits, sb_buf->inode_bitmap_sects);   
      /*************************************************************/

      list_init(&cur_part->open_inodes);
      printk("mount %s done!\n", part->name);

   /* 此处返回true是为了迎合主调函数list_traversal的实现,与函数本身功能无关。
      只有返回true时list_traversal才会停止遍历,减少了后面元素无意义的遍历.*/
      return true;
   }
   return false;     // 使list_traversal继续遍历
}
Ejemplo n.º 7
0
Archivo: fs.c Proyecto: RickWei/ics2015
int fs_read(int fd, void *buf, int len)
{
	int i=fd;
	if(file_state[i].offset+len>file_table[i-3].size)
 	{
		int len_new=file_table[i-3].size-file_state[i].offset;
		ide_read(buf,file_table[i-3].disk_offset+file_state[i].offset,len_new);
		file_state[i].offset+=len_new;
		return len_new;
	}
	ide_read(buf,file_table[i-3].disk_offset+file_state[i].offset,len);
	file_state[i].offset+=len;
	return	len;
}
Ejemplo n.º 8
0
/* 根据i结点号返回相应的i结点 */
struct inode* inode_open(struct partition* part, uint32_t inode_no) {
   /* 先在已打开inode链表中找inode,此链表是为提速创建的缓冲区 */
   struct list_elem* elem = part->open_inodes.head.next;
   struct inode* inode_found;
   while (elem != &part->open_inodes.tail) {
      inode_found = elem2entry(struct inode, inode_tag, elem);
      if (inode_found->i_no == inode_no) {
	 inode_found->i_open_cnts++;
	 return inode_found;
      }
      elem = elem->next;
   }

   /*由于open_inodes链表中找不到,下面从硬盘上读入此inode并加入到此链表 */
   struct inode_position inode_pos;

   /* inode位置信息会存入inode_pos, 包括inode所在扇区地址和扇区内的字节偏移量 */
   inode_locate(part, inode_no, &inode_pos);

/* 为使通过sys_malloc创建的新inode被所有任务共享,
 * 需要将inode置于内核空间,故需要临时
 * 将cur_pbc->pgdir置为NULL */
   struct task_struct* cur = running_thread();
   uint32_t* cur_pagedir_bak = cur->pgdir;
   cur->pgdir = NULL;
   /* 以上三行代码完成后下面分配的内存将位于内核区 */
   inode_found = (struct inode*)sys_malloc(sizeof(struct inode));
   /* 恢复pgdir */
   cur->pgdir = cur_pagedir_bak;

   char* inode_buf;
   if (inode_pos.two_sec) {	// 考虑跨扇区的情况
      inode_buf = (char*)sys_malloc(1024);

   /* i结点表是被partition_format函数连续写入扇区的,
    * 所以下面可以连续读出来 */
      ide_read(part->my_disk, inode_pos.sec_lba, inode_buf, 2);
   } else {	// 否则,所查找的inode未跨扇区,一个扇区大小的缓冲区足够
      inode_buf = (char*)sys_malloc(512);
      ide_read(part->my_disk, inode_pos.sec_lba, inode_buf, 1);
   }
   memcpy(inode_found, inode_buf + inode_pos.off_size, sizeof(struct inode));

   /* 因为一会很可能要用到此inode,故将其插入到队首便于提前检索到 */
   list_push(&part->open_inodes, &inode_found->inode_tag);
   inode_found->i_open_cnts = 1;

   sys_free(inode_buf);
   return inode_found;
}
Ejemplo n.º 9
0
Archivo: fs.c Proyecto: yaobaiwei/JOS
// Make sure a particular disk block is loaded into memory.
// Returns 0 on success, or a negative error code on error.
// 
// If blk != 0, set *blk to the address of the block in memory.
//
// Hint: Use diskaddr, map_block, and ide_read.
static int
read_block(uint32_t blockno, char **blk)
{
	int r;
	char *addr;

	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);
	
	addr = diskaddr(blockno);
    if(!block_is_mapped(blockno)){
        if((r = map_block(blockno)) < 0)
            return r;
        r = ide_read(blockno*BLKSECTS, (void *)addr, BLKSECTS);
        if(r < 0)
            return r;
    }
    if(blk)
        *blk = addr;
	
	return 0;
}
Ejemplo n.º 10
0
Archivo: fs.c Proyecto: darfux/jos
// Make sure a particular disk block is loaded into memory.
// Returns 0 on success, or a negative error code on error.
// 
// If blk != 0, set *blk to the address of the block in memory.
//
// Hint: Use diskaddr, map_block, and ide_read.
static int
read_block(uint32_t blockno, char **blk)
{
	int r;
	char *addr;

	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);

	// LAB 5: Your code here.
	addr = diskaddr(blockno);
	int error = map_block(blockno);
	if(error<0) return error;

	int secno = blockno*BLKSECTS;
	error = ide_read(secno, addr, (size_t)BLKSECTS);
	if(error) return error;

	if(blk) *blk = addr;
	// panic("read_block not implemented");

	return 0;
}
Ejemplo n.º 11
0
Archivo: fs.c Proyecto: ren85/jos2006
// Make sure a particular disk block is loaded into memory.
// Returns 0 on success, or a negative error code on error.
// 
// If blk != 0, set *blk to the address of the block in memory.
//
// Hint: Use diskaddr, map_block, and ide_read.
static int
read_block(uint32_t blockno, char **blk)
{
	int r;
	char *addr;

	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);

	// LAB 5: Your code here.

	addr = diskaddr(blockno);

	if(!block_is_mapped(blockno)){		
		if ((r = sys_page_alloc(sys_getenvid(), diskaddr(blockno), PTE_U|PTE_P|PTE_W)) < 0)
	  		return r;
		if((r = ide_read(blockno*(BLKSIZE/SECTSIZE), addr, (size_t) BLKSIZE/SECTSIZE)) < 0)
			return r;
 	}

	if(blk != 0)
		*blk = addr;
	return 0;
}
Ejemplo n.º 12
0
Archivo: fs.c Proyecto: sunrenjie/jos
// Make sure a particular disk block is loaded into memory.
// Returns 0 on success, or a negative error code on error.
// 
// If blk != 0, set *blk to the address of the block in memory.
//
// Hint: Use diskaddr, map_block, and ide_read.
static int
read_block(uint32_t blockno, char **blk)
{
	int r;
	char *addr;

	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);

	// LAB 5: Your code here.
	addr = diskaddr(blockno);
	if (block_is_mapped(blockno)) {
		goto succeeded;
	}

	// now that the block is not in memory, allocate memory and read it in.
	if ((r = map_block(blockno)) < 0)
		return r;
	if ((r = ide_read(blockno * BLKSECTS, addr, BLKSECTS)) < 0)
		return r;

succeeded:
	if (blk)
		*blk = addr;
	return 0;
}
Ejemplo n.º 13
0
Archivo: fs.c Proyecto: reesun/guavaos
// Make sure a particular disk block is loaded into memory.
// Returns 0 on success, or a negative error code on error.
// 
// If blk != 0, set *blk to the address of the block in memory.
//
// Hint: Use diskaddr, map_block, and ide_read.
static int
read_block(uint32_t blockno, char **blk)
{
	int r;
	char *addr;

	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);

	// LAB 5: Your code here.
	r = map_block(blockno);
	if (r)
		return r;

	addr = diskaddr(blockno);
	r = ide_read(blockno * BLKSECTS, addr, BLKSECTS);
	if (r)
		return r;

	if (blk)
		*blk = addr;

	return sys_page_map(0, addr, 0, addr, vpt[VPN(addr)] & PTE_USER);
}
Ejemplo n.º 14
0
// Fault any disk block that is read or written in to memory by
// loading it from disk.
// Hint: Use ide_read and BLKSECTS.
static void
bc_pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
	int r;

	// Check that the fault was within the block cache region
	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("page fault in FS: eip %08x, va %08x, err %04x",
		      utf->utf_eip, addr, utf->utf_err);

	// Allocate a page in the disk map region and read the
	// contents of the block from the disk into that page.
	//
	// LAB 5: Your code here
	addr = ROUNDDOWN(addr, PGSIZE);
	if ((r = sys_page_alloc(0, addr, PTE_USER)) < 0)
		panic("sys_page_alloc: %e", r);
	if (ide_read(blockno * BLKSECTS, addr, BLKSECTS) < 0)
		panic("ide_read failed");

	// Sanity check the block number. (exercise for the reader:
	// why do we do this *after* reading the block in?)
	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	// Check that the block we read was allocated.
	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);
}
/**
 * \brief Lee 512 bytes de un dispositivo
 * \param indexDevice
 * \param block
 * \param buffer
 * \return 1, si todo Ok, 0 en caso contrario
 */
int ReadBlock(int indexDevice, unsigned block, unsigned char* buffer)
{
	unsigned status,err;
	if (!devices[indexDevice].existe) return 0;
	
	// voy a leer con lba28
	unsigned lba0 = block & 0xFF;
	unsigned lba1 = (block & 0xFF00) >> 8;
	unsigned lba2 = (block & 0xFF0000) >> 16;
	unsigned devSelected = (block & 0xFF000000) >> 24;
	devSelected = (devices[indexDevice].slave << 4) | devSelected | 0x40;
	unsigned sectorCount = 1;
	
	// espero a que este desocupado el dispositivo
	while (ide_read(indexDevice, ATA_REG_STATUS) & ATA_SR_BSY);
	
	// ahora a leer el sector en cuestion
	ide_write(indexDevice,ATA_REG_SECCOUNT0, sectorCount);
	ide_write(indexDevice,ATA_REG_LBA0, lba0);
	ide_write(indexDevice,ATA_REG_LBA1, lba1);
	ide_write(indexDevice,ATA_REG_LBA2, lba2);
	ide_write(indexDevice,ATA_REG_HDDEVSEL, devSelected);
	ide_write(indexDevice,ATA_REG_COMMAND, ATA_CMD_READ_PIO);
	
	
	// ahora esperamos la disponibilidad de datos
	err = 0;
	while(!err) {
            status = ide_read(indexDevice, ATA_REG_STATUS);
            if (status & ATA_SR_ERR) 
							err = 1;
            if (!err && !(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) 
							// Everything is right.
							err = 2;
	 }
	 if (err == 1)
	 {
		 // ocurrio un error, debo analizarlo
		 return 0;
	 }
	 
	 // todo bien leamos los datos
	 ide_read_data(indexDevice,buffer);
	 return 1;
}
Ejemplo n.º 16
0
uint32_t loader() {
	Elf32_Ehdr *elf;
	Elf32_Phdr *ph = NULL;

	uint8_t buf[4096];

#ifdef HAS_DEVICE
	ide_read(buf, ELF_OFFSET_IN_DISK, 4096);
#else
	ramdisk_read(buf, ELF_OFFSET_IN_DISK, 4096);
#endif

	elf = (void*)buf;

	/* TODO: fix the magic number with the correct one */
	const uint32_t elf_magic = 0x7f454c46;
	uint32_t *p_magic = (void *)buf;
	nemu_assert(*p_magic == elf_magic);

	/* Load each program segment */
	for(; true; ) {
		/* Scan the program header table, load each segment into memory */
		if(ph->p_type == PT_LOAD) {	//PT_LOAT=1, Loadable program segment 

			/* TODO: read the content of the segment from the ELF file 
			 * to the memory region [VirtAddr, VirtAddr + FileSiz)
			 */
			 
			 
			/* TODO: zero the memory region 
			 * [VirtAddr + FileSiz, VirtAddr + MemSiz)
			 */


#ifdef IA32_PAGE
			/* Record the program break for future use. */
			extern uint32_t brk;
			uint32_t new_brk = ph->p_vaddr + ph->p_memsz - 1;
			if(brk < new_brk) { brk = new_brk; }
#endif
		}
	}

	volatile uint32_t entry = elf->e_entry;

#ifdef IA32_PAGE
	mm_malloc(KOFFSET - STACK_SIZE, STACK_SIZE);

#ifdef HAS_DEVICE
	create_video_mapping();
#endif

	write_cr3(get_ucr3());
#endif

	return entry;
}
Ejemplo n.º 17
0
Archivo: fs.c Proyecto: wzcjj/wzcjj
int fs_read(int fd, void *buf, int len) {
	if (fd < 3) return 0;
	assert(file_state[fd].opened);
	if (file_state[fd].offset+len >= file_table[fd-3].size)
		len = file_table[fd-3].size-file_state[fd].offset-1;
	ide_read(buf, file_table[fd-3].disk_offset+file_state[fd].offset, len);
	file_state[fd].offset += len;
	return len;
}
Ejemplo n.º 18
0
int fs_read(int fd, void *buf, int len) {
	//assert(state_array[i].opened == true);
	if(!state_array[fd].opened) return -1;
	int t = file_table[fd-3].size - state_array[fd].offset;
	len = len>t? t : len;
	ide_read(buf, file_table[fd-3].disk_offset + state_array[fd].offset, len);
	state_array[fd].offset += len;
	return len;	
}
Ejemplo n.º 19
0
//Borrowed from os dev really tired will write my own in future.
unsigned char ide_polling(unsigned char channel, unsigned int advanced_check) {
   for(int i = 0; i < 4; i++)
      ide_read(channel, ATA_REG_ALTSTATUS);
   while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY)
      ; 
   if (advanced_check) {
      unsigned char state = ide_read(channel, ATA_REG_STATUS);
      if (state & ATA_SR_ERROR)
      	panic();
      if (state & ATA_SR_DF)
         return 1;
      if ((state & ATA_SR_DRQ) == 0)
         return 3; 
 
   }
 
   return 0;
 
}
Ejemplo n.º 20
0
/* 回收inode的数据块和inode本身 */
void inode_release(struct partition* part, uint32_t inode_no) {
   struct inode* inode_to_del = inode_open(part, inode_no);
   ASSERT(inode_to_del->i_no == inode_no);

/* 1 回收inode占用的所有块 */
   uint8_t block_idx = 0, block_cnt = 12;
   uint32_t block_bitmap_idx;
   uint32_t all_blocks[140] = {0};	  //12个直接块+128个间接块

   /* a 先将前12个直接块存入all_blocks */
   while (block_idx < 12) {
      all_blocks[block_idx] = inode_to_del->i_sectors[block_idx];
      block_idx++;
   }

   /* b 如果一级间接块表存在,将其128个间接块读到all_blocks[12~], 并释放一级间接块表所占的扇区 */
   if (inode_to_del->i_sectors[12] != 0) {
      ide_read(part->my_disk, inode_to_del->i_sectors[12], all_blocks + 12, 1);
      block_cnt = 140;

      /* 回收一级间接块表占用的扇区 */
      block_bitmap_idx = inode_to_del->i_sectors[12] - part->sb->data_start_lba;
      ASSERT(block_bitmap_idx > 0);
      bitmap_set(&part->block_bitmap, block_bitmap_idx, 0);
      bitmap_sync(cur_part, block_bitmap_idx, BLOCK_BITMAP);
   }
   
   /* c inode所有的块地址已经收集到all_blocks中,下面逐个回收 */
   block_idx = 0;
   while (block_idx < block_cnt) {
      if (all_blocks[block_idx] != 0) {
	 block_bitmap_idx = 0;
	 block_bitmap_idx = all_blocks[block_idx] - part->sb->data_start_lba;
	 ASSERT(block_bitmap_idx > 0);
	 bitmap_set(&part->block_bitmap, block_bitmap_idx, 0);
	 bitmap_sync(cur_part, block_bitmap_idx, BLOCK_BITMAP);
      }
      block_idx++; 
   }

/*2 回收该inode所占用的inode */
   bitmap_set(&part->inode_bitmap, inode_no, 0);  
   bitmap_sync(cur_part, inode_no, INODE_BITMAP);

   /******     以下inode_delete是调试用的    ******
   * 此函数会在inode_table中将此inode清0,
   * 但实际上是不需要的,inode分配是由inode位图控制的,
   * 硬盘上的数据不需要清0,可以直接覆盖*/
   void* io_buf = sys_malloc(1024);
   inode_delete(part, inode_no, io_buf);
   sys_free(io_buf);
   /***********************************************/
    
   inode_close(inode_to_del);
}
Ejemplo n.º 21
0
int fs_read(int fd, void *buf, size_t len) {
    if (fd < 3) return -1;
    assert(fd < NR_FILES + 3);
    assert(f_state[fd].opened);
    int max_len = file_table[fd - 3].size - f_state[fd].offset;
    assert(max_len >= 0);
    if (max_len < len) len = max_len;
    ide_read(buf, file_table[fd - 3].disk_offset + f_state[fd].offset, len);
    f_state[fd].offset += len;
    return len;
}
Ejemplo n.º 22
0
// Fault any disk block that is read or written in to memory by
// loading it from disk.
// Hint: Use ide_read and BLKSECTS.
    static void
bc_pgfault(struct UTrapframe *utf)
{
    void *addr = (void *) utf->utf_fault_va;
    uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
    int r;

    // Check that the fault was within the block cache region
	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("page fault in FS: eip %08x, va %08x, err %04x",
		      utf->utf_rip, addr, utf->utf_err);

    // Sanity check the block number.
    if (super && blockno >= super->s_nblocks)
        panic("reading non-existent block %08x\n", blockno);

    // Allocate a page in the disk map region, read the contents
    // of the block from the disk into that page, and mark the
    // page not-dirty (since reading the data from disk will mark
    // the page dirty).
    //
    // LAB 5: Your code here
	
	
	if((r= sys_page_alloc(0, ROUNDDOWN(addr,PGSIZE), PTE_SYSCALL)) < 0)
	panic("File System page fault handler couldn't alloc new page at addr %d. %e",addr, r);
	
	//if(super)
	//	cprintf("12 %d\n",super->s_nblocks);
#ifndef VMM_GUEST
	if((r = ide_read(blockno*BLKSECTS, ROUNDDOWN(addr,BLKSIZE), BLKSECTS)) < 0)
#else
     if((r = host_read(BLKSECTS*blockno, ROUNDDOWN(addr,BLKSIZE), BLKSECTS)) < 0)

#endif	
	panic("File System page fault handler couldn't read in the data from disk. %e", r);
	
	//if(super)
	//	cprintf("13 %d\n",super->s_nblocks);
	if((r = sys_page_map(0, ROUNDDOWN(addr,PGSIZE), 0, ROUNDDOWN(addr,BLKSIZE), PTE_P| PTE_U | PTE_W)) < 0) //PTE_SYSCALL&~PTE_D
			panic("Couldn't map page not dirty bc_pageflt %e",r);
	
	//if(super)
	//	cprintf("14 %d\n",super->s_nblocks);
	//cprintf("Handled the Fault\n");
	//panic("bc_pgfault not implemented");
	// Check that the block we read was allocated. (exercise for
	// the reader: why do we do this *after* reading the block
	// in?)
	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);
}
Ejemplo n.º 23
0
/* 将硬盘分区part上的inode清空 */
void inode_delete(struct partition* part, uint32_t inode_no, void* io_buf) {
   ASSERT(inode_no < 4096);
   struct inode_position inode_pos;
   inode_locate(part, inode_no, &inode_pos);     // inode位置信息会存入inode_pos
   ASSERT(inode_pos.sec_lba <= (part->start_lba + part->sec_cnt));
   
   char* inode_buf = (char*)io_buf;
   if (inode_pos.two_sec) {   // inode跨扇区,读入2个扇区
      /* 将原硬盘上的内容先读出来 */
      ide_read(part->my_disk, inode_pos.sec_lba, inode_buf, 2);
      /* 将inode_buf清0 */
      memset((inode_buf + inode_pos.off_size), 0, sizeof(struct inode));
      /* 用清0的内存数据覆盖磁盘 */
      ide_write(part->my_disk, inode_pos.sec_lba, inode_buf, 2);
   } else {    // 未跨扇区,只读入1个扇区就好
      /* 将原硬盘上的内容先读出来 */
      ide_read(part->my_disk, inode_pos.sec_lba, inode_buf, 1);
      /* 将inode_buf清0 */
      memset((inode_buf + inode_pos.off_size), 0, sizeof(struct inode));
      /* 用清0的内存数据覆盖磁盘 */
      ide_write(part->my_disk, inode_pos.sec_lba, inode_buf, 1);
   }
}
Ejemplo n.º 24
0
unsigned char ide_polling(unsigned char channel, unsigned int advanced_check) {
 
   // (I) Delay 400 nanosecond for BSY to be set:
   // -------------------------------------------------
   int i;
   for(i = 0; i < 4; i++)
      ide_read(channel, ATA_REG_ALTSTATUS); // Reading the Alternate Status port wastes 100ns; loop four times.
 
   // (II) Wait for BSY to be cleared:
   // -------------------------------------------------
   while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY)
      ; // Wait for BSY to be zero.
 
   if (advanced_check) {
      unsigned char state = ide_read(channel, ATA_REG_STATUS); // Read Status Register.
 
      // (III) Check For Errors:
      // -------------------------------------------------
      if (state & ATA_SR_ERR)
         return 2; // Error.
 
      // (IV) Check If Device fault:
      // -------------------------------------------------
      if (state & ATA_SR_DF)
         return 1; // Device Fault.
 
      // (V) Check DRQ:
      // -------------------------------------------------
      // BSY = 0; DF = 0; ERR = 0 so we should check for DRQ now.
      if ((state & ATA_SR_DRQ) == 0)
         return 3; // DRQ should be set
 
   }
 
   return 0; // No Error.
 
}
Ejemplo n.º 25
0
/* Read n sectors from the hard disk using PIO mode */
int ide_read(uint32 linear, uint32 numsects, void * bufptr) {
	int	i;
	uint32  cyl,head,sector;

	if (numsects > 1) {
		for (i=0; i<numsects; i++) {
			if (ide_read(linear+i, 1, ((uint8 *)bufptr)+i*512) < 0)
				return -1;
		}
	} else {
		linear_to_chs(linear, &cyl, &head, &sector);
		if (ide_read_chs(cyl, head, sector, numsects, (uint8*)bufptr) < 0)
			return -1;
	}

	return 0;
}
Ejemplo n.º 26
0
// Fault any disk block that is read in to memory by
// loading it from disk.
static void
bc_pgfault(struct UTrapframe *utf)
{
    void *addr = (void *) utf->utf_fault_va;
    uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
    int r;

    // Check that the fault was within the block cache region
    if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
        panic("page fault in FS: eip %08x, va %08x, err %04x",
              utf->utf_eip, addr, utf->utf_err);

    // Sanity check the block number.
    if (super && blockno >= super->s_nblocks)
        panic("reading non-existent block %08x\n", blockno);

    // Allocate a page in the disk map region, read the contents
    // of the block from the disk into that page.
    // Hint: first round addr to page boundary. fs/ide.c has code to read
    // the disk.
    //
    // LAB 5: you code here:

    addr = (void *)ROUNDDOWN(addr, PGSIZE);

    if ((r = sys_page_alloc(0, addr, PTE_P | PTE_U | PTE_W)) < 0) {
        panic("bc_pgfault: sys_page_alloc error %e\n", r);
    }

    if ((r = ide_read(BLKSECTS * blockno, addr, BLKSECTS)) < 0) {
        panic("bc_pgfault: ide_read error %e\n", r);
    }

    // Clear the dirty bit for the disk block page since we just read the
    // block from disk
    if ((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL)) < 0)
        panic("in bc_pgfault, sys_page_map: %e", r);

    // Check that the block we read was allocated. (exercise for
    // the reader: why do we do this *after* reading the block
    // in?)
    if (bitmap && block_is_free(blockno))
        panic("reading free block %08x\n", blockno);

}
Ejemplo n.º 27
0
// Fault any disk block that is read in to memory by
// loading it from disk.
// Hint: Use ide_read and BLKSECTS.
static void
bc_pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
	int r;

	// Check that the fault was within the block cache region
	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("page fault in FS: eip %08x, va %08x, err %04x",
			  utf->utf_rip, addr, utf->utf_err);

	// Sanity check the block number.
	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	// Allocate a page in the disk map region, read the contents
	// of the block from the disk into that page.
	// Hint: first round addr to page boundary.
	//
	// LAB 5: your code here:
	addr = ROUNDDOWN(addr, PGSIZE);
	if(0 != sys_page_alloc(0, (void*)addr, PTE_SYSCALL)){
		panic("Page Allocation Failed during handling page fault in FS");
	}
#ifdef VMM_GUEST
	if(0 != host_read((uint32_t) (blockno * BLKSECTS), (void*)addr, BLKSECTS))
	{
		panic("ide read failed in Page Fault Handling");		
	}
#else
	if(0 != ide_read((uint32_t) (blockno * BLKSECTS), (void*)addr, BLKSECTS))
	{
		panic("ide read failed in Page Fault Handling");		
	}
#endif	
	if ((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL)) < 0)
		panic("in bc_pgfault, sys_page_map: %e", r);

	// Check that the block we read was allocated. (exercise for
	// the reader: why do we do this *after* reading the block
	// in?)
	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);
}
Ejemplo n.º 28
0
Archivo: bc.c Proyecto: xiangho/Cse506
// Fault any disk block that is read in to memory by
// loading it from disk.
static void
bc_pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
	int r;

	// Check that the fault was within the block cache region
	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("page fault in FS: eip %08x, va %08x, err %04x",
		      utf->utf_rip, addr, utf->utf_err);

	// Sanity check the block number.
	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	// Allocate a page in the disk map region, read the contents
	// of the block from the disk into that page.
	// Hint: first round addr to page boundary.
	//
	// LAB 5: your code here:

	// Check that the block we read was allocated. (exercise for
	// the reader: why do we do this *after* reading the block
	// in?)
	if (bitmap && block_is_free(blockno))    //doubtful
		panic("reading free block %08x\n", blockno);

	void *new_addr = ROUNDDOWN(addr, PGSIZE);
	r = sys_page_alloc(0, new_addr, PTE_P|PTE_W|PTE_U);
	if(r<0)
		panic("Something wrong with allocation %e",r);
	uint64_t sec_no = BLKSECTS * blockno;
	size_t nsecs = BLKSECTS;
#ifdef VMM_GUEST
		r = host_read(sec_no, new_addr, nsecs);
#else
	r = ide_read(sec_no, new_addr, nsecs);
#endif
	if(r<0)
		panic("Something wrong with reading from the disk %e",r);
}
Ejemplo n.º 29
0
void kmain(ol_mmap_register_t mmr)
{
	textinit();
	clearscreen();

	println("The openLoader kernel is executing. \n");

	print("Current stack pointer: ");
	ol_registers_t regs = getregs();
	printnum(regs->esp, 16, FALSE, FALSE);
	putc(0xa);

	char status = inb(0x60);
	if((status & 2) == 2)
	{
		println("The A20 gate is open.");
		putc(0xa);
	}
	
	pic_init();
	setIDT();
	outb(OL_KBC_COMMAND, OL_KB_INIT);	// enable the keyboard

// display mmap
	init_mmap(mmr);
	println("Multiboot memory map:\n");
	display_mmap(mmr);

#if 0
	uint8_t active = ide_init(bootdrive);
	ide_read(0x100, 1<<20, &bootdrive[active], 60);
	uint8_t eax = ata_identify();
	printnum(active, 16, FALSE, FALSE);
#endif

	putc(0xa);

	println("Waiting for service interrupts..");
	while(1) halt();
	println("End of program reached!");
	endprogram();
}
Ejemplo n.º 30
0
static LONG ide_identify(WORD dev)
{
    LONG ret;
    UWORD ifnum, ifdev;

    ifnum = dev / 2;    /* i.e. primary IDE, secondary IDE, ... */
    ifdev = dev & 1;    /* 0 or 1 */

    KDEBUG(("ide_identify(%d [ifnum=%d ifdev=%d])\n", dev, ifnum, ifdev));

    if (ide_device_exists(dev)) {
        ret = ide_read(IDE_CMD_IDENTIFY_DEVICE,ifnum,ifdev,0L,1,
                       (UBYTE *)&identify,IDE_DATA_REGISTER_IS_BYTESWAPPED);
    } else ret = EUNDEV;

    if (ret < 0)
        KDEBUG(("ide_identify(%d [ifnum=%d ifdev=%d]) ret=%ld\n", dev, ifnum, ifdev, ret));

    return ret;
}