Kernel: Make better use of the multiboot info.

Define the multiboot info struct properly so we don't have to grab at byte
offsets in the memory access checker code. Also print kernel command line
in init().
This commit is contained in:
Andreas Kling 2019-06-02 09:50:18 +02:00
parent 8454d3e184
commit 4320c5fd58
Notes: sideshowbarker 2024-07-19 13:47:53 +09:00
5 changed files with 115 additions and 28 deletions

View file

@ -39,8 +39,8 @@ stack_top:
.extern init
.type init, @function
.extern multiboot_ptr
.type multiboot_ptr, @object
.extern multiboot_info_ptr
.type multiboot_info_ptr, @object
start:
cli
@ -54,7 +54,7 @@ start:
pushl %eax /* Multiboot header magic */
pushl %ebx /* Multiboot header pointer */
mov %ebx, multiboot_ptr
mov %ebx, multiboot_info_ptr
call init

97
Kernel/Multiboot.h Normal file
View file

@ -0,0 +1,97 @@
#pragma once
#include <AK/Types.h>
struct multiboot_aout_symbol_table {
dword tabsize;
dword strsize;
dword addr;
dword reserved;
};
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
struct multiboot_elf_section_header_table {
dword num;
dword size;
dword addr;
dword shndx;
};
typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
struct multiboot_info {
// Multiboot info version number.
dword flags;
// Available memory from BIOS.
dword mem_lower;
dword mem_upper;
// "root" partition.
dword boot_device;
// Kernel command line.
dword cmdline;
// Boot-Module list.
dword mods_count;
dword mods_addr;
union {
multiboot_aout_symbol_table_t aout_sym;
multiboot_elf_section_header_table_t elf_sec;
} u;
// Memory Mapping buffer.
dword mmap_length;
dword mmap_addr;
// Drive Info buffer.
dword drives_length;
dword drives_addr;
// ROM configuration table.
dword config_table;
// Boot Loader Name.
dword boot_loader_name;
// APM table.
dword apm_table;
// Video.
dword vbe_control_info;
dword vbe_mode_info;
word vbe_mode;
word vbe_interface_seg;
word vbe_interface_off;
word vbe_interface_len;
qword framebuffer_addr;
dword framebuffer_pitch;
dword framebuffer_width;
dword framebuffer_height;
byte framebuffer_bpp;
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
byte framebuffer_type;
union {
struct
{
dword framebuffer_palette_addr;
word framebuffer_palette_num_colors;
};
struct
{
byte framebuffer_red_field_position;
byte framebuffer_red_mask_size;
byte framebuffer_green_field_position;
byte framebuffer_green_mask_size;
byte framebuffer_blue_field_position;
byte framebuffer_blue_mask_size;
};
};
};
typedef struct multiboot_info multiboot_info_t;
extern "C" multiboot_info_t* multiboot_info_ptr;

View file

@ -25,6 +25,7 @@
#include <Kernel/SharedMemory.h>
#include <Kernel/ProcessTracer.h>
#include <Kernel/FileSystem/Custody.h>
#include <Kernel/Multiboot.h>
//#define DEBUG_POLL_SELECT
//#define DEBUG_IO
@ -1433,33 +1434,12 @@ enum class KernelMemoryCheckResult {
AccessDenied
};
// FIXME: Nothing about this is really super...
// This structure is only present at offset 28 in the main multiboot info struct
// if bit 5 of offset 0 (flags) is set. We're just assuming that the flag is set.
//
// Also, there's almost certainly a better way to get that information here than
// a global set by boot.S
//
// Also I'm not 100% sure any of this is correct...
struct mb_elf {
uint32_t num;
uint32_t size;
uint32_t addr;
uint32_t shndx;
};
extern "C" {
void* multiboot_ptr;
}
static KernelMemoryCheckResult check_kernel_memory_access(LinearAddress laddr, bool is_write)
{
// FIXME: It would be better to have a proper structure for this...
auto* sections = (const mb_elf*)((const byte*)multiboot_ptr + 28);
auto& sections = multiboot_info_ptr->u.elf_sec;
auto* kernel_program_headers = (Elf32_Phdr*)(sections->addr);
for (unsigned i = 0; i < sections->num; ++i) {
auto* kernel_program_headers = (Elf32_Phdr*)(sections.addr);
for (unsigned i = 0; i < sections.num; ++i) {
auto& segment = kernel_program_headers[i];
if (segment.p_type != PT_LOAD || !segment.p_vaddr || !segment.p_memsz)
continue;

View file

@ -25,6 +25,7 @@
#include <Kernel/Net/E1000NetworkAdapter.h>
#include <Kernel/Net/NetworkTask.h>
#include <Kernel/Devices/DebugLogDevice.h>
#include <Kernel/Multiboot.h>
//#define STRESS_TEST_SPAWNING
@ -94,9 +95,13 @@ VFS* vfs;
ASSERT_NOT_REACHED();
}
extern "C" {
multiboot_info_t* multiboot_info_ptr;
}
extern "C" [[noreturn]] void init()
{
cli();
kprintf("Kernel command line: '%s'\n", multiboot_info_ptr->cmdline);
sse_init();

View file

@ -2,6 +2,8 @@
[ -z "$SERENITY_QEMU_BIN" ] && SERENITY_QEMU_BIN="qemu-system-i386"
SERENITY_KERNEL_CMDLINE="hello"
export SDL_VIDEO_X11_DGAMOUSE=0
ram_size=128
@ -17,6 +19,7 @@ elif [ "$1" = "qn" ]; then
-debugcon stdio \
-device e1000 \
-kernel kernel \
-append ${SERENITY_KERNEL_CMDLINE} \
-hda _fs_contents \
-soundhw pcspk
elif [ "$1" = "qtap" ]; then
@ -30,6 +33,7 @@ elif [ "$1" = "qtap" ]; then
-netdev tap,ifname=tap0,id=br0 \
-device e1000,netdev=br0 \
-kernel kernel \
-append ${SERENITY_KERNEL_CMDLINE} \
-hda _fs_contents \
-soundhw pcspk
else
@ -43,6 +47,7 @@ else
-netdev user,id=breh,hostfwd=tcp:127.0.0.1:8888-192.168.5.2:8888 \
-device e1000,netdev=breh \
-kernel kernel \
-append ${SERENITY_KERNEL_CMDLINE} \
-hda _fs_contents \
-soundhw pcspk
fi