Skip to content

Commit 5100dab

Browse files
committed
Kernel: Copy the kernel command line to a good location at boot
When building the kernel with -O2, we somehow ended up with the kernel command line outside of the lower 8MB of physical memory. Since we don't map that area in our initial page table setup, we would triple fault when trying to parse the command line. This patch sidesteps the issue by copying the (first 4KB of) the kernel command line to a buffer in a known safe location at boot.
1 parent 4172a46 commit 5100dab

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

Kernel/Arch/i386/Boot/boot.S

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ stack_bottom:
3131
.skip 32768
3232
stack_top:
3333

34+
.global kernel_cmdline
35+
kernel_cmdline:
36+
.skip 4096
37+
3438
.section .page_tables, "aw", @nobits
3539
.align 4096
3640
.global boot_pdpt
@@ -93,6 +97,19 @@ start:
9397
cli
9498
cld
9599

100+
/* We don't know where the bootloader might have put the command line.
101+
* It might be at an inconvenient location that we're not about to map,
102+
* so let's just copy it to a convenient location while we have the whole
103+
* memory space identity-mapped anyway. :^)
104+
*/
105+
106+
movl %ebx, %esi
107+
addl $16, %esi
108+
movl (%esi), %esi
109+
movl $1024, %ecx
110+
movl $(kernel_cmdline - 0xc0000000), %edi
111+
rep movsl
112+
96113
/* clear pdpt */
97114
movl $(boot_pdpt - 0xc0000000), %edi
98115
movl $1024, %ecx

Kernel/init.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ extern "C" u8* end_of_safemem_atomic_text;
9191
multiboot_module_entry_t multiboot_copy_boot_modules_array[16];
9292
size_t multiboot_copy_boot_modules_count;
9393

94+
extern "C" const char kernel_cmdline[4096];
95+
9496
namespace Kernel {
9597

9698
[[noreturn]] static void init_stage2(void*);
@@ -122,7 +124,7 @@ extern "C" UNMAP_AFTER_INIT [[noreturn]] void init()
122124

123125
// We need to copy the command line before kmalloc is initialized,
124126
// as it may overwrite parts of multiboot!
125-
CommandLine::early_initialize(reinterpret_cast<const char*>(low_physical_to_virtual(multiboot_info_ptr->cmdline)));
127+
CommandLine::early_initialize(kernel_cmdline);
126128
memcpy(multiboot_copy_boot_modules_array, (u8*)low_physical_to_virtual(multiboot_info_ptr->mods_addr), multiboot_info_ptr->mods_count * sizeof(multiboot_module_entry_t));
127129
multiboot_copy_boot_modules_count = multiboot_info_ptr->mods_count;
128130
s_bsp_processor.early_initialize(0);
@@ -328,9 +330,9 @@ UNMAP_AFTER_INIT void setup_serial_debug()
328330
// serial_debug will output all the klog() and dbgln() data to COM1 at
329331
// 8-N-1 57600 baud. this is particularly useful for debugging the boot
330332
// process on live hardware.
331-
u32 cmdline = low_physical_to_virtual(multiboot_info_ptr->cmdline);
332-
if (cmdline && StringView(reinterpret_cast<const char*>(cmdline)).contains("serial_debug"))
333+
if (StringView(kernel_cmdline).contains("serial_debug")) {
333334
set_serial_debug(true);
335+
}
334336
}
335337

336338
extern "C" {

0 commit comments

Comments
 (0)