Example #1
0
int main(int argc, char *argv[]){
    FILE *file;
    if (argc < 2) {
        /* read input */
        /* give error message and exit */
        fprintf(stderr, "Must pass an argument!\n");
        exit(1);
    }
    file = fopen(argv[1],"rb"); // open file
    //FILE *file = fopen("fat_volume.dat","rb");
    if (file==NULL) {
        printf("No such a file");
        exit(0);
    }
    printf("File found   ");
    fseek(file, 0L, SEEK_END);
    long buff_size = ftell(file);
    
    fseek(file, 0L, SEEK_SET);
    char *buf = malloc(buff_size+1);// create a buffer
    
    fread(buf,buff_size,1,file);
    
    long boot_off = 0;
    char* sec_buf = malloc(512);
    sec_read(file, boot_off,sec_buf); // read boot and store it in boot_sect_t
    boot_sect_t* boot = boot_read(sec_buf);
    free(sec_buf);
    ssize = (boot->ssize[1]<<8|boot->ssize[0]); //its sector size.
    printf("Sector Size: %i\n",ssize);
    csize = boot->csize;
    printf("cluster size in sectors: %i\n",boot->csize);
    int reserved = (boot->reserved[1]<<8|boot->reserved[0]);//the number of reserved sectors on the disk.
    printf("The number of reserved sctor: %i\n",reserved);
    printf("The number of FAT copies: %i\n",boot->numfat);
    int numroot = (boot->numroot[1] <<8|boot->numroot[0] ); //the number of entries in its root directory
    printf("The number of entries in its root directory: %i\n",numroot);
    int sectors16 = (boot->sectors16[1]<<8|boot->sectors16[0]);//Total number of sectors in the filesystem
                                                               //printf("The total number of sectors in filesystem: %i\n",sectors16);
    int sectperfat16 = (boot->sectperfat16[1]<<8|boot->sectperfat16[0]);
    printf("The number of sectors in FAT: %i\n",sectperfat16);
    int sectpertrack = (boot->sectpertrack[1]<<8|boot->sectpertrack[0]);
    int heads = (boot->heads[1]<<8|boot->heads[0]);
    int num_hidden_sec = (boot->prevsect[1]<<8|boot->prevsect[0]); //Number of hidden sectors
    printf("The number of hidden sectors on the disk: %i\n",num_hidden_sec);
    sec_num_first_FAT = 0+reserved;
    printf("The sector number of the first copy of FAT: %i\n",sec_num_first_FAT);
    sec_num_first_root = reserved+(boot->numfat*sectperfat16);
    printf("The sector number of the first sector of root dictory: %i\n",sec_num_first_root);
    sec_num_first_data = ((numroot*32)/ssize)+sec_num_first_root;
    printf("The sector number of the first sector of data: %i\n",sec_num_first_data);
    // printf("Data from file:\n%u",buf[sec_num_first_data] );
    /***************************************************************************/
    //end of boot sec
    long cur_buf_pos = (sec_num_first_root)*ssize;
    //printf("%c\n",buf[cur_buf_pos]);
    directory_read(file,cur_buf_pos, 0);
    
    
    fclose(file); // close file
                  //free(buf);
    
}
Example #2
0
void load_kernel(int bootdrv) {
  struct master_boot_record *mbr;
  struct superblock *sb;
  struct groupdesc *group;
  struct inodedesc *inode;
  int blocksize;
  int blks_per_sect;
  int kernelsize;
  int kernelpages;
  char *kerneladdr;
  struct dos_header *doshdr;
  struct image_header *imghdr;
  char *addr;
  blkno_t blkno;
  int i;
  int j;
  pte_t *pt;
  int imgpages;
  int start;
  char *label;
  struct boot_sector *bootsect;

  //kprintf("Loading kernel");

  // Determine active boot partition if booting from harddisk
  if (bootdrv & 0x80 && (bootdrv & 0xF0) != 0xF0) {
    mbr = (struct master_boot_record *) bsect;
    if (boot_read(mbr, SECTORSIZE, 0) != SECTORSIZE) {
      panic("unable to read master boot record");
    }

    if (mbr->signature != MBR_SIGNATURE) panic("invalid boot signature");

    bootsect = (struct boot_sector *) bsect;
    label = bootsect->label;
    if (label[0] == 'S' && label[1] == 'A' && label[2] == 'N' && label[3] == 'O' && label[4] == 'S') {
      // Disk does not have a partition table
      start = 0;
      bootpart = -1;
    } else {
      // Find active partition
      bootpart = -1;
      for (i = 0; i < 4; i++) {
        if (mbr->parttab[i].bootid == 0x80) {
          bootpart = i;
          start = mbr->parttab[i].relsect;
        }
      }

      if (bootpart == -1) panic("no bootable partition on boot drive");
    }
  } else {
    start = 0;
    bootpart = 0;
  }

  // Read super block from boot device
  sb = (struct superblock *) ssect;
  if (boot_read(sb, SECTORSIZE, 1 + start) != SECTORSIZE) {
    panic("unable to read super block from boot device");
  }

  // Check signature and version
  if (sb->signature != DFS_SIGNATURE) panic("invalid DFS signature");
  if (sb->version != DFS_VERSION) panic("invalid DFS version");
  blocksize = 1 << sb->log_block_size;
  blks_per_sect =  blocksize / SECTORSIZE;

  // Read first group descriptor
  group = (struct groupdesc *) gsect;
  if (boot_read(group, SECTORSIZE, sb->groupdesc_table_block * blks_per_sect + start) != SECTORSIZE) {
    panic("unable to read group descriptor from boot device");
  }

  // Read inode for kernel
  inode = (struct inodedesc *) isect;
  if (boot_read(isect, SECTORSIZE, group->inode_table_block * blks_per_sect + start) != SECTORSIZE) {
    panic("unable to read kernel inode from boot device");
  }
  inode += DFS_INODE_KRNL;

  // Calculate kernel size
  kernelsize = (int) inode->size;
  kernelpages = PAGES(kernelsize);
  //kprintf("Kernel size %d KB\n", kernelsize / 1024);

  // Allocate page table for kernel
  if (kernelpages > PTES_PER_PAGE) panic("kernel too big");
  pt = (pte_t *) alloc_heap(1);
  pdir[PDEIDX(OSBASE)] = (unsigned long) pt | PT_PRESENT | PT_WRITABLE;

  // Allocate pages for kernel
  kerneladdr = alloc_heap(kernelpages);

  // Read kernel from boot device
  if (inode->depth == 0) {
    addr = kerneladdr;
    for (i = 0; i < (int) inode->blocks; i++) {
      if (boot_read(addr, blocksize, inode->blockdir[i] * blks_per_sect + start) != blocksize) {
        panic("error reading kernel from boot device");
      }
      addr += blocksize;
    }
  } else if (inode->depth == 1) {
    addr = kerneladdr;
    blkno = 0;
    for (i = 0; i < DFS_TOPBLOCKDIR_SIZE; i++) {
      if (boot_read(blockdir, blocksize, inode->blockdir[i] * blks_per_sect + start) != blocksize) {
        panic("error reading kernel inode dir from boot device");
      }

      for (j = 0; j < (int) (blocksize / sizeof(blkno_t)); j++) {
        if (boot_read(addr, blocksize, blockdir[j] * blks_per_sect + start) != blocksize) {
          panic("error reading kernel inode dir from boot device");
        }
        
        addr += blocksize;

        blkno++;
        if (blkno == inode->blocks) break;
      }

      if (blkno == inode->blocks) break;
    }
  } else {
    panic("unsupported inode depth");
  }

  // Determine entry point for kernel
  doshdr = (struct dos_header *) kerneladdr;
  imghdr = (struct image_header *) (kerneladdr + doshdr->e_lfanew);
  krnlentry = imghdr->optional.address_of_entry_point + OSBASE;

  // Allocate pages for .data section
  imgpages = PAGES(imghdr->optional.size_of_image);
  alloc_heap(imgpages - kernelpages);

  // Relocate resource data and clear uninitialized data
  if (imghdr->header.number_of_sections == 4) {
    struct image_section_header *data = &imghdr->sections[2];
    struct image_section_header *rsrc = &imghdr->sections[3];
    memcpy(kerneladdr + rsrc->virtual_address, kerneladdr + rsrc->pointer_to_raw_data, rsrc->size_of_raw_data);
    memset(kerneladdr + data->virtual_address + data->size_of_raw_data, 0, data->virtual_size - data->size_of_raw_data);
  }

  // Map kernel into vitual address space
  for (i = 0; i < imgpages; i++) pt[i] = (unsigned long) (kerneladdr + i * PAGESIZE) | PT_PRESENT | PT_WRITABLE;
}