void task_fs() { printk("Task FS begins.\n"); init_buffer( 0x300000 ); init_fs(); MESSAGE msg; while(1) { send_recv( RECEIVE, ANY, &msg ); int src = msg.source; switch(msg.type) { case OPEN: msg.FD = do_open( &msg ); break; case CLOSE: msg.RETVAL = do_close( &msg ); break; case READ: case WRITE: msg.CNT = do_rdwr( &msg ); break; case RESUME_PROC: src = msg.PROC_NR; break; case FORK: msg.RETVAL = fs_fork( &msg ); break; case EXIT: msg.RETVAL = fs_exit( &msg ); break; default: dump_msg("FS:unknow message:", &msg ); assert(0); break; } if( msg.type != SUSPEND_PROC ) { msg.type = SYSCALL_RET; send_recv( SEND, src, &msg ); } } spin("FS"); }
/** * <Ring 1> The main loop of TASK FS. * *****************************************************************************/ PUBLIC void task_fs() { printl("{FS} Task FS begins.\n"); init_fs(); while (1) { send_recv(RECEIVE, ANY, &fs_msg); int msgtype = fs_msg.type; int src = fs_msg.source; pcaller = &proc_table[src]; switch (msgtype) { case OPEN: fs_msg.FD = do_open(); break; case CLOSE: fs_msg.RETVAL = do_close(); break; case READ: case WRITE: fs_msg.CNT = do_rdwt(); break; case UNLINK: fs_msg.RETVAL = do_unlink(); break; case RESUME_PROC: src = fs_msg.PROC_NR; break; case FORK: fs_msg.RETVAL = fs_fork(); break; case EXIT: fs_msg.RETVAL = fs_exit(); break; /* case LSEEK: */ /* fs_msg.OFFSET = do_lseek(); */ /* break; */ case STAT: fs_msg.RETVAL = do_stat(); break; default: dump_msg("FS::unknown message:", &fs_msg); assert(0); break; } #ifdef ENABLE_DISK_LOG char * msg_name[128]; msg_name[OPEN] = "OPEN"; msg_name[CLOSE] = "CLOSE"; msg_name[READ] = "READ"; msg_name[WRITE] = "WRITE"; msg_name[LSEEK] = "LSEEK"; msg_name[UNLINK] = "UNLINK"; /* msg_name[FORK] = "FORK"; */ /* msg_name[EXIT] = "EXIT"; */ /* msg_name[STAT] = "STAT"; */ switch (msgtype) { case UNLINK: dump_fd_graph("%s just finished. (pid:%d)", msg_name[msgtype], src); //panic(""); case OPEN: case CLOSE: case READ: case WRITE: case FORK: case EXIT: /* case LSEEK: */ case STAT: break; case RESUME_PROC: break; default: assert(0); } #endif /* reply */ if (fs_msg.type != SUSPEND_PROC) { fs_msg.type = SYSCALL_RET; send_recv(SEND, src, &fs_msg); } } }
/** * efi_main - The entry point for the OS loader image. * @image: firmware-allocated handle that identifies the image * @sys_table: EFI system table */ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table) { WCHAR *error_buf; EFI_STATUS err; EFI_LOADED_IMAGE *info; CHAR16 *name, *options; UINT32 options_size; char *cmdline; InitializeLib(image, _table); sys_table = _table; boot = sys_table->BootServices; runtime = sys_table->RuntimeServices; if (CheckCrc(sys_table->Hdr.HeaderSize, &sys_table->Hdr) != TRUE) return EFI_LOAD_ERROR; Print(banner, EFILINUX_VERSION_MAJOR, EFILINUX_VERSION_MINOR); err = fs_init(); if (err != EFI_SUCCESS) goto failed; err = handle_protocol(image, &LoadedImageProtocol, (void **)&info); if (err != EFI_SUCCESS) goto fs_deinit; if (!read_config_file(info, &options, &options_size)) { int i; options = info->LoadOptions; options_size = info->LoadOptionsSize; /* * Skip the first word, that's probably our name. Stop * when we hit a word delimiter (' ') or the start of an * efilinux argument ('-'). */ i = 0; while (i < options_size) { if (options[i] == ' ' || options[i] == '-') break; i++; } options = &options[i]; options_size -= i; } if (options && options_size != 0) { err = parse_args(options, options_size, &name, &cmdline); /* We print the usage message in case of invalid args */ if (err == EFI_INVALID_PARAMETER) { fs_exit(); return EFI_SUCCESS; } if (err != EFI_SUCCESS) goto fs_deinit; } err = load_image(image, name, cmdline); if (err != EFI_SUCCESS) goto free_args; return EFI_SUCCESS; free_args: free(cmdline); free(name); fs_deinit: fs_exit(); failed: /* * We need to be careful not to trash 'err' here. If we fail * to allocate enough memory to hold the error string fallback * to returning 'err'. */ if (allocate_pool(EfiLoaderData, ERROR_STRING_LENGTH, (void **)&error_buf) != EFI_SUCCESS) { Print(L"Couldn't allocate pages for error string\n"); return err; } StatusToString(error_buf, err); Print(L": %s\n", error_buf); return exit(image, err, ERROR_STRING_LENGTH, error_buf); }
/* pre: takes in int 'argc' and char** 'argv' command line arguments which * include: * -f <file_list> * -d <dir_list> * -s <disk size> * -b <block size> * post: runs the filesystem simulation program * return: 0 on sucessful exit, something else on error */ int main(int argc, char** argv) { int n; char* line; char** v; /* parse args and setup global environment */ parse_args(argc, argv); /* read input files and initialize filesystem */ init(); /* main command reading loop */ line = (char*)malloc(CMD_LEN * sizeof(char)); bzero((void*)line, CMD_LEN * sizeof(char)); while (1) { /* prompt */ printf("%s ", PROMPT); fflush(stdout); /* fd 0 is stdin */ if ((n = read(0, line, CMD_LEN)) == -1) { perror(argv[0]); fs_exit(); exit(-1); } else if (n == 0) { fs_exit(); break; } else { /* overwrite newline with NULL-byte */ line[n - 1] = '\0'; #ifdef DEBUG printf("[DEBUG]\tRead line: <%s>\n", line); fflush(stdout); #endif /* use str2vect to break 'line' into a list of whitespace separated * strings */ v = str2vect(line); /* check for commands and execute the proper function */ if (!strcmp(v[0], "append")) { if (v[1] != NULL && v[2] != NULL) fs_append(v[1], atoi(v[2])); else { printf("usage: append name size\n"); fflush(stdout); } } else if (!strcmp(v[0], "cd")) { if (v[1] != NULL) fs_cd(v[1]); else { printf("usage: cd directory\n"); fflush(stdout); } } else if (!strcmp(v[0], "cd..")) /* just in case this is the intended command */ { fs_cd(".."); } else if (!strcmp(v[0], "create")) { if (v[1] != NULL) fs_create(v[1]); else { printf("usage: create name\n"); fflush(stdout); } } else if (!strcmp(v[0], "delete")) { if (v[1] != NULL) fs_delete(v[1]); else { printf("usage: delete name\n"); fflush(stdout); } } else if (!strcmp(v[0], "dir")) { fs_dir(); } else if (!strcmp(v[0], "exit")) { /* free the vector immediately and break to exit */ free_vect(v); break; } else if (!strcmp(v[0], "ls")) { fs_ls(); } else if (!strcmp(v[0], "mkdir")) { if (v[1] != NULL) fs_mkdir(v[1]); else { printf("usage: mkdir directory\n"); fflush(stdout); } } else if (!strcmp(v[0], "prdisk")) { fs_prdisk(); } else if (!strcmp(v[0], "prfiles")) { fs_prfiles(); } else if (!strcmp(v[0], "remove")) { if (v[1] != NULL && v[2] != NULL) fs_remove(v[1], atoi(v[2])); else { printf("usage: remove name size\n"); fflush(stdout); } } else { printf("%s: command not found: %s\n", argv[0], v[0]); fflush(stdout); } /* free the vector to avoid memory leaks */ free_vect(v); } } free(line); fs_exit(); return 0; }
/** * efi_main - The entry point for the OS loader image. * @image: firmware-allocated handle that identifies the image * @sys_table: EFI system table */ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table) { WCHAR *error_buf; EFI_STATUS err; EFI_LOADED_IMAGE *info; CHAR16 *name = NULL; CHAR16 *options; BOOLEAN options_from_conf_file = FALSE; UINT32 options_size; CHAR8 *cmdline = NULL; struct bootimg_hooks hooks; main_image_handle = image; InitializeLib(image, _table); sys_table = _table; boot = sys_table->BootServices; runtime = sys_table->RuntimeServices; if (CheckCrc(ST->Hdr.HeaderSize, &ST->Hdr) != TRUE) return EFI_LOAD_ERROR; log_init(); info(banner, EFILINUX_VERSION_MAJOR, EFILINUX_VERSION_MINOR, EFILINUX_BUILD_STRING, EFILINUX_VERSION_STRING, EFILINUX_VERSION_DATE); store_osloader_version(EFILINUX_BUILD_STRING); err = fs_init(); if (err != EFI_SUCCESS) error(L"fs_init failed, DnX mode ?\n"); err = handle_protocol(image, &LoadedImageProtocol, (void **)&info); if (err != EFI_SUCCESS) goto fs_deinit; efilinux_image_base = info->ImageBase; efilinux_image = info->DeviceHandle; if (!read_config_file(info, &options, &options_size)) { int i; options = info->LoadOptions; options_size = info->LoadOptionsSize; /* Skip the first word, that's our name. */ for (i = 0; i < options_size && options[i] != ' '; i++) ; options = &options[i]; options_size -= i; } else options_from_conf_file = TRUE; err = init_platform_functions(); if (EFI_ERROR(err)) { error(L"Failed to initialize platform: %r\n", err); goto fs_deinit; } CHAR16 type = '\0'; if (options && options_size != 0) { err = parse_args(options, options_size, &type, &name, &cmdline); if (options_from_conf_file) free(options); /* We print the usage message in case of invalid args */ if (err == EFI_INVALID_PARAMETER) { fs_exit(); return EFI_SUCCESS; } if (err != EFI_SUCCESS) goto fs_deinit; } hooks.before_exit = loader_ops.hook_before_exit; hooks.before_jump = loader_ops.hook_before_jump; hooks.watchdog = tco_start_watchdog; debug(L"shell cmdline=%a\n", cmdline); switch(type) { case 'f': if (!name) { error(L"No file name specified or name is empty\n"); goto free_args; } info(L"Starting file %s\n", name); err = android_image_start_file(info->DeviceHandle, name, cmdline, &hooks); break; case 't': { enum targets target; if ((err = name_to_target(name, &target)) != EFI_SUCCESS) { error(L"Unknown target name %s\n", name); goto free_args; } info(L"Starting target %s\n", name); loader_ops.load_target(target, cmdline); break; } case 'p': { EFI_GUID part_guid; if ((err = name_to_guid(name, &part_guid)) != EFI_SUCCESS) { error(L"Unknown target name %s\n", name); goto free_args; } info(L"Starting partition %s\n", name); err = android_image_start_partition(&part_guid, cmdline, &hooks); break; } case 'c': { int i; for (i = 0 ; i < sizeof(commands) / sizeof(*commands); i++) if (!StrCmp(commands[i].name, name)) commands[i].func(); err = EFI_SUCCESS; } break; case 'a': { CHAR16 *endptr; VOID * addr = (VOID *)strtoul16(name, &endptr, 0); if ((name[0] == '\0' || *endptr != '\0')) { error(L"Failed to convert %s into address\n", name); goto free_args; } debug(L"Loading android image at 0x%x\n", addr); err = android_image_start_buffer(addr, cmdline, &hooks); break; } default: debug(L"type=0x%x, starting bootlogic\n", type); err = start_boot_logic(cmdline); if (EFI_ERROR(err)) { error(L"Boot logic failed: %r\n", err); goto free_args; } } free_args: if (cmdline) free(cmdline); if (name) free(name); fs_deinit: fs_exit(); /* * We need to be careful not to trash 'err' here. If we fail * to allocate enough memory to hold the error string fallback * to returning 'err'. */ error_buf = AllocatePool(ERROR_STRING_LENGTH); if (!error_buf) { error(L"Couldn't allocate pages for error string\n"); return EFI_OUT_OF_RESOURCES; } StatusToString(error_buf, err); error(L": %s\n", error_buf); loader_ops.hook_before_exit(); return exit(image, err, ERROR_STRING_LENGTH, error_buf); }
PUBLIC void task_fs() { printl("Task FS begins.\n"); init_fs(); while (1) { send_recv(RECEIVE, ANY, &fs_msg); int src = fs_msg.source; pcaller = &proc_table[src]; switch (fs_msg.type) { case OPEN: fs_msg.FD = do_open(); break; case CLOSE: fs_msg.RETVAL = do_close(); break; case READ: case WRITE: fs_msg.CNT = do_rdwt(); break; case UNLINK: fs_msg.RETVAL = do_unlink(); break; case RESUME_PROC: src = fs_msg.PROC_NR; // 恢复最初请求的进程,如 TestB break; case FORK: fs_msg.RETVAL = fs_fork(); break; case EXIT: fs_msg.RETVAL = fs_exit(); break; case STAT: fs_msg.RETVAL = do_stat(); break; default: dump_msg("FS::unknown message:", &fs_msg); assert(0); break; } /* 如果发送者要求挂起,则不回送消息 */ if (fs_msg.type != SUSPEND_PROC) { fs_msg.type = SYSCALL_RET; send_recv(SEND, src, &fs_msg); } } spin("FS"); }