Exemplo 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);
   }
}
Exemplo n.º 2
0
Arquivo: fs.c Projeto: RickWei/ics2015
int fs_write(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_write(buf,file_table[i-3].disk_offset+file_state[i].offset,len_new);
		return len_new;
	}
	ide_write(buf,file_table[i-3].disk_offset+file_state[i].offset,len);
	return	len;
}	
Exemplo n.º 3
0
void ide_write(unsigned char channel, unsigned char reg, unsigned char data) {
   if (reg > 0x07 && reg < 0x0C)
      ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);
   if (reg < 0x08)
      outb(data, channels[channel].base  + reg - 0x00);
   else if (reg < 0x0C)
      outb(data, channels[channel].base  + reg - 0x06);
   else if (reg < 0x0E)
      outb(data, channels[channel].ctrl  + reg - 0x0A);
   else if (reg < 0x16)
      outb(data, channels[channel].bmide + reg - 0x0E);
   if (reg > 0x07 && reg < 0x0C)
      ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
}
Exemplo n.º 4
0
int32_t ide_pio_readwrite(uint8_t rw, uint8_t drive, uint64_t lba, 
                          uint8_t *buf, uint32_t numsectors)
{
  /* Sanity */
  if(rw > 1 || buf == 0)
    return 0;

  /* Vars */
  uint64_t addr = lba;
  uint8_t lba_mode = 1; /* 1 - 28, 2 - 48 */
  uint8_t cmd = 0;
  uint8_t channel = ide_devices[drive].channel;
  uint32_t slave = ide_devices[drive].drive;
  uint32_t bus = ide_channels[channel].base;
  uint32_t words = (numsectors * 512) / 2;

  /* Make sure IRQs are disabled */
  _outb(bus + IDE_REGISTER_CTRL, 0x02);

  /* Wait for it to acknowledge */
  ide_wait(channel, 0);

  /* Determine LBA mode */
  if(ide_devices[drive].flags & 0x1)
    lba_mode = 2;

  /* Read or write? */
  if(rw == IDE_READ)
    cmd = IDE_COMMAND_PIO_READ;
  else
    cmd = IDE_COMMAND_PIO_WRITE;

  /* Reset IRQ counter */
  ide_channels[channel].irq_wait = 0;

  /* Now, send the command */
  if(lba_mode == 2)
    {
      /* LBA48 */
      cmd += 0x04;

      /* Send it */
      ide_write(channel, IDE_REGISTER_HDDSEL, (0x40 | (slave << 4)));
      ide_wait(channel, 0);
      ide_write(channel, IDE_REGISTER_SECCOUNT0, 0x00);
      ide_write(channel, IDE_REGISTER_LBA0, (uint8_t)((addr >> 24) & 0xFF));
      ide_write(channel, IDE_REGISTER_LBA1, (uint8_t)((addr >> 32) & 0xFF));
      ide_write(channel, IDE_REGISTER_LBA2, (uint8_t)((addr >> 40) & 0xFF));
    }
Exemplo n.º 5
0
Arquivo: fs.c Projeto: darfux/jos
// Copy the current contents of the block out to disk.
// Then clear the PTE_D bit using sys_page_map.
// Hint: Use ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
void
write_block(uint32_t blockno)
{
	char *addr;
	if (!block_is_mapped(blockno))
		panic("write unmapped block %08x", blockno);
	
	// Write the disk block and clear PTE_D.
	// LAB 5: Your code here.

	// We will use the VM hardware to keep track of whether a 
	// disk block has been modified since it was last read from 
	// or written to disk. To see whether a block needs writing, 
	// we can just look to see if the PTE_D "dirty" bit is set 
	// in the vpt entry.
	addr = diskaddr(blockno);
	if(!va_is_dirty(addr)) return;

	
	int error;
	int secno = blockno*BLKSECTS;
	error = ide_write(secno, addr, BLKSECTS);
	if(error<0) panic("write block error on writing");

	int env_id = sys_getenvid();
	error = sys_page_map(env_id, addr, 
		env_id, addr, ((PTE_U|PTE_P|PTE_W) & ~PTE_D));
	if(error<0) panic("write block error on clearing PTE_D");



	// panic("write_block not implemented");
}
Exemplo n.º 6
0
int fs_write(int fd, void *buf, int len) {
	if(!state_array[fd].opened) return -1;
	assert(state_array[fd].offset + len < file_table[fd - 3].size);
	ide_write(buf, file_table[fd-3].disk_offset + state_array[fd].offset, len);
	state_array[fd].offset += len;
	return len;	
}
Exemplo n.º 7
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
	{
		uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
		int r;
		
		if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
			panic("flush_block of bad va %08x", addr);
	
		// LAB 5: Your code here.
		//panic("flush_block not implemented");
		if(va_is_mapped(addr) == false || va_is_dirty(addr) == false)
		{
			return;
		}
		addr = ROUNDDOWN(addr, PGSIZE);
#ifdef VMM_GUEST
		if(0 != host_write((uint32_t) (blockno * BLKSECTS), (void*)addr, BLKSECTS))
		{
			panic("ide read failed in Page Fault Handling");		
		}
#else
		if(0 != ide_write((uint32_t) (blockno * BLKSECTS), (void*)addr, BLKSECTS))
		{
			panic("ide write failed in Flush Block");	
		}
#endif	
		if ((r = sys_page_map(0, addr, 0, addr, PTE_SYSCALL)) < 0)
		{
			panic("in flush_block, sys_page_map: %e", r);
		}
	}
Exemplo n.º 8
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
 	uint32_t secno, r;
	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
        addr = ROUNDDOWN(addr,PGSIZE);
        secno = blockno*BLKSECTS;
	
	if(va_is_mapped(addr) && va_is_dirty(addr))
	{	
		r = ide_write(secno, addr, BLKSECTS);
		if(r)
			panic("IDE write failed: %e", r);
		//cprintf("\nClearing PTE_D : 0x%08x\n", vpt[VPN(addr)] & (~PTE_D));
		r = sys_page_map(0,addr,0,addr, ((vpt[VPN(addr)] | PTE_USER) & (~PTE_D)));		// & PTE_USER  
		if(r)
			cprintf("\nPage Mapping failed %e\n", r);
	}

	//panic("flush_block not implemented");
}
Exemplo n.º 9
0
void ide_read_buffer(unsigned char channel, unsigned char reg, unsigned int buffer,unsigned int quads) {
   if (reg > 0x07 && reg < 0x0C)
      ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);
   asm("pushw %es; movw %ds, %ax; movw %ax, %es");
   //if (reg < 0x08)
     // insl(channels[channel].base  + reg - 0x00, buffer, quads);
   //else if (reg < 0x0C)
      //insl(channels[channel].base  + reg - 0x06, buffer, quads);
   //else if (reg < 0x0E)
      //insl(channels[channel].ctrl  + reg - 0x0A, buffer, quads);
 //  else if (reg < 0x16)
      //insl(channels[channel].bmide + reg - 0x0E, buffer, quads);
   asm("popw %es;");
   if (reg > 0x07 && reg < 0x0C)
      ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
}
Exemplo n.º 10
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
    uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
    int r;

    if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
        panic("flush_block of bad va %08x", addr);

    // LAB 5: Your code here.
    addr = (void *)ROUNDDOWN(addr, PGSIZE);

    if (!va_is_mapped(addr) || !va_is_dirty(addr))
        return;

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

    if ((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL & ~PTE_D))) {
        panic("flush_block: sys_page_map error %e\n", r);
    }

    return;
}
Exemplo n.º 11
0
unsigned char ide_read(unsigned char channel, unsigned char reg) {
   unsigned char result;
   if (reg > 0x07 && reg < 0x0C)
      ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);
   if (reg < 0x08)
      result = inb(channels[channel].base + reg - 0x00);
   else if (reg < 0x0C)
      result = inb(channels[channel].base  + reg - 0x06);
   else if (reg < 0x0E)
      result = inb(channels[channel].ctrl  + reg - 0x0A);
   else if (reg < 0x16)
      result = inb(channels[channel].bmide + reg - 0x0E);
   if (reg > 0x07 && reg < 0x0C)
      ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
   return result;
}
Exemplo n.º 12
0
/**
 * Initialize disk device driver. Reserves memory for data structures
 * and register driver to the interrupt handler.
 *
 * @param desc Pointer to the PCI IO device descriptor of the controller
 *
 * @return Pointer to the device structure of the controller
 */
