arch/um/kernel/um_arch.c

Source file repositories/reference/linux-study-clean/arch/um/kernel/um_arch.c

File Facts

System
Linux kernel
Corpus path
arch/um/kernel/um_arch.c
Extension
.c
Size
12532 bytes
Lines
552
Domain
Architecture Layer
Bucket
arch/um
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

while (*to_parse != 0 && isspace(*to_parse)) {
			to_parse++;
		}
		if (kstrtoul(to_parse, 10, &res) == 0 && is_power_of_2(res))
			boot_cpu_data.cache_alignment = res;
		else
			boot_cpu_data.cache_alignment = L1_CACHE_BYTES;
	}
}

static unsigned long __init get_top_address(char **envp)
{
	unsigned long top_addr = (unsigned long) &top_addr;
	int i;

	/* The earliest variable should be after the program name in ELF */
	for (i = 0; envp[i]; i++) {
		if ((unsigned long) envp[i] > top_addr)
			top_addr = (unsigned long) envp[i];
	}

	return PAGE_ALIGN(top_addr + 1);
}

int __init linux_main(int argc, char **argv, char **envp)
{
	unsigned long avail, diff;
	unsigned long virtmem_size, max_physmem;
	unsigned long host_task_size;
	unsigned long stack;
	unsigned int i;
	int add;

	for (i = 1; i < argc; i++) {
		if ((i == 1) && (argv[i][0] == ' '))
			continue;
		add = 1;
		uml_checksetup(argv[i], &add);
		if (add)
			add_arg(argv[i]);
	}
	if (have_root == 0)
		add_arg(DEFAULT_COMMAND_LINE_ROOT);

	if (have_console == 0)
		add_arg(DEFAULT_COMMAND_LINE_CONSOLE);

	host_task_size = get_top_address(envp);
	/* reserve a few pages for the stubs */
	stub_start = host_task_size - STUB_SIZE;
	host_task_size = stub_start;

	/* Limit TASK_SIZE to what is addressable by the page table */
	task_size = host_task_size;
	if (task_size > (unsigned long long) PTRS_PER_PGD * PGDIR_SIZE)
		task_size = PTRS_PER_PGD * PGDIR_SIZE;

	/*
	 * TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps
	 * out
	 */
	task_size = task_size & PGDIR_MASK;

	/* OS sanity checks that need to happen before the kernel runs */
	os_early_checks();

	get_host_cpu_features(parse_host_cpu_flags, parse_cache_line);

	brk_start = (unsigned long) sbrk(0);

	/*
	 * Increase physical memory size for exec-shield users
	 * so they actually get what they asked for. This should
	 * add zero for non-exec shield users
	 */
	diff = PAGE_ALIGN(brk_start) - PAGE_ALIGN((unsigned long) &_end);
	if (diff > 1024 * 1024) {
		os_info("Adding %ld bytes to physical memory to account for "
			"exec-shield gap\n", diff);
		physmem_size += diff;
	}

	uml_physmem = (unsigned long) __binary_start & PAGE_MASK;

	/* Reserve up to 4M after the current brk */
	uml_reserved = ROUND_4M(brk_start) + (1 << 22);

	setup_machinename(init_utsname()->machine);

	physmem_size = PAGE_ALIGN(physmem_size);

Annotation

Implementation Notes