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; }
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 (); } } }