From 95b841d37b8479851d16e0ad53bb29eda1da0744 Mon Sep 17 00:00:00 2001 From: robertmh Date: Tue, 11 Nov 2008 23:27:18 +0000 Subject: [PATCH] 2008-11-12 Robert Millan Use newly-added Multiboot support in coreboot. * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Replace `kern/i386/coreboot/mmap.c' with `kern/i386/multiboot_mmap.c'. * kern/i386/coreboot/startup.S: Enable Multiboot header, fix its alignment, set `MULTIBOOT_MEMORY_INFO' flag. (codestart): Store the MBI in `startup_multiboot_info' when we're being loaded using Multiboot. * kern/i386/coreboot/init.c (grub_machine_init): Move grub_at_keyboard_init() call to beginning of function (useful for debugging). Call grub_machine_mmap_init() before attempting to use grub_machine_mmap_iterate(). (grub_lower_mem, grub_upper_mem): Move from here ... * kern/i386/multiboot_mmap.c (grub_lower_mem, grub_upper_mem): ... to here (new file). * include/grub/i386/coreboot/memory.h (grub_machine_mmap_init): New function prototype. --- ChangeLog | 23 ++++++++ DISTLIST | 1 + conf/i386-coreboot.mk | 16 +++--- conf/i386-coreboot.rmk | 2 +- include/grub/i386/coreboot/memory.h | 2 + kern/i386/coreboot/init.c | 7 +-- kern/i386/coreboot/startup.S | 12 +++-- kern/i386/multiboot_mmap.c | 84 +++++++++++++++++++++++++++++ 8 files changed, 129 insertions(+), 18 deletions(-) create mode 100644 kern/i386/multiboot_mmap.c diff --git a/ChangeLog b/ChangeLog index 33e70ec89..cbb920c62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2008-11-12 Robert Millan + + Use newly-added Multiboot support in coreboot. + + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Replace + `kern/i386/coreboot/mmap.c' with `kern/i386/multiboot_mmap.c'. + + * kern/i386/coreboot/startup.S: Enable Multiboot header, fix its + alignment, set `MULTIBOOT_MEMORY_INFO' flag. + (codestart): Store the MBI in `startup_multiboot_info' when we're + being loaded using Multiboot. + + * kern/i386/coreboot/init.c (grub_machine_init): Move + grub_at_keyboard_init() call to beginning of function (useful for + debugging). Call grub_machine_mmap_init() before attempting to use + grub_machine_mmap_iterate(). + (grub_lower_mem, grub_upper_mem): Move from here ... + * kern/i386/multiboot_mmap.c (grub_lower_mem, grub_upper_mem): ... to + here (new file). + + * include/grub/i386/coreboot/memory.h (grub_machine_mmap_init): New + function prototype. + 2008-11-12 Robert Millan Fix a regression introduced by the at_keyboard.mod split. Because diff --git a/DISTLIST b/DISTLIST index 95f28a4d0..01046c2e4 100644 --- a/DISTLIST +++ b/DISTLIST @@ -313,6 +313,7 @@ kern/generic/rtc_get_time_ms.c kern/i386/dl.c kern/i386/halt.c kern/i386/loader.S +kern/i386/multiboot_mmap.c kern/i386/pit.c kern/i386/realmode.S kern/i386/reboot.c diff --git a/conf/i386-coreboot.mk b/conf/i386-coreboot.mk index aaa221c61..f15ae2158 100644 --- a/conf/i386-coreboot.mk +++ b/conf/i386-coreboot.mk @@ -14,7 +14,7 @@ pkglib_PROGRAMS = kernel.elf # For kernel.elf. kernel_elf_SOURCES = kern/i386/coreboot/startup.S \ kern/i386/coreboot/init.c \ - kern/i386/coreboot/mmap.c \ + kern/i386/multiboot_mmap.c \ kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ @@ -27,11 +27,11 @@ kernel_elf_SOURCES = kern/i386/coreboot/startup.S \ term/i386/pc/console.c \ term/i386/pc/at_keyboard.c term/i386/pc/vga_text.c \ symlist.c -CLEANFILES += kernel.elf kernel_elf-kern_i386_coreboot_startup.o kernel_elf-kern_i386_coreboot_init.o kernel_elf-kern_i386_coreboot_mmap.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_time.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_i386_tsc.o kernel_elf-kern_i386_pit.o kernel_elf-kern_generic_rtc_get_time_ms.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_env.o kernel_elf-term_i386_pc_console.o kernel_elf-term_i386_pc_at_keyboard.o kernel_elf-term_i386_pc_vga_text.o kernel_elf-symlist.o -MOSTLYCLEANFILES += kernel_elf-kern_i386_coreboot_startup.d kernel_elf-kern_i386_coreboot_init.d kernel_elf-kern_i386_coreboot_mmap.d kernel_elf-kern_main.d kernel_elf-kern_device.d kernel_elf-kern_disk.d kernel_elf-kern_dl.d kernel_elf-kern_file.d kernel_elf-kern_fs.d kernel_elf-kern_err.d kernel_elf-kern_misc.d kernel_elf-kern_mm.d kernel_elf-kern_loader.d kernel_elf-kern_rescue.d kernel_elf-kern_term.d kernel_elf-kern_time.d kernel_elf-kern_i386_dl.d kernel_elf-kern_parser.d kernel_elf-kern_partition.d kernel_elf-kern_i386_tsc.d kernel_elf-kern_i386_pit.d kernel_elf-kern_generic_rtc_get_time_ms.d kernel_elf-kern_generic_millisleep.d kernel_elf-kern_env.d kernel_elf-term_i386_pc_console.d kernel_elf-term_i386_pc_at_keyboard.d kernel_elf-term_i386_pc_vga_text.d kernel_elf-symlist.d +CLEANFILES += kernel.elf kernel_elf-kern_i386_coreboot_startup.o kernel_elf-kern_i386_coreboot_init.o kernel_elf-kern_i386_multiboot_mmap.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_time.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_i386_tsc.o kernel_elf-kern_i386_pit.o kernel_elf-kern_generic_rtc_get_time_ms.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_env.o kernel_elf-term_i386_pc_console.o kernel_elf-term_i386_pc_at_keyboard.o kernel_elf-term_i386_pc_vga_text.o kernel_elf-symlist.o +MOSTLYCLEANFILES += kernel_elf-kern_i386_coreboot_startup.d kernel_elf-kern_i386_coreboot_init.d kernel_elf-kern_i386_multiboot_mmap.d kernel_elf-kern_main.d kernel_elf-kern_device.d kernel_elf-kern_disk.d kernel_elf-kern_dl.d kernel_elf-kern_file.d kernel_elf-kern_fs.d kernel_elf-kern_err.d kernel_elf-kern_misc.d kernel_elf-kern_mm.d kernel_elf-kern_loader.d kernel_elf-kern_rescue.d kernel_elf-kern_term.d kernel_elf-kern_time.d kernel_elf-kern_i386_dl.d kernel_elf-kern_parser.d kernel_elf-kern_partition.d kernel_elf-kern_i386_tsc.d kernel_elf-kern_i386_pit.d kernel_elf-kern_generic_rtc_get_time_ms.d kernel_elf-kern_generic_millisleep.d kernel_elf-kern_env.d kernel_elf-term_i386_pc_console.d kernel_elf-term_i386_pc_at_keyboard.d kernel_elf-term_i386_pc_vga_text.d kernel_elf-symlist.d -kernel.elf: $(kernel_elf_DEPENDENCIES) kernel_elf-kern_i386_coreboot_startup.o kernel_elf-kern_i386_coreboot_init.o kernel_elf-kern_i386_coreboot_mmap.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_time.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_i386_tsc.o kernel_elf-kern_i386_pit.o kernel_elf-kern_generic_rtc_get_time_ms.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_env.o kernel_elf-term_i386_pc_console.o kernel_elf-term_i386_pc_at_keyboard.o kernel_elf-term_i386_pc_vga_text.o kernel_elf-symlist.o - $(TARGET_CC) -o $@ kernel_elf-kern_i386_coreboot_startup.o kernel_elf-kern_i386_coreboot_init.o kernel_elf-kern_i386_coreboot_mmap.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_time.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_i386_tsc.o kernel_elf-kern_i386_pit.o kernel_elf-kern_generic_rtc_get_time_ms.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_env.o kernel_elf-term_i386_pc_console.o kernel_elf-term_i386_pc_at_keyboard.o kernel_elf-term_i386_pc_vga_text.o kernel_elf-symlist.o $(TARGET_LDFLAGS) $(kernel_elf_LDFLAGS) +kernel.elf: $(kernel_elf_DEPENDENCIES) kernel_elf-kern_i386_coreboot_startup.o kernel_elf-kern_i386_coreboot_init.o kernel_elf-kern_i386_multiboot_mmap.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_time.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_i386_tsc.o kernel_elf-kern_i386_pit.o kernel_elf-kern_generic_rtc_get_time_ms.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_env.o kernel_elf-term_i386_pc_console.o kernel_elf-term_i386_pc_at_keyboard.o kernel_elf-term_i386_pc_vga_text.o kernel_elf-symlist.o + $(TARGET_CC) -o $@ kernel_elf-kern_i386_coreboot_startup.o kernel_elf-kern_i386_coreboot_init.o kernel_elf-kern_i386_multiboot_mmap.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_time.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_i386_tsc.o kernel_elf-kern_i386_pit.o kernel_elf-kern_generic_rtc_get_time_ms.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_env.o kernel_elf-term_i386_pc_console.o kernel_elf-term_i386_pc_at_keyboard.o kernel_elf-term_i386_pc_vga_text.o kernel_elf-symlist.o $(TARGET_LDFLAGS) $(kernel_elf_LDFLAGS) kernel_elf-kern_i386_coreboot_startup.o: kern/i386/coreboot/startup.S $(kern/i386/coreboot/startup.S_DEPENDENCIES) $(TARGET_CC) -Ikern/i386/coreboot -I$(srcdir)/kern/i386/coreboot $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< @@ -41,9 +41,9 @@ kernel_elf-kern_i386_coreboot_init.o: kern/i386/coreboot/init.c $(kern/i386/core $(TARGET_CC) -Ikern/i386/coreboot -I$(srcdir)/kern/i386/coreboot $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< -include kernel_elf-kern_i386_coreboot_init.d -kernel_elf-kern_i386_coreboot_mmap.o: kern/i386/coreboot/mmap.c $(kern/i386/coreboot/mmap.c_DEPENDENCIES) - $(TARGET_CC) -Ikern/i386/coreboot -I$(srcdir)/kern/i386/coreboot $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< --include kernel_elf-kern_i386_coreboot_mmap.d +kernel_elf-kern_i386_multiboot_mmap.o: kern/i386/multiboot_mmap.c $(kern/i386/multiboot_mmap.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_i386_multiboot_mmap.d kernel_elf-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 78088fd3f..79333e5b7 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -13,7 +13,7 @@ pkglib_PROGRAMS = kernel.elf # For kernel.elf. kernel_elf_SOURCES = kern/i386/coreboot/startup.S \ kern/i386/coreboot/init.c \ - kern/i386/coreboot/mmap.c \ + kern/i386/multiboot_mmap.c \ kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ diff --git a/include/grub/i386/coreboot/memory.h b/include/grub/i386/coreboot/memory.h index 687077c48..b1b015472 100644 --- a/include/grub/i386/coreboot/memory.h +++ b/include/grub/i386/coreboot/memory.h @@ -59,6 +59,8 @@ struct grub_linuxbios_mem_region }; typedef struct grub_linuxbios_mem_region *mem_region_t; +void grub_machine_mmap_init (void); + void EXPORT_FUNC(grub_machine_mmap_iterate) (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index 051154765..e08bc866d 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -42,7 +42,6 @@ extern char _end[]; grub_addr_t grub_os_area_addr; grub_size_t grub_os_area_size; -grub_size_t grub_lower_mem, grub_upper_mem; /* FIXME: we need interrupts to do this right */ static grub_uint32_t grub_time_tics = 0; @@ -79,9 +78,7 @@ grub_machine_init (void) { /* Initialize the console as early as possible. */ grub_console_init (); - - grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE; - grub_upper_mem = 0; + grub_at_keyboard_init (); auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, grub_uint32_t); int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) @@ -132,13 +129,13 @@ grub_machine_init (void) return 0; } + grub_machine_mmap_init (); grub_machine_mmap_iterate (heap_init); /* This variable indicates size, not offset. */ grub_upper_mem -= GRUB_MEMORY_MACHINE_UPPER_START; grub_tsc_init (); - grub_at_keyboard_init (); } void diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S index 8d1aa3c15..835978bfe 100644 --- a/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -55,20 +55,24 @@ VARIABLE(grub_prefix) . = EXT_C(start) + GRUB_KERNEL_CPU_DATA_END -#if 0 /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). */ + .p2align 2 /* force 4-byte alignment */ multiboot_header: /* magic */ .long 0x1BADB002 /* flags */ - .long 0 + .long MULTIBOOT_MEMORY_INFO /* checksum */ - .long -0x1BADB002 -#endif + .long -0x1BADB002 - MULTIBOOT_MEMORY_INFO codestart: + cmpl $MULTIBOOT_MAGIC2, %eax + jne 0f + movl %ebx, EXT_C(startup_multiboot_info) +0: + /* initialize the stack */ movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp diff --git a/kern/i386/multiboot_mmap.c b/kern/i386/multiboot_mmap.c new file mode 100644 index 000000000..16f155bac --- /dev/null +++ b/kern/i386/multiboot_mmap.c @@ -0,0 +1,84 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +grub_size_t grub_lower_mem, grub_upper_mem; + +/* A pointer to the MBI in its initial location. */ +struct grub_multiboot_info *startup_multiboot_info; + +/* The MBI has to be copied to our BSS so that it won't be + overwritten. This is its final location. */ +static struct grub_multiboot_info kern_multiboot_info; + +/* Unfortunately we can't use heap at this point. But 32 looks like a sane + limit (used by memtest86). */ +static grub_uint8_t mmap_entries[sizeof (struct grub_multiboot_mmap_entry) * 32]; + +void +grub_machine_mmap_init () +{ + if (! startup_multiboot_info) + grub_fatal ("Must be loaded using Multiboot specification (is this an old version of coreboot?)"); + + /* Move MBI to a safe place. */ + grub_memmove (&kern_multiboot_info, startup_multiboot_info, sizeof (struct grub_multiboot_info)); + + if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEM_MAP) == 0) + grub_fatal ("Missing Multiboot memory information"); + + /* Move the memory map to a safe place. */ + if (kern_multiboot_info.mmap_length > sizeof (mmap_entries)) + { + grub_printf ("WARNING: Memory map size exceeds limit; it will be truncated\n"); + kern_multiboot_info.mmap_length = sizeof (mmap_entries); + } + grub_memmove (mmap_entries, (void *) kern_multiboot_info.mmap_addr, kern_multiboot_info.mmap_length); + kern_multiboot_info.mmap_addr = (grub_uint32_t) mmap_entries; + + if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEMORY) == 0) + { + grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE; + grub_upper_mem = 0; + } + else + { + grub_lower_mem = kern_multiboot_info.mem_lower * 1024; + grub_upper_mem = kern_multiboot_info.mem_upper * 1024; + } +} + +void +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +{ + struct grub_multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr; + + while ((unsigned long) entry < kern_multiboot_info.mmap_addr + kern_multiboot_info.mmap_length) + { + if (hook (entry->addr, entry->len, entry->type)) + break; + + entry = (void *) ((grub_addr_t) entry + entry->size + sizeof (entry->size)); + } +}