void ide_write(uint8_t channel, uint8_t reg, uint8_t data)
{
  /* */
  if(reg > 0x07 && reg < 0x0C)
    ide_write(channel, IDE_REGISTER_CTRL, 0x80 | ide_channels[channel].irq);

  /* */
  if(reg < 0x08)
    _outb((uint16_t)(ide_channels[channel].base + reg), data);
  else if(reg < 0x0C)
    _outb((uint16_t)(ide_channels[channel].base + reg - 0x06), data);
  else if(reg < 0x0E)
    _outb((uint16_t)(ide_channels[channel].ctrl + reg - 0x0A), data);
  else if(reg < 0x16)
    _outb((uint16_t)(ide_channels[channel].busm + reg - 0x0E), data);

  if(reg > 0x07 && reg < 0x0C)
    ide_write(channel, IDE_REGISTER_CTRL, ide_channels[channel].irq);
}
Exemplo n.º 13
0
int fs_write(int fd, const 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_write(buf, file_table[fd - 3].disk_offset + f_state[fd].offset, len);
    f_state[fd].offset += len;
    return len;
}
Exemplo n.º 14
0
Arquivo: bc.c Projeto: evilzone/CSE506
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
	int r;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
	void *dst_addr = (void *)(ROUNDDOWN(addr, PGSIZE));
	// Project addition --> Transparent disk encryption.
	if(va_is_mapped(dst_addr))
	{
		if(va_is_dirty(dst_addr))
		{
			if((blockno == 0) || (blockno == 2)) 
			 	ide_write(blockno * BLKSECTS, dst_addr, BLKSECTS);
			else if((blockno == 1))
			{
				if(!s_encrypted)
					ide_write(blockno * BLKSECTS, dst_addr, BLKSECTS);
				else
				{
					r = transparent_disk_encrypt(blockno, dst_addr);
					if(r)
						return;
				}
			}
			else 
			{ 
				r = transparent_disk_encrypt(blockno, dst_addr);
				if(r)
					return;
			}
			sys_page_map(thisenv->env_id, dst_addr, thisenv->env_id, dst_addr, PTE_SYSCALL);
		}
	}

