int fs_write(int fd, void *buf, int len) { if ((fd >= 0) && (fd < NR_FILES) && (curenv->file[fd].opened == true)) { int i; struct inode node; unsigned int ioff = directory_d.entries[fd].inode_offset; readsect((void*)node.data_block_offsets,ioff + 201); int length = min(len,directory_d.entries[fd].file_size-curenv->file[fd].offset); unsigned int begin = curenv->file[fd].offset / 512; unsigned int begin_off = curenv->file[fd].offset % 512; unsigned int end = (curenv->file[fd].offset + length) / 512; unsigned int end_off = (curenv->file[fd].offset + length) % 512; if (begin == end) { char sect[512]; readsect((void*)sect,node.data_block_offsets[begin] + 201); for (i = 0;i < len;i++) { sect[begin_off + i] = ((char*)buf)[i]; } writesect((void*)sect,node.data_block_offsets[begin] + 201); } else { char sect[512]; readsect((void*)sect,node.data_block_offsets[begin] + 201); for (i = 0;i < 512 - begin_off;i++) { sect[begin_off + i] = ((char*)buf)[i]; } writesect((void*)sect,node.data_block_offsets[begin]); buf = ((char*)buf) + 512 - begin_off; for (i = begin + 1;i < end;i++) { writesect(buf,node.data_block_offsets[i] + 201); buf = ((char*)buf)+512; } readsect((void*)sect,node.data_block_offsets[end] + 201); for (i = 0;i < end_off;i++) { sect[i] = ((char*)buf)[i]; } writesect((void*)sect,node.data_block_offsets[end] + 201); } curenv->file[fd].offset += length; return length; } else { printk("fs_write fails!\n"); return -1; } }
void do_multiboot(const char *filename) { uint8_t buf[SECTORSIZE]; elf_header *elfh = (elf_header *) buf; off_t o; if ((diskfd = open(filename, O_RDWR)) < 0) { fprintf(stderr, "%s: %s\n", filename, strerror(errno)); usage(); } readsect(buf, 0); if (elfh->e_magic != ELF_MAGIC) { fprintf(stderr, "%s: not an ELF executable file\n", filename); usage(); } o = elfh->e_phoff + sizeof(elf_program) * elfh->e_phnum; if (o >= 4096 - sizeof(multiboot_header)) { fprintf(stderr, "%s: ELF header too large to accommodate multiboot header\n", filename); usage(); } else if (lseek(diskfd, o, SEEK_SET) != o) { perror("lseek"); usage(); } diskwrite(multiboot_header, sizeof(multiboot_header)); exit(0); }
int read(void *f, void *data, int len) { File *fp = f; Fat *fat = fp->fat; if(fp->len > 0 && fp->rp >= fp->ep){ if(fp->clust != ~0U){ if(fp->lbaoff % fat->clustsize == 0){ if((fp->clust >> 4) == fat->eofmark) return -1; fp->lbaoff = (fp->clust - 2) * fat->clustsize; fp->clust = readnext(fp, fp->clust); fp->lba = fp->lbaoff + fat->datalba; } fp->lbaoff++; } if(readsect(fat->drive, fp->lba++, fp->rp = fp->buf)) return -1; } if(fp->len < len) len = fp->len; if(len > (fp->ep - fp->rp)) len = fp->ep - fp->rp; memmove(data, fp->rp, len); fp->rp += len; fp->len -= len; return len; }
void readsector(int sectornumber, char* buffer) { int sec,head,cyl; sec=mod(sectornumber,0x12)+1; head=mod(div(sectornumber,0x12),2); cyl=div(sectornumber,0x24); readsect(buffer,sec,head,cyl); }
static int findfat(Fat *fat, int drive, ulong xbase, ulong lba) { struct { uchar status; uchar bchs[3]; uchar typ; uchar echs[3]; uchar lba[4]; uchar len[4]; } *p; uchar buf[Sectsz]; int i; if(xbase == 0) xbase = lba; if(readsect(drive, lba, buf)) return -1; if(buf[0x1fe] != 0x55 || buf[0x1ff] != 0xAA) return -1; p = (void*)&buf[0x1be]; for(i=0; i<4; i++){ switch(p[i].typ){ case 0x05: case 0x0f: case 0x85: /* extended partitions */ if(!findfat(fat, drive, xbase, xbase + GETLONG(p[i].lba))) return 0; /* no break */ case 0x00: continue; default: if(p[i].status != 0x80) continue; fat->drive = drive; fat->partlba = lba + GETLONG(p[i].lba); if(readsect(drive, fat->partlba, buf)) continue; if(conffat(fat, buf)) continue; return 0; } } return -1; }
static int isowalk(Extend *ex, char *path) { char name[MAXPATH], c, *end; int i; Dir d; isoclose(ex); /* find pvd */ for(i=0x10; i<0x1000; i++){ if(readsect(i, ex->buf)) return -1; if(*ex->buf == 1) break; } ex->lba = *((ulong*)(ex->buf + 156 + 2)); ex->len = *((ulong*)(ex->buf + 156 + 10)); for(;;){ if(readn(ex, &d, Dirsz) != Dirsz) break; if(d.dirlen == 0) break; if(readn(ex, name, d.namelen) != d.namelen) break; i = d.dirlen - (Dirsz + d.namelen); while(i-- > 0) read(ex, &c, 1); for(i=0; i<d.namelen; i++){ c = name[i]; if(c >= 'A' && c <= 'Z'){ c -= 'A'; c += 'a'; } name[i] = c; } name[i] = 0; while(*path == '/') path++; if((end = strchr(path, '/')) == 0) end = path + strlen(path); i = end - path; if(d.namelen == i && memcmp(name, path, i) == 0){ ex->rp = ex->ep; ex->lba = *((ulong*)d.lba); ex->len = *((ulong*)d.len); if(*end == 0) return 0; else if(d.flags[0] & 2){ path = end; continue; } break; } } return -1; }
/* 将位于磁盘offset位置的count字节数据读入物理地址pa */ void readseg(unsigned char *pa, int count, int offset) { unsigned char *epa; epa = pa + count; pa -= offset % SECTSIZE; offset = (offset / SECTSIZE) + 1; for(; pa < epa; pa += SECTSIZE, offset ++) readsect(pa, offset); }
/*reads a sector into the buffer*/ void readsector(int sectornumber, char* buffer) { int sec,head,cyl; /*convert to CHS*/ sec=mod(sectornumber,0x12)+1; head=mod(mydiv(sectornumber,0x12),2); cyl=mydiv(sectornumber,0x24); readsect(buffer,sec,head,cyl); }
void bootmain(void) { int sectnum = 64; uint8_t *dst = 0; int i = 1; for (; i <= sectnum; ++i) { readsect( dst, i); dst += SECTSIZE; } __asm__ __volatile("ljmp $0x8, $0x0"); }
void readseg(u8 *pa, u32 sz, u32 offset) { u8 *epa; epa = pa + sz; /* round down to sector boundary */ pa -= offset % SECTSIZE; /* bytes to sectors; kernel starts at sector 1 */ offset = (offset / SECTSIZE) + 1; for (; pa < epa; pa += SECTSIZE, offset++) { readsect(pa, offset); } }
static int isoread(void *f, void *data, int len) { Extend *ex = f; if(ex->len > 0 && ex->rp >= ex->ep) if(readsect(ex->lba++, ex->rp = ex->buf)) return -1; if(ex->len < len) len = ex->len; if(len > (ex->ep - ex->rp)) len = ex->ep - ex->rp; memmove(data, ex->rp, len); ex->rp += len; ex->len -= len; return len; }
/* * * readseg - read @count bytes at @offset from kernel into virtual address @va, * might copy more than asked. * */ static void readseg(uintptr_t va, uint32_t count, uint32_t offset) { uintptr_t end_va = va + count; // round down to sector boundary va -= offset % SECTSIZE; // translate from bytes to sectors; kernel starts at sector 1 uint32_t secno = (offset / SECTSIZE) + 1; // If this is too slow, we could read lots of sectors at a time. // We'd write more to memory than asked, but it doesn't matter -- // we load in increasing order. for (; va < end_va; va += SECTSIZE, secno ++) { readsect((void *)va, secno); } }
static ulong readnext(File *fp, ulong clust) { Fat *fat = fp->fat; uint b = fat->ver; ulong sect, off; sect = clust * b / Sectsz; off = clust * b % Sectsz; if(readsect(fat->drive, fat->fatlba + sect, fp->buf)) memset(fp->buf, 0xff, 4); switch(fat->ver){ case Fat16: return GETSHORT(&fp->buf[off]); case Fat32: return GETLONG(&fp->buf[off])& 0x0fffffff; } return 0; }
// Find a JOS kernel partition int find_partition(off_t partition_sect, off_t extended_sect, int partoff) { int i, r; uint8_t buf[SECTORSIZE]; off_t o; struct Partitiondesc *ptable; // read the partition sector: initially sector 0 readsect(buf, partition_sect); // check for partition table magic number if ((uint8_t) buf[PTABLE_MAGIC_OFFSET] != PTABLE_MAGIC1 || (uint8_t) buf[PTABLE_MAGIC_OFFSET + 1] != PTABLE_MAGIC2) return 0; // search partition table ptable = (struct Partitiondesc*) (buf + PTABLE_OFFSET); for (i = 0; i < 4; i++) if (ptable[i].lba_length == 0) /* ignore entry */; else if (ptable[i].type == PTYPE_JOS_KERN) { // use this partition partition_sect += (off_t) ptable[i].lba_start; fprintf(stderr, "Using partition %d (start sector %ld, sector length %ld)\n", partoff + i + 1, (long) partition_sect, (long) ptable[i].lba_length); o = lseek(diskfd, partition_sect * SECTORSIZE, SEEK_SET); if (o != partition_sect * SECTORSIZE) { fprintf(stderr, "cannot seek to partition start: %s\n", strerror(errno)); usage(); } maxoff = (off_t) ptable[i].lba_length * SECTORSIZE; return 1; } else if (ptable[i].type == PTYPE_DOS_EXTENDED || ptable[i].type == PTYPE_W95_EXTENDED || ptable[i].type == PTYPE_LINUX_EXTENDED) { off_t inner_sect = extended_sect; if (!inner_sect) inner_sect = ptable[i].lba_start; if ((r = find_partition(ptable[i].lba_start + extended_sect, inner_sect, (partoff ? partoff + 1 : 4))) > 0) return r; } // no partition number found return 0; }
// Read 'count' bytes at 'offset' from kernel into virtual address 'va'. // Might copy more than asked. void readseg(uint va, uint count, uint offset) { uint eva; eva = va + count; // Round down to sector boundary. va &= ~(SECTSIZE - 1); // Translate from bytes to sectors; kernel starts at sector 1. offset = (offset / SECTSIZE) + 1; // If this is too slow, we could read lots of sectors at a time. // We'd write more to memory than asked, but it doesn't matter -- // we load in increasing order. for(; va < eva; va += SECTSIZE, offset++) readsect((uchar*)va, offset); }
// Read 'count' bytes at 'offset' from kernel into physical address 'pa'. // Might copy more than asked. void readseg(uchar* pa, uint count, uint offset) { uchar* epa; epa = pa + count; // Round down to sector boundary. pa -= offset % SECTSIZE; // Translate from bytes to sectors; kernel starts at sector 1. offset = (offset / SECTSIZE) + 1; // If this is too slow, we could read lots of sectors at a time. // We'd write more to memory than asked, but it doesn't matter -- // we load in increasing order. for(; pa < epa; pa += SECTSIZE, offset++) readsect(pa, offset); }
void init_cond() { init_segment(); init_idt(); init_intr(); init_serial(); init_timer(); init_mem(); sem_init(); readsect((void *)directory_d.entries,201 + 256); printk("Filename = %s\n",directory_d.entries[0].filename); env_init(); kernel_env.file[0].opened = true; kernel_env.file[0].offset = 0; curenv = &kernel_env; set_timer_intr_handler(kernel_timer_event); //asm volatile("cli"); env_create(200,0,ENV_TYPE_USER); env_run(&envs[0]); }
/* * Read 'count' bytes at 'offset' from kernel into virtual address 'va'. * Might copy more than asked */ static void readseg(uint32_t va, uint32_t count, uint32_t offset) { uint32_t end_va; va &= 0xFFFFFF; end_va = va + count; // round down to sector boundary va &= ~(SECTSIZE - 1); // translate from bytes to sectors, and kernel starts at sector 1 offset = (offset / SECTSIZE); // If this is too slow, we could read lots of sectors at a time. // We'd write more to memory than asked, but it doesn't matter -- // we load in increasing order. while (va < end_va) { readsect((uint8_t *) va, offset); va += SECTSIZE; offset++; } }
// Read 'filesz' bytes at 'offset' from kernel into virtual address 'va', // then clear the memory from 'va+filesz' up to 'va+memsz' (set it to 0). void readseg(uint32_t va, uint32_t filesz, uint32_t memsz, uint32_t sect) { uint32_t end_va; end_va = va + filesz; memsz += va; // round down to sector boundary va &= ~(SECTORSIZE - 1); // read sectors while (va < end_va) { readsect((uint8_t*) va, sect); va += SECTORSIZE; sect++; } // clear bss segment while (end_va < memsz) *((uint8_t*) end_va++) = 0; }