2 #include <lwk/kernel.h>
3 #include <lwk/string.h>
4 #include <lwk/screen_info.h>
5 #include <lwk/params.h>
7 #include <lwk/cpuinfo.h>
8 #include <arch/bootsetup.h>
9 #include <arch/sections.h>
11 #include <arch/processor.h>
12 #include <arch/desc.h>
13 #include <arch/proto.h>
14 #include <arch/page.h>
15 #include <arch/pgtable.h>
16 #include <arch/tlbflush.h>
19 * Data passed to the kernel by the bootloader.
21 * NOTE: This is marked as __initdata so it goes away after the
22 * kernel bootstrap process is complete.
24 char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
27 * Interrupt Descriptor Table (IDT) descriptor.
29 * This descriptor contains the length of the IDT table and a
30 * pointer to the table. The lidt instruction (load IDT) requires
33 struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
36 * Array of pointers to each CPU's per-processor data area.
37 * The array is indexed by CPU ID.
39 struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly;
42 * Array of per-processor data area structures, one per CPU.
43 * The array is indexed by CPU ID.
45 struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned;
48 * This unmaps virtual addresses [0,512GB) by clearing the first entry in the
49 * PGD/PML4T. After this executes, accesses to virtual addresses [0,512GB) will
53 zap_identity_mappings(void)
55 pgd_t *pgd = pgd_offset_k(0UL);
61 * Determines the address of the kernel boot command line.
64 find_command_line(void)
66 unsigned long new_data;
68 new_data = *(u32 *) (x86_boot_params + NEW_CL_POINTER);
70 if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) {
73 new_data = OLD_CL_BASE_ADDR + * (u16 *) OLD_CL_OFFSET;
75 return __va(new_data);
79 * This is the initial C entry point to the kernel.
80 * NOTE: The order of operations is usually important. Be careful.
83 x86_64_start_kernel(char * real_mode_data)
88 * Zero the "Block Started by Symbol" section...
89 * you know, the one that holds uninitialized data.
91 memset(__bss_start, 0,
92 (unsigned long) __bss_stop - (unsigned long) __bss_start);
95 * Make NULL pointer dereferences segfault.
97 zap_identity_mappings();
100 * Setup the initial interrupt descriptor table (IDT).
101 * This will be eventually be populated with the real handlers.
103 for (i = 0; i < 256; i++)
104 set_intr_gate(i, early_idt_handler);
105 asm volatile("lidt %0" :: "m" (idt_descr));
108 * Early per-processor data area (PDA) initialization.
110 for (i = 0; i < NR_CPUS; i++)
111 cpu_pda(i) = &boot_cpu_pda[i];
112 pda_init(0, &bootstrap_task_union.task_info);
115 * Make a copy data passed by the bootloader.
116 * real_mode_data will get clobbered eventually when the memory
117 * subsystem is initialized.
119 memcpy(x86_boot_params, __va(real_mode_data), sizeof(x86_boot_params));
120 memcpy(lwk_command_line, find_command_line(), sizeof(lwk_command_line));
123 * Tell the VGA driver the starting line number... this avoids
124 * overwriting BIOS and bootloader messages.
126 param_set_by_name_int("vga.row", SCREEN_INFO.orig_y);
129 * Okay... we've done the bare essentials. Call into the
130 * platform-independent bootstrap function. This will in turn
131 * call back into architecture dependent code to do things like
132 * initialize interrupts and boot CPUs.