//	panic("flush_block not implemented");
}
Exemplo n.º 15
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);
   }
}
Exemplo n.º 16
0
uint8_t ide_read(uint8_t channel, uint8_t reg)
{
  /* */
  uint8_t data = 0;;

  if(reg > 0x07 && reg < 0x0C)
    ide_write(channel, IDE_REGISTER_CTRL, 0x80 | ide_channels[channel].irq);

  /* */
  if(reg < 0x08)
    data = _inb((uint16_t)(ide_channels[channel].base + reg));
  else if(reg < 0x0C)
    data = _inb((uint16_t)(ide_channels[channel].base + reg - 0x06));
  else if(reg < 0x0E)
    data = _inb((uint16_t)(ide_channels[channel].ctrl + reg - 0x0A));
  else if(reg < 0x16)
    data = _inb((uint16_t)(ide_channels[channel].busm + reg - 0x0E));

  if(reg > 0x07 && reg < 0x0C)
    ide_write(channel, IDE_REGISTER_CTRL, ide_channels[channel].irq);

  return data;
}
Exemplo n.º 17
0
// Write the contents of DISKMAP block 'blocknum' to disk.
// Returns 0 on success, < 0 on failure.  Error codes include -E_INVAL
//   (blocknum out of range), -E_FAULT (block not in memory), -E_IO.
//
static int
flush_block(blocknum_t blocknum)
{
	uintptr_t va = DISKMAP + blocknum * BLKSIZE;
	BlockInfo *bip;
	int r;

	if (blocknum >= (blocknum_t) (DISKSIZE / BLKSIZE))
		return -E_INVAL;
	if (!(vpd[PDX(va)] & PTE_P) || !(vpt[PGNUM(va)] & PTE_P))
		return -E_FAULT;

	return ide_write(blocknum * BLKSECTS, (void *) va, BLKSECTS);
}
Exemplo n.º 18
0
Arquivo: fs.c Projeto: wzcjj/wzcjj
int fs_write(int fd, void *buf, int len) {
	if ((fd == 1)||(fd == 2)) {
		int i;
		for (i = 0; i < len; i++)
			serial_printc(((char*)buf)[i]);
	}
	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;
	if (len <= 0) return 0;
	ide_write(buf, file_table[fd-3].disk_offset+file_state[fd].offset, len);
	file_state[fd].offset += len;
	return len;
}
Exemplo n.º 19
0
Arquivo: bc.c Projeto: LancelotGT/JOS
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
    addr = ROUNDDOWN(addr, PGSIZE);
    if (!va_is_mapped(addr) || !va_is_dirty(addr))
      return;
    ide_write(blockno * BLKSECTS, addr, BLKSECTS);
    sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL);
}
Exemplo n.º 20
0
/* Write n sectors to the hard disk using PIO mode */
int ide_write(uint32 linear, uint32 numsects, void *bufptr) {
	int	i;
	uint32  cyl,head,sector;

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

	return 0;
}
Exemplo n.º 21
0
Arquivo: fs.c Projeto: sunrenjie/jos
// Copy the current contents of the block out to disk.
// Then clear the PTE_D bit using sys_page_map.
// Hint: Use ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
void
write_block(uint32_t blockno)
{
	int r;
	char *addr;

	if (!block_is_mapped(blockno))
		panic("write unmapped block %08x", blockno);
	
	// Write the disk block and clear PTE_D.
	// LAB 5: Your code here.
	addr = diskaddr(blockno);
	if ((r = ide_write(blockno * BLKSECTS, addr, BLKSECTS)) < 0)
		panic("write_block: ide_write failed: %e.\n", r);
	if ((r = sys_page_map(0, addr, 0, addr, PTE_USER)) < 0)
		panic("write_block: sys_page_map failed: %e.\n", r);
}
Exemplo n.º 22
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
	int r;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
	addr = ROUNDDOWN(addr, PGSIZE);
	if (!va_is_mapped(addr) || !va_is_dirty(addr))
		return;

	if (ide_write(blockno * BLKSECTS, addr, BLKSECTS) < 0)
		panic("ide_write failed");
	if ((r = sys_page_map(0, addr, 0, addr, PTE_USER)) < 0)
		panic("sys_page_map: %e", r);
}
Exemplo n.º 23
0
Arquivo: bc.c Projeto: YYmooon/439h
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
    addr             = (void *) ROUNDDOWN(addr, PGSIZE);
    uint32_t sectno  = ((uint32_t)addr - DISKMAP) / SECTSIZE;
    uint32_t blockno = (sectno / BLKSECTS);

    if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
        panic("flush_block of bad va %08x", addr);

    // LAB 5: Your code here.
    if(va_is_dirty(addr) && va_is_mapped(addr)) {
        ide_write(sectno, addr, BLKSECTS);
        sys_page_map(0, addr, 
                     0, addr,
                     (PTE_SYSCALL));
        BC_DEBUG("Wrote block %08x, now mapped r/o\n", blockno);
    }
}
Exemplo n.º 24
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
    void
