[platform][qemu-virt] read the memory size out of the FDT using libfdt
-Bump the kernel forward by 64K
-Look for the FDT that qemu leaves around in the space just before the kernel
-Pick out the 'memory' node, parse the base/length values and patch the main
pmm arena before adding it
This commit is contained in:
@@ -36,13 +36,14 @@
|
||||
#include <platform/gic.h>
|
||||
#include <platform/interrupts.h>
|
||||
#include <platform/qemu-virt.h>
|
||||
#include <libfdt.h>
|
||||
#include "platform_p.h"
|
||||
|
||||
#if WITH_LIB_MINIP
|
||||
#include <lib/minip.h>
|
||||
#endif
|
||||
|
||||
#define MEMORY_SIZE (MEMSIZE) // XXX get this from the emulator somehow
|
||||
#define DEFAULT_MEMORY_SIZE (MEMSIZE) /* try to fetch from the emulator via the fdt */
|
||||
|
||||
/* initial memory mappings. parsed by start.S */
|
||||
struct mmu_initial_mapping mmu_initial_mappings[] = {
|
||||
@@ -71,7 +72,7 @@ struct mmu_initial_mapping mmu_initial_mappings[] = {
|
||||
static pmm_arena_t arena = {
|
||||
.name = "ram",
|
||||
.base = MEMORY_BASE_PHYS,
|
||||
.size = MEMORY_SIZE,
|
||||
.size = DEFAULT_MEMORY_SIZE,
|
||||
.flags = PMM_ARENA_FLAG_KMAP,
|
||||
};
|
||||
|
||||
@@ -84,8 +85,53 @@ void platform_early_init(void)
|
||||
|
||||
uart_init_early();
|
||||
|
||||
/* look for a flattened device tree just before the kernel */
|
||||
const void *fdt = (void *)KERNEL_BASE;
|
||||
int err = fdt_check_header(fdt);
|
||||
if (err >= 0) {
|
||||
/* walk the nodes, looking for 'memory' */
|
||||
int depth = 0;
|
||||
int offset = 0;
|
||||
for (;;) {
|
||||
offset = fdt_next_node(fdt, offset, &depth);
|
||||
if (offset < 0)
|
||||
break;
|
||||
|
||||
/* get the name */
|
||||
const char *name = fdt_get_name(fdt, offset, NULL);
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
/* look for the 'memory' property */
|
||||
if (strcmp(name, "memory") == 0) {
|
||||
int lenp;
|
||||
const void *prop_ptr = fdt_getprop(fdt, offset, "reg", &lenp);
|
||||
if (prop_ptr && lenp == 0x10) {
|
||||
/* we're looking at a memory descriptor */
|
||||
//uint64_t base = fdt64_to_cpu(*(uint64_t *)prop_ptr);
|
||||
uint64_t len = fdt64_to_cpu(*((const uint64_t *)prop_ptr + 1));
|
||||
|
||||
/* trim size on certain platforms */
|
||||
#if ARCH_ARM
|
||||
if (len > 1024*1024*1024U) {
|
||||
len = 1024*1024*1024; /* only use the first 1GB on ARM32 */
|
||||
printf("trimming memory to 1GB\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set the size in the pmm arena */
|
||||
arena.size = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add the main memory arena */
|
||||
pmm_add_arena(&arena);
|
||||
|
||||
/* reserve the first 64k of ram, which should be holding the fdt */
|
||||
struct list_node list = LIST_INITIAL_VALUE(list);
|
||||
pmm_alloc_range(MEMBASE, 0x10000 / PAGE_SIZE, &list);
|
||||
}
|
||||
|
||||
void platform_init(void)
|
||||
|
||||
@@ -23,9 +23,11 @@ MODULE_SRCS += \
|
||||
|
||||
MEMBASE := 0x40000000
|
||||
MEMSIZE ?= 0x08000000 # 512MB
|
||||
KERNEL_LOAD_OFFSET := 0x10000 # 64k
|
||||
|
||||
MODULE_DEPS += \
|
||||
lib/cbuf \
|
||||
lib/fdt \
|
||||
dev/interrupt/arm_gic \
|
||||
dev/timer/arm_generic \
|
||||
dev/virtio/block \
|
||||
|
||||
@@ -7,6 +7,7 @@ function HELP {
|
||||
echo "-t a virtio tap network device"
|
||||
echo "-d a virtio display"
|
||||
echo "-6 64bit arm"
|
||||
echo "-m <memory in MB>"
|
||||
echo "-h for help"
|
||||
echo "all arguments after -- are passed to qemu directly"
|
||||
exit 1
|
||||
@@ -17,15 +18,18 @@ DO_NET_TAP=0
|
||||
DO_BLOCK=0
|
||||
DO_64BIT=0
|
||||
DO_DISPLAY=0
|
||||
MEMSIZE=512
|
||||
SUDO=""
|
||||
|
||||
while getopts bdhnt6 FLAG; do
|
||||
while getopts bdhm:nt6 FLAG; do
|
||||
case $FLAG in
|
||||
b) DO_BLOCK=1;;
|
||||
d) DO_DISPLAY=1;;
|
||||
n) DO_NET=1;;
|
||||
t) DO_NET_TAP=1;;
|
||||
6) DO_64BIT=1;;
|
||||
6) DO_MEM=1;;
|
||||
m) MEMSIZE=$OPTARG;;
|
||||
h) HELP;;
|
||||
\?)
|
||||
echo unrecognized option
|
||||
@@ -43,7 +47,7 @@ else
|
||||
PROJECT="qemu-virt-a15-test"
|
||||
fi
|
||||
|
||||
ARGS=" -m 512 -kernel build-${PROJECT}/lk.elf"
|
||||
ARGS=" -m $MEMSIZE -kernel build-${PROJECT}/lk.elf"
|
||||
BLOCK_ARGS=" -drive if=none,file=blk.bin,id=blk,format=raw -device virtio-blk-device,drive=blk"
|
||||
NET_ARGS=" -netdev user,id=vmnic,hostname=qemu -device virtio-net-device,netdev=vmnic"
|
||||
NET_TAP_ARGS=" -netdev tap,id=vmnic -device virtio-net-device,netdev=vmnic"
|
||||
|
||||
Reference in New Issue
Block a user