diff --git a/boards/x86-multiboot-common/include/multiboot.h b/boards/x86-multiboot-common/include/multiboot.h index 2b00b33118..1834eb9634 100644 --- a/boards/x86-multiboot-common/include/multiboot.h +++ b/boards/x86-multiboot-common/include/multiboot.h @@ -1,18 +1,22 @@ -/* Copyright (C) 1999, 2001 Free Software Foundation, Inc. - - This program 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 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +/* Copyright (C) 1999,2003,2007,2008,2009 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ /** * @defgroup boards_x86-multiboot i586 multiboot common @@ -32,107 +36,198 @@ extern "C" { #endif -#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 /**< The magic number for the Multiboot header. */ -#define MULTIBOOT_HEADER_FLAGS 0x00010003 /**< The flags for the Multiboot header. */ -#define MULTIBOOT_HEADER_CHECKSUM (-(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)) /**< The checksum for the Multiboot header. */ -#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 /**< The magic number passed by a Multiboot-compliant boot loader. */ +/** How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 + +/** The flags for the Multiboot header. */ +#define MULTIBOOT_HEADER_FLAGS 0x00010003 + +/** The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/** This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/** The bits in the required part of flags field we don't support. */ +#define MULTIBOOT_UNSUPPORTED 0x0000fffc + +/** Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/** Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/** Flags set in the 'flags' member of the multiboot header. */ + +/** Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/** Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/** Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/** This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/** Flags to be set in the 'flags' member of the multiboot info structure. */ + +/** is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/** is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/** is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/** are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/** These next two are mutually exclusive */ + +/** is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/** is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/** is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/** Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/** Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/** Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/** Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/** Is there video information? */ +#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800 + +#ifndef ASM_FILE + +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; -/** - * @brief The Multiboot header. - * - * A multiboot enabled kernel needs to contain this header in the first 8kB of the binary file. - */ typedef struct multiboot_header { - unsigned long magic; /**< Set to MULTIBOOT_HEADER_MAGIC. */ - unsigned long flags; /**< Set to MULTIBOOT_HEADER_FLAGS. */ - unsigned long checksum; /**< Set to MULTIBOOT_HEADER_CHECKSUM. */ - unsigned long header_addr; /**< The address of the datum. */ - unsigned long load_addr; /**< Set to `(uintptr_t) &_kernel_memory_start`. */ - unsigned long load_end_addr; /**< Set to `(uintptr_t) &_section_data_end`. */ - unsigned long bss_end_addr; /**< Set to `(uintptr_t) &_section_bss_end` */ - unsigned long entry_addr; /**< Your entry function. */ + /** Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /** Feature flags. */ + multiboot_uint32_t flags; + + /** The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; + + /** These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; + + /** These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; } multiboot_header_t; -/** - * @brief The symbol table for a.out. - * - * Do not use! - */ -typedef struct aout_symbol_table { - unsigned long tabsize; - unsigned long strsize; - unsigned long addr; - unsigned long reserved; -} aout_symbol_table_t; - -/** - * @brief The section header table for ELF. - * - * Do not use! - */ -typedef struct elf_section_header_table { - unsigned long num; - unsigned long size; - unsigned long addr; - unsigned long shndx; -} elf_section_header_table_t; - -/** - * @brief The multiboot information provided by the bootloader (e.g. Grub). - */ -typedef struct multiboot_info { - unsigned long flags; - unsigned long mem_lower; - unsigned long mem_upper; - unsigned long boot_device; - unsigned long cmdline; - unsigned long mods_count; - unsigned long mods_addr; - union { - aout_symbol_table_t aout_sym; - elf_section_header_table_t elf_sec; - } u; - unsigned long mmap_length; - unsigned long mmap_addr; -} multiboot_info_t; - -/** - * @brief The module structure. - * - * Do not use! - */ -typedef struct module { - unsigned long mod_start; - unsigned long mod_end; - unsigned long string; - unsigned long reserved; -} module_t; - -/** - * @brief An entry in the memory map table. - */ -typedef struct memory_map { - unsigned long size; - unsigned long base_addr_low; - unsigned long base_addr_high; - unsigned long length_low; - unsigned long length_high; - unsigned long type; -} memory_map_t; - -enum multiboot_info_flags { - MULTIBOOT_INFO_FLAGS_MEM = 0x01, - MULTIBOOT_INFO_FLAGS_BOOT = 0x02, - MULTIBOOT_INFO_FLAGS_CMDLINE = 0x04, - MULTIBOOT_INFO_FLAGS_MODS = 0x08, - MULTIBOOT_INFO_FLAGS_SYMS1 = 0x10, - MULTIBOOT_INFO_FLAGS_SYMS2 = 0x20, - MULTIBOOT_INFO_FLAGS_MMAP = 0x40, +/** The symbol table for a.out. */ +struct multiboot_aout_symbol_table { + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; }; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; -#ifdef __cplusplus -} -#endif +/** The section header table for ELF. */ +struct multiboot_elf_section_header_table { + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; -#endif /* MULTIBOOT_H_ */ -/** @} */ +struct multiboot_info { + /** Multiboot info version number */ + multiboot_uint32_t flags; + + /** Available memory from BIOS */ + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; + + /** "root" partition */ + multiboot_uint32_t boot_device; + + /** Kernel command line */ + multiboot_uint32_t cmdline; + + /** Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; + + union { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /** Memory Mapping buffer */ + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; + + /** Drive Info buffer */ + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; + + /** ROM configuration table */ + multiboot_uint32_t config_table; + + /** Boot Loader Name */ + multiboot_uint32_t boot_loader_name; + + /** APM table */ + multiboot_uint32_t apm_table; + + /** Video */ + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_mmap_entry { + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 + multiboot_uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list { + /** the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + + /** Module command line */ + multiboot_uint32_t cmdline; + + /** padding to take it to 16 bytes (must be zero) */ + multiboot_uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +#endif /** ! ASM_FILE */ + +#endif /** ! MULTIBOOT_HEADER */ diff --git a/boards/x86-multiboot-common/startup.c b/boards/x86-multiboot-common/startup.c index c4a039f7a7..45f8fd3913 100644 --- a/boards/x86-multiboot-common/startup.c +++ b/boards/x86-multiboot-common/startup.c @@ -52,7 +52,7 @@ extern const multiboot_header_t multiboot_header __attribute__((section("._multi const multiboot_header_t multiboot_header = { .magic = MULTIBOOT_HEADER_MAGIC, .flags = MULTIBOOT_HEADER_FLAGS, - .checksum = MULTIBOOT_HEADER_CHECKSUM, + .checksum = (-(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)), .header_addr = (uintptr_t) &multiboot_header, .load_addr = (uintptr_t) &_kernel_memory_start, .load_end_addr = (uintptr_t) &_section_data_end, @@ -80,11 +80,11 @@ bool x86_get_memory_region(uint64_t *start, uint64_t *len, unsigned long *pos) return false; } - const memory_map_t *mmap = (void *)(multiboot_info->mmap_addr + *pos); + const multiboot_memory_map_t *mmap = (void *)(multiboot_info->mmap_addr + *pos); *pos += mmap->size + 4; - *start = mmap->base_addr_low + ((uint64_t) mmap->base_addr_high << 32); - *len = mmap->length_low + ((uint64_t) mmap->length_high << 32); + *start = mmap->addr; + *len = mmap->len; uint64_t end = *start + *len; printf(" %08lx%08lx - %08lx%08lx ", (long) (*start >> 32), (long) *start, (long) (end >> 32), (long) end); @@ -134,7 +134,7 @@ static void __attribute__((noreturn)) startup(uint32_t multiboot_magic, const mu videoram_puts(" Multiboot magic is wrong \r\n"); x86_hlt(); } - else if (!(multiboot_info->flags && MULTIBOOT_INFO_FLAGS_MMAP)) { + else if (!(multiboot_info->flags && MULTIBOOT_INFO_MEM_MAP)) { videoram_puts(" Multiboot is lacking memory map information \r\n"); x86_hlt(); }