flush_block(void *addr)
{
	uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
	int r;

    if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
        panic("flush_block of bad va %08x", addr);
		
			// LAB 5: Your code here.
	if((va_is_mapped(addr))&&(va_is_dirty(addr)))
	#ifndef VMM_GUEST
		ide_write(blockno*BLKSECTS, ROUNDDOWN(addr,BLKSIZE), BLKSECTS);
	#else
		host_write(blockno*BLKSECTS, ROUNDDOWN(addr,BLKSIZE), BLKSECTS);
	#endif	
	if((va_is_mapped(addr)) && ((r = sys_page_map(0, ROUNDDOWN(addr,PGSIZE), 0, ROUNDDOWN(addr,PGSIZE), PTE_SYSCALL&~PTE_D)) < 0))
			panic("Couldn't flush disk page%e",r);
}
Exemplo n.º 25
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
	addr = ROUNDDOWN(addr, PGSIZE);

	if (!va_is_mapped(addr) || !va_is_dirty(addr)) return;
	
	ide_write(blockno * BLKSECTS, addr, BLKSECTS);
	
	if (sys_page_map(0, addr, 0, addr, PTE_SYSCALL) < 0)
		panic("bc.c/flush_block: map page failed.\n");
	//panic("flush_block not implemented");
}
Exemplo n.º 26
0
/* 将内存中bitmap第bit_idx位所在的512字节同步到硬盘 */
void bitmap_sync(struct partition* part, uint32_t bit_idx, uint8_t btmp_type) {
   uint32_t off_sec = bit_idx / 4096;  // 本i结点索引相对于位图的扇区偏移量
   uint32_t off_size = off_sec * BLOCK_SIZE;  // 本i结点索引相对于位图的字节偏移量
   uint32_t sec_lba;
   uint8_t* bitmap_off;

/* 需要被同步到硬盘的位图只有inode_bitmap和block_bitmap */
   switch (btmp_type) {
      case INODE_BITMAP:
	 sec_lba = part->sb->inode_bitmap_lba + off_sec;
	 bitmap_off = part->inode_bitmap.bits + off_size;
	 break;

      case BLOCK_BITMAP: 
	 sec_lba = part->sb->block_bitmap_lba + off_sec;
	 bitmap_off = part->block_bitmap.bits + off_size;
	 break;
   }
   ide_write(part->my_disk, sec_lba, bitmap_off, 1);
}
Exemplo n.º 27
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
	if( !va_is_mapped(addr) || !(uvpt[PGNUM(addr)] & PTE_D)) { /* no need to flush */
		return;
	}
	int r;
	addr = ROUNDDOWN(addr, PGSIZE);
	if( (r = ide_write(blockno * BLKSECTS, addr, (PGSIZE/SECTSIZE))) != 0) {
		panic("in flush_block, ide_write: %e", r);
	}

	if ((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL)) < 0)
		panic("in sys_page_map, sys_page_map: %e", r);
}
Exemplo n.º 28
0
Arquivo: fs.c Projeto: reesun/guavaos
// Copy the current contents of the block out to disk.
// Then clear the PTE_D bit using sys_page_map.
// Hint: Use ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
void
write_block(uint32_t blockno)
{
	int r;
	char *addr;

	if (!block_is_mapped(blockno))
		panic("write unmapped block %08x", blockno);
	
	// Write the disk block and clear PTE_D.
	// LAB 5: Your code here.

	addr = diskaddr(blockno);
	r = ide_write(blockno * BLKSECTS, addr, BLKSECTS);
	if (r)
		panic("write_block(): ide_write() failed: %e\n", r);

	r = sys_page_map(0, addr, 0, addr, vpt[VPN(addr)] & PTE_USER);
	if (r)
		panic("write_block(): sys_page_map() failed: %e\n", r);
}
Exemplo n.º 29
0
Arquivo: fs.c Projeto: mainboy/xv6
// Copy the current contents of the block out to disk.
// Then clear the PTE_D bit using sys_page_map.
// Hint: Use ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
void
write_block(uint32_t blockno)
{
	char *addr;

	if (!block_is_mapped(blockno))
		panic("write unmapped block %08x", blockno);
	
	// Write the disk block and clear PTE_D.
	// LAB 5: Your code here.
	addr = diskaddr(blockno);	
	if(va_is_dirty(addr) == 0){
		cprintf("va isn't dirty!\n");
		return;
	}
	if(ide_write(blockno * BLKSECTS, addr, BLKSECTS) < 0)
		panic("write_block ide_write fail!\n");
	if(sys_page_map(0,addr,0,addr, PTE_USER) < 0)
		panic("write_block sys_page_map fail!\n");
	return;
}
Exemplo n.º 30
0
Arquivo: bc.c Projeto: wuxy/mitjos
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
	int r;
	void *blkva;
	blkva=ROUNDDOWN(addr,BLKSIZE);
	if(va_is_mapped(addr)&&va_is_dirty(addr))
	{
		ide_write(blockno*BLKSECTS,blkva,BLKSECTS);
		if((r=sys_page_map(0,blkva,0,blkva,PTE_USER))<0)
			panic("page mapping failed:%e\n",r);
		
	}
	//panic("flush_block not implemented");
}