// ------------------------------------------------------------------------------------ // Parse a C++-like integer literal - hex and oct prefixes. // 0xNNNN - hex // 0NNN - oct // NNN - dec // ------------------------------------------------------------------------------------ std::size_t strtoul_cppstyle(const char* in, const char** out = 0) { if ('0' == in[0]) { return 'x' == in[1] ? strtoul16(in + 2, out) : strtoul8(in + 1, out); } return strtoul10(in, out); }
/** * 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); }