diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2015-05-21 10:26:49 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-05-21 11:44:57 +0200 |
commit | fa9ea2e622eb105fb77f1f09e3194bfc05db7c5e (patch) | |
tree | be8d9bd2dd39fb6cd6c090f8c7bbbf1d43a39f90 | |
parent | bd363b8030716a759823d8828690e49ad4d25f96 (diff) | |
download | qboot-fa9ea2e622eb105fb77f1f09e3194bfc05db7c5e.zip qboot-fa9ea2e622eb105fb77f1f09e3194bfc05db7c5e.tar.gz qboot-fa9ea2e622eb105fb77f1f09e3194bfc05db7c5e.tar.bz2 |
add malloc
Allocate the e820 map in the E-segment.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | code16.c | 23 | ||||
-rw-r--r-- | flat.lds | 6 | ||||
-rw-r--r-- | include/bios.h | 2 | ||||
-rw-r--r-- | include/e820.h | 26 | ||||
-rw-r--r-- | include/string.h | 3 | ||||
-rw-r--r-- | main.c | 24 | ||||
-rw-r--r-- | malloc.c | 21 |
8 files changed, 63 insertions, 44 deletions
@@ -1,5 +1,5 @@ obj-y = code16.o entry.o main.o string.o printf.o cstart.o fw_cfg.o -obj-y += linuxboot.o +obj-y += linuxboot.o malloc.o all-y = bios.bin all: $(all-y) @@ -1,4 +1,5 @@ asm(".code16gcc"); +#include <stddef.h> #include "bios.h" #include "segment.h" #include "ioport.h" @@ -23,32 +24,40 @@ static inline uint32_t rdfs32(unsigned long addr) { uint32_t v; - asm volatile("addr32 movl %%fs:%1,%0" : "=q" (v) : "m" (*(uint32_t *)addr)); + asm volatile("addr32 movl %%fs:%1,%0" : "=r" (v) : "m" (*(uint32_t *)addr)); return v; } -struct e820map e820; +static inline uint16_t rdcs16(void *p) +{ + uint32_t addr = ((uintptr_t) p) & 65535; + uint16_t v; + + asm volatile("addr32 movw %%cs:%1,%0" : "=r" (v) : "m" (*(uint32_t *)addr)); + + return v; +} + +uint16_t e820_seg; bioscall void e820_query_map(struct biosregs *regs) { uint32_t map_size; - uint16_t fs_seg; uint32_t ndx; - fs_seg = flat_to_seg16((uintptr_t) &e820); - set_fs(fs_seg); + set_fs(rdcs16(&e820_seg)); ndx = regs->ebx; - map_size = rdfs32(flat_to_off16((uintptr_t) &e820.nr_map)); + map_size = rdfs32(offsetof(struct e820map, nr_map)); if (ndx < map_size) { uint32_t start; unsigned int i; uint8_t *p; - start = flat_to_off16((uintptr_t)&e820.map[ndx]); + start = flat_to_off16(offsetof(struct e820map, map[ndx])); p = (void *) regs->edi; @@ -3,14 +3,16 @@ OUTPUT_ARCH(i386) SECTIONS { . = 1024K - 64K; + stext = .; .text : { *(.text.startup) *(.text) *(.text.*) } - . = ALIGN(4K); + . = ALIGN(16); .data : { *(.data) } . = ALIGN(16); .rodata : { *(.rodata) } . = ALIGN(16); .bss : { *(.bss) } - . = ALIGN(4K); + . = ALIGN(16); + edata = .; . = 1024K - 128; .init : { *(.init); diff --git a/include/bios.h b/include/bios.h index 93c4c96..d3f9a22 100644 --- a/include/bios.h +++ b/include/bios.h @@ -38,7 +38,7 @@ extern void bios_int15(void); extern void boot_from_fwcfg(void); -extern struct e820map e820; +extern uint16_t e820_seg; #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) diff --git a/include/e820.h b/include/e820.h index 1dfd18f..085df6a 100644 --- a/include/e820.h +++ b/include/e820.h @@ -2,30 +2,6 @@ #define _UAPI_ASM_X86_E820_H #define SMAP 0x534d4150 /* ASCII "SMAP" */ -#define E820MAP 0x2d0 /* our map */ -#define E820MAX 128 /* number of entries in E820MAP */ - -/* - * Legacy E820 BIOS limits us to 128 (E820MAX) nodes due to the - * constrained space in the zeropage. If we have more nodes than - * that, and if we've booted off EFI firmware, then the EFI tables - * passed us from the EFI firmware can list more nodes. Size our - * internal memory map tables to have room for these additional - * nodes, based on up to three entries per node for which the - * kernel was built: MAX_NUMNODES == (1 << CONFIG_NODES_SHIFT), - * plus E820MAX, allowing space for the possible duplicate E820 - * entries that might need room in the same arrays, prior to the - * call to sanitize_e820_map() to remove duplicates. The allowance - * of three memory map entries per node is "enough" entries for - * the initial hardware platform motivating this mechanism to make - * use of additional EFI map entries. Future platforms may want - * to allow more than three entries per node or otherwise refine - * this size. - */ - -#define E820_X_MAX E820MAX - -#define E820NR 0x1e8 /* # entries in E820MAP */ #define E820_RAM 1 #define E820_RESERVED 2 @@ -50,7 +26,7 @@ struct e820entry { struct e820map { uint32_t nr_map; - struct e820entry map[E820_X_MAX]; + struct e820entry map[]; }; #define ISA_START_ADDRESS 0xa0000 diff --git a/include/string.h b/include/string.h index 962b07e..9b0b8af 100644 --- a/include/string.h +++ b/include/string.h @@ -15,4 +15,7 @@ int memcmp(const void *s1, const void *s2, size_t n); void *memmove(void *dest, const void *src, size_t n); void *memchr(const void *s, int c, size_t n); +void *malloc(int n); +void *malloc_fseg(int n); + #endif @@ -1,4 +1,5 @@ #include "bios.h" +#include "stdio.h" #include "e820.h" #include "pci.h" #include "string.h" @@ -83,24 +84,31 @@ static void extract_e820(void) { int id = fw_cfg_file_id("etc/e820"); uint32_t size; + int nr_map; + struct e820map *e820; if (id == -1) panic(); size = fw_cfg_file_size(id); - e820.nr_map = size / sizeof(e820.map[0]) + 4; + nr_map = size / sizeof(e820->map[0]) + 4; fw_cfg_file_select(id); - e820.map[0] = (struct e820entry) + + e820 = malloc(offsetof(struct e820map, map[nr_map])); + e820->nr_map = nr_map; + e820->map[0] = (struct e820entry) { .addr = 0, .size = 639 * 1024, .type = E820_RAM }; /* low RAM */ - e820.map[1] = (struct e820entry) + e820->map[1] = (struct e820entry) { .addr = 639 * 1024, .size = 1024, .type = E820_RESERVED }; /* EBDA */ - e820.map[2] = (struct e820entry) + e820->map[2] = (struct e820entry) { .addr = 0xe0000, .size = 64 * 1024, .type = E820_NVS }; /* ACPI tables */ - e820.map[3] = (struct e820entry) + e820->map[3] = (struct e820entry) { .addr = 0xf0000, .size = 64 * 1024, .type = E820_RESERVED }; /* firmware */ - fw_cfg_read(&e820.map[4], size); - e820.map[4].addr = 1024 * 1024; - e820.map[4].size -= 1024 * 1024; + fw_cfg_read(&e820->map[4], size); + e820->map[4].addr = 1024 * 1024; + e820->map[4].size -= 1024 * 1024; + + e820_seg = ((uintptr_t) e820) >> 4; } int main(void) diff --git a/malloc.c b/malloc.c new file mode 100644 index 0000000..3ab95ed --- /dev/null +++ b/malloc.c @@ -0,0 +1,21 @@ +#include <inttypes.h> +#include "string.h" + +extern uint8_t edata; +static uint8_t *fseg_base = &edata; + +extern uint8_t stext; +static uint8_t *malloc_top = &stext; + +void *malloc(int n) +{ + malloc_top -= (n + 15) & -16; + return malloc_top; +} + +void *malloc_fseg(int n) +{ + void *p = fseg_base; + fseg_base += (n + 15) & -16; + return p; +} |