Пример #1
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);
}
Пример #2
0
void
get_current_configuration(struct supported_gdb_version *sp)
{
	FILE *fp;
	static char buf[512];
	char *p;

#ifdef __alpha__
        target_data.target = ALPHA;
#endif
#ifdef __i386__
        target_data.target = X86;
#endif
#ifdef __powerpc__
        target_data.target = PPC;
#endif
#ifdef __ia64__
        target_data.target = IA64;
#endif
#ifdef __s390__
        target_data.target = S390;
#endif
#ifdef __s390x__
        target_data.target = S390X;
#endif
#ifdef __powerpc64__
        target_data.target = PPC64;
#endif
#ifdef __x86_64__
        target_data.target = X86_64;
#endif
#ifdef __arm__
        target_data.target = ARM;
#endif
#ifdef __aarch64__
        target_data.target = ARM64;
#endif
#ifdef __mips__
        target_data.target = MIPS;
#endif

	set_initial_target(sp);

        /* 
	 * Override target if specified on command line.
	 */
	target_data.host = target_data.target;

	if (target_data.target_as_param) {
		if ((target_data.target == X86 || target_data.target == X86_64) &&
		    (name_to_target((char *)target_data.target_as_param) == ARM)) {
			/* 
			 *  Debugging of ARM core files supported on X86, and on
			 *  X86_64 when built as a 32-bit executable.
			 */
			target_data.target = ARM;
		} else if ((target_data.target == X86 || target_data.target == X86_64) &&
			   (name_to_target((char *)target_data.target_as_param) == MIPS)) {
			/*
			 *  Debugging of MIPS little-endian core files
			 *  supported on X86, and on X86_64 when built as a
			 *  32-bit executable.
			 */
			target_data.target = MIPS;
		} else if ((target_data.target == X86_64) &&
			(name_to_target((char *)target_data.target_as_param) == X86)) {
			/*
			 *  Build an X86 crash binary on an X86_64 host.
			 */
			target_data.target = X86;
		} else if ((target_data.target == X86_64) &&
			(name_to_target((char *)target_data.target_as_param) == ARM64)) {
			/*
			 *  Build an ARM64 crash binary on an X86_64 host.
			 */
			target_data.target = ARM64;
		} else if ((target_data.target == X86_64) &&
			(name_to_target((char *)target_data.target_as_param) == PPC64)) {
			/*
			 *  Build a PPC64 little-endian crash binary on an X86_64 host.
			 */
			target_data.target = PPC64;
		} else if ((target_data.target == PPC64) &&
			(name_to_target((char *)target_data.target_as_param) == PPC)) {
			/*
			 *  Build an PPC crash binary on an PPC64 host.
			 */
			target_data.target = PPC;
		} else if (name_to_target((char *)target_data.target_as_param) ==
			target_data.host) {
			if ((target_data.initial_gdb_target != UNKNOWN) &&
			    (target_data.host != target_data.initial_gdb_target))
				arch_mismatch(sp);
		} else {
			fprintf(stderr,
			    "\ntarget=%s is not supported on the %s host architecture\n\n",
				target_data.target_as_param,
				target_to_name(target_data.host));
			exit(1);
		}
        }

	/*
	 *  Impose implied (sticky) target if an initial build has been
	 *  done in the source tree.
	 */
	if (target_data.initial_gdb_target && 
	    (target_data.target != target_data.initial_gdb_target)) {
		if ((target_data.initial_gdb_target == ARM) &&
		    (target_data.target != ARM)) {
			if ((target_data.target == X86) || 
			    (target_data.target == X86_64))
				target_data.target = ARM;
			else
				arch_mismatch(sp);
		}
		if ((target_data.target == ARM) &&
		    (target_data.initial_gdb_target != ARM))
			arch_mismatch(sp);

		if ((target_data.initial_gdb_target == MIPS) &&
		    (target_data.target != MIPS)) {
			if ((target_data.target == X86) ||
			    (target_data.target == X86_64))
				target_data.target = MIPS;
			else
				arch_mismatch(sp);
		}

		if ((target_data.initial_gdb_target == X86) &&
		    (target_data.target != X86)) {
			if (target_data.target == X86_64) 
				target_data.target = X86;
			else
				arch_mismatch(sp);
		}
		if ((target_data.target == X86) &&
		    (target_data.initial_gdb_target != X86))
			arch_mismatch(sp);

		if ((target_data.initial_gdb_target == ARM64) &&
		    (target_data.target != ARM64)) {
			if (target_data.target == X86_64) 
				target_data.target = ARM64;
			else
				arch_mismatch(sp);
		}
		if ((target_data.target == ARM64) &&
		    (target_data.initial_gdb_target != ARM64))
			arch_mismatch(sp);

		if ((target_data.initial_gdb_target == PPC64) &&
		    (target_data.target != PPC64)) {
			if (target_data.target == X86_64) 
				target_data.target = PPC64;
			else
				arch_mismatch(sp);
		}
		if ((target_data.target == PPC64) &&
		    (target_data.initial_gdb_target != PPC64))
			arch_mismatch(sp);

		if ((target_data.initial_gdb_target == PPC) &&
		    (target_data.target != PPC)) {
			if (target_data.target == PPC64) 
				target_data.target = PPC;
			else
				arch_mismatch(sp);
		}
		if ((target_data.target == PPC) &&
		    (target_data.initial_gdb_target != PPC))
			arch_mismatch(sp);
	}

        if ((fp = fopen("Makefile", "r")) == NULL) {
		perror("Makefile");
		goto get_release;
	}

	while (fgets(buf, 512, fp)) {
		if (strncmp(buf, "PROGRAM=", strlen("PROGRAM=")) == 0) {
			p = strstr(buf, "=") + 1;
			strip_linefeeds(p);
			upper_case(p, target_data.program);
			if (target_data.flags & DAEMON)
				strcat(target_data.program, "D");
			continue;
		}
	}

	fclose(fp);

get_release:

	target_data.release[0] = '\0';

	if (file_exists(".rh_rpm_package")) {
        	if ((fp = fopen(".rh_rpm_package", "r")) == NULL) {
			perror(".rh_rpm_package");
		} else {
			if (fgets(buf, 512, fp)) {
				strip_linefeeds(buf);
				if (strlen(buf)) {
					buf[MAXSTRLEN-1] = '\0';
					strcpy(target_data.release, buf);
				} else 
					fprintf(stderr, 
				   "WARNING: .rh_rpm_package file is empty!\n");
			} else
				fprintf(stderr, 
				   "WARNING: .rh_rpm_package file is empty!\n");
			fclose(fp);

			if (strlen(target_data.release))
				return;
		} 
	} else 
		fprintf(stderr, 
			"WARNING: .rh_rpm_package file does not exist!\n");

        if ((fp = fopen("defs.h", "r")) == NULL) {
                perror("defs.h");
		return;
        }

        while (fgets(buf, 512, fp)) {
                if (strncmp(buf, "#define BASELEVEL_REVISION", 
		    strlen("#define BASELEVEL_REVISION")) == 0) {
			p = strstr(buf, "\"") + 1;
			strip_linefeeds(p);
			p[strlen(p)-1] = '\0';
			strcpy(target_data.release, p);
			break;
		}
	}

	fclose(fp);
}