Beispiel #1
0
int main(int argc, char **argv)
{
    char *out = 0;
    int i;
    unsigned boot_addr = 0x07; // Standard boot address: $800
    int boot_file = 0; // Next file is boot file
    int exact_size = 0; // Use image of exact size
    int min_size = 0; // Minimum image size

    prog_name = argv[0];

    file_list flist;
    darray_init(flist, 1);
    flist_add_main_dir(&flist);

    for(i=1; i<argc; i++)
    {
        char *arg = argv[i];
        if( arg[0] == '-' )
        {
            char op;
            while( 0 != (op = *++arg) )
            {
                if( op == 'h' || op == '?' )
                    show_usage();
                else if( op == 'b' )
                {
                    if( boot_file )
                        show_error("can specify only one boot file\n");
                    boot_file = 1;
                }
                else if( op == 'x' )
                    exact_size = 1;
                else if( op == 'B' )
                {
                    char *ep;
                    if( i+1 >= argc )
                        show_error("option '-B' needs an argument\n");
                    i++;
                    boot_addr = strtol(argv[i], &ep, 0);
                    if( boot_addr <= 3 || boot_addr >= 0xF0 || !ep || *ep )
                        show_error("argument for option '-B' must be from 3 to 240\n");
                }
                else if( op == 's' )
                {
                    char *ep;
                    if( i+1 >= argc )
                        show_error("option '-s' needs an argument\n");
                    i++;
                    min_size = strtol(argv[i], &ep, 0);
                    if( min_size <= 0 || !ep || *ep )
                        show_error("argument for option '-s' must be a positive integer\n");
                    if( min_size > 65535 * 256 )
                        show_error("maximum image size is 16776960 bytes\n");
                }
                else if( op == 'v' )
                    show_version();
                else
                    show_error("invalid command line option '-%c'. Try '%s -h' for help.\n",
                               op, prog_name);
            }
        }
        else if( !out && boot_file != 1 )
            out = arg;
        else
        {
            flist_add_file(&flist, arg, boot_file == 1);
            if( boot_file )
                boot_file = -1;
        }
    }
    if( !out )
        show_error("missing output file name. Try '%s -h' for help.\n", prog_name);

    struct sfs *sfs = 0;
    if( exact_size )
    {
        // Try biggest size and the try reducing:
        if( min_size < 128*65535 )
            sfs = build_spartafs(128, 65535, boot_addr, &flist);
        if( !sfs )
            sfs = build_spartafs(256, 65535, boot_addr, &flist);
        if( sfs )
        {
            int nsec = 65535 - sfs_get_free_sectors(sfs);
            int ssec = sfs_get_sector_size(sfs);

            if( nsec*ssec < min_size )
                nsec = (min_size + ssec - 1) / ssec;

            for(; nsec>5 && (nsec*ssec)>=min_size; nsec--)
            {
                struct sfs *n = build_spartafs(ssec, nsec, boot_addr, &flist);
                if( !n )
                    break;
                sfs_free(sfs);
                sfs = n;
                if( sfs_get_free_sectors(sfs) > 0 && (nsec-1)*ssec > min_size )
                {
                    nsec = nsec - sfs_get_free_sectors(sfs) + 1;
                    if( nsec*ssec < min_size )
                        nsec = 1 + (min_size + ssec - 1) / ssec;
                }
            }
        }
    }
    else
    {
        for(i=0; !sfs && sectors[i].size; i++)
        {
            if( sectors[i].size * sectors[i].num < min_size )
                continue;
            sfs = build_spartafs(sectors[i].size, sectors[i].num, boot_addr, &flist);
        }
    }
    if( sfs )
        write_atr(out, sfs_get_data(sfs), sfs_get_sector_size(sfs), sfs_get_num_sectors(sfs));
    else
        show_error("can't create an image big enough\n");
    return 0;
}
Beispiel #2
0
static void
syscall_handler (struct intr_frame *f)
{
  int32_t* esp = (int32_t*)f->esp;
  /*
    Any parameters passed to syscall will be above ESP, see illustration below.
    Number of arguments each syscall expects is in argc[] array above.

    syscall number is pointed to by ESP.
    --------------------------------------
    PHYS_BASE
    .................
    <param>
    <param>
    ESP --->    <syscall_number>

    --------------------------------------
  */

  // verify esp pointer is ok, first parameter: current thread
   if(esp == NULL || verify_fix_length(esp, sizeof(esp)) == false){
	sys_exit(-1);
   }

   // esp adress belongs to thread
  if(pagedir_get_page(thread_current()->pagedir, esp) == NULL){
	sys_exit(-1);
   } 

  // ok syscall nr
  int32_t syscall_nr = *esp;
  if(syscall_nr < 0 || syscall_nr >= SYS_NUMBER_OF_CALLS){
	sys_exit(-1);
  }

  // Make sure our data is not overwriting PHYS_BASE.
  int expected_args = argc[syscall_nr];
  unsigned long highest_addr = esp + (expected_args * sizeof(int));
  if(highest_addr >= PHYS_BASE){
	sys_exit(-1);
  }
  
  if(pagedir_get_page(thread_current()->pagedir, highest_addr) == NULL){
	sys_exit(-1);
  }

  /*
  int i = 1;
  for(; i <= expected_args; i++){
	if(verify_fix_length(&esp[i], sizeof(int) ) == false){
		sys_exit(-1);
	}
      
  }
	*/

  DEBUG_SYSCALL("# SYSCALL received = %s\n", get_system_call_name(syscall_nr));
  
  
  switch (syscall_nr)
    {
  
    case SYS_HALT:
      power_off();
      break;
    case SYS_EXEC:
    {

      	f->eax = SYS_EXEC_handler(esp);
    }
    break;
  
    case SYS_WAIT:
    {
      
      int child_pid = *(esp + 1);
      
      f->eax = process_wait (child_pid);
      break; 
    }
  
    case SYS_EXIT:
    {
      if(is_kernel_vaddr(pg_round_up((void*)esp[1]) )){
	sys_exit(-1);
      }
      int exit_status = *(esp + 1);
      process_exit(exit_status);
      thread_exit();
      break;
    }
    case SYS_PLIST:
        process_print_list();
    break;
    case SYS_CREATE:
      {
        bool success = false;

        char *name = (char*)*(esp + 1);
	if(name == NULL){
		sys_exit(-1);
	}
        unsigned initial_size = *(esp + 2);

	if(verify_fix_length(esp[1], initial_size) == false){
		sys_exit(-1);
	}
	if(verify_variable_length(esp[1]) == false){
		sys_exit(-1);
	}
        success = filesys_create(name, initial_size);

        if(success) {
          DEBUG_SYSCALL("#SYS_CREATE - File with name: %s created. \n", name);

        } else {
          DEBUG_SYSCALL("#SYS_CREATE - filesys_create failed: file named \'%s\' already exists  or internal memory allocation failed \n", name);
        }

        f->eax = success;
        break;
      }
    case SYS_OPEN:
      {
        char *name = (char*)*(esp + 1);
	if(name == NULL){
		sys_exit(-1);
	}
	if(verify_variable_length(esp[1]) == false){
		sys_exit(-1);
	}


        struct file *file;
        file = filesys_open(name);


	int retVal = -1;
        if(file != NULL) {
          DEBUG_SYSCALL("# SYS_OPEN - File with name: '%s' created. \n", name);

	  int fd = flist_add_file(file);
	  retVal = fd;
        } else {
          DEBUG_SYSCALL("# SYS_OPEN - filesys_open failed: no file named \'%s\' exists or internal memory allocation failed \n", name);
          retVal = -1;

        }
	f->eax = retVal;
        break;
      }
    case SYS_READ:
      {
        int retVal = SYS_READ_handler(esp);

        f->eax = retVal;
        break;
      }
    case SYS_CLOSE:
	{
	int retVal = SYS_CLOSE_handler(esp);
	f->eax = retVal;
	
	break;
	}
    case SYS_REMOVE:
	{
		int retVal = SYS_REMOVE_handler(esp);
		f->eax = retVal;
		break;
	}
    case SYS_WRITE:
      {
        int retVal = SYS_WRITE_handler(esp);
        f->eax = retVal;
        break;
      }
    case SYS_SEEK:
	{
	f->eax = SYS_SEEK_handler(esp);
	break;
	}
    case SYS_TELL:

	f->eax = SYS_TELL_handler(esp);
	break;
	

    case SYS_FILESIZE:
	f->eax = SYS_FILESIZE_handler(esp);
	break;
    default:
      {
        DEBUG_SYSCALL ("Executed an unknown system call (nr: %i)!\n", syscall_nr);
        DEBUG_SYSCALL ("Stack top + 0: %d\n", esp[0]);
        DEBUG_SYSCALL ("Stack top + 1: %d\n", esp[1]);

        thread_exit ();
      }
    }
}