|
@@ -151,12 +151,19 @@ target_ulong riscv_load_kernel(const char *kernel_filename,
|
|
|
target_ulong kernel_start_addr,
|
|
|
symbol_fn_t sym_cb)
|
|
|
{
|
|
|
- uint64_t kernel_entry;
|
|
|
+ uint64_t kernel_load_base, kernel_entry;
|
|
|
|
|
|
+ /*
|
|
|
+ * NB: Use low address not ELF entry point to ensure that the fw_dynamic
|
|
|
+ * behaviour when loading an ELF matches the fw_payload, fw_jump and BBL
|
|
|
+ * behaviour, as well as fw_dynamic with a raw binary, all of which jump to
|
|
|
+ * the (expected) load address load address. This allows kernels to have
|
|
|
+ * separate SBI and ELF entry points (used by FreeBSD, for example).
|
|
|
+ */
|
|
|
if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
|
|
|
- &kernel_entry, NULL, NULL, NULL, 0,
|
|
|
+ NULL, &kernel_load_base, NULL, NULL, 0,
|
|
|
EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
|
|
|
- return kernel_entry;
|
|
|
+ return kernel_load_base;
|
|
|
}
|
|
|
|
|
|
if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
|