From 813ab1718417e09465edc2ed2e4910ce4a58f07a Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 14 Feb 2020 11:31:38 +0530 Subject: [PATCH] Make spike capable of booting Linux Latest Linux does not boot Spike mainly because: 1. Spike does not set bootargs in DTS 2. Spike does not provide mechanism to load initrd for Linux This patch addresses both above issues and we can now get latest Linux to prompt on Spike. Signed-off-by: Anup Patel --- riscv/dts.cc | 10 ++++++++++ riscv/dts.h | 1 + riscv/sim.cc | 6 +++--- riscv/sim.h | 4 +++- spike_main/spike.cc | 40 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 56 insertions(+), 5 deletions(-) diff --git a/riscv/dts.cc b/riscv/dts.cc index f7302934..246773e0 100644 --- a/riscv/dts.cc +++ b/riscv/dts.cc @@ -9,6 +9,7 @@ #include std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, + reg_t initrd_start, reg_t initrd_end, std::vector procs, std::vector> mems) { @@ -21,6 +22,15 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, " #size-cells = <2>;\n" " compatible = \"ucbbar,spike-bare-dev\";\n" " model = \"ucbbar,spike-bare\";\n" + " chosen {\n"; + if (initrd_start < initrd_end) { + s << " bootargs = \"root=/dev/ram console=hvc0 earlycon=sbi\";\n" + " linux,initrd-start = <" << (size_t)initrd_start << ">;\n" + " linux,initrd-end = <" << (size_t)initrd_end << ">;\n"; + } else { + s << " bootargs = \"console=hvc0 earlycon=sbi\";\n"; + } + s << " };\n" " cpus {\n" " #address-cells = <1>;\n" " #size-cells = <0>;\n" diff --git a/riscv/dts.h b/riscv/dts.h index ec0aa616..b9ddb8e4 100644 --- a/riscv/dts.h +++ b/riscv/dts.h @@ -7,6 +7,7 @@ #include std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, + reg_t initrd_start, reg_t initrd_end, std::vector procs, std::vector> mems); diff --git a/riscv/sim.cc b/riscv/sim.cc index 7d6f3c18..3d7cd880 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -26,14 +26,14 @@ static void handle_signal(int sig) } sim_t::sim_t(const char* isa, const char* priv, const char* varch, - size_t nprocs, bool halted, + size_t nprocs, bool halted, reg_t initrd_start, reg_t initrd_end, reg_t start_pc, std::vector> mems, std::vector> plugin_devices, const std::vector& args, std::vector const hartids, const debug_module_config_t &dm_config) : htif_t(args), mems(mems), plugin_devices(plugin_devices), - procs(std::max(nprocs, size_t(1))), start_pc(start_pc), current_step(0), + procs(std::max(nprocs, size_t(1))), initrd_start(initrd_start), initrd_end(initrd_end), start_pc(start_pc), current_step(0), current_proc(0), debug(false), histogram_enabled(false), log_commits_enabled(false), dtb_enabled(true), remote_bitbang(NULL), debug_module(this, dm_config) @@ -201,7 +201,7 @@ void sim_t::make_dtb() std::vector rom((char*)reset_vec, (char*)reset_vec + sizeof(reset_vec)); - dts = make_dts(INSNS_PER_RTC_TICK, CPU_HZ, procs, mems); + dts = make_dts(INSNS_PER_RTC_TICK, CPU_HZ, initrd_start, initrd_end, procs, mems); std::string dtb = dts_compile(dts); rom.insert(rom.end(), dtb.begin(), dtb.end()); diff --git a/riscv/sim.h b/riscv/sim.h index 3b7e25c0..44f2f92a 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -22,7 +22,7 @@ class sim_t : public htif_t, public simif_t { public: sim_t(const char* isa, const char* priv, const char* varch, size_t _nprocs, - bool halted, + bool halted, reg_t initrd_start, reg_t initrd_end, reg_t start_pc, std::vector> mems, std::vector> plugin_devices, const std::vector& args, const std::vector hartids, @@ -54,6 +54,8 @@ private: std::vector> plugin_devices; mmu_t* debug_mmu; // debug port into main memory std::vector procs; + reg_t initrd_start; + reg_t initrd_end; reg_t start_pc; std::string dts; std::unique_ptr boot_rom; diff --git a/spike_main/spike.cc b/spike_main/spike.cc index 4656a0a9..f14ef87c 100644 --- a/spike_main/spike.cc +++ b/spike_main/spike.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include "../VERSION" static void help(int exit_code = 1) @@ -49,6 +50,7 @@ static void help(int exit_code = 1) fprintf(stderr, " --rbb-port= Listen on for remote bitbang connection\n"); fprintf(stderr, " --dump-dts Print device tree string and exit\n"); fprintf(stderr, " --disable-dtb Don't write the device tree blob into memory\n"); + fprintf(stderr, " --initrd= Load kernel initrd into memory\n"); fprintf(stderr, " --dm-progsize= Progsize for the debug module [default 2]\n"); fprintf(stderr, " --dm-sba= Debug bus master supports up to " " wide accesses [default 0]\n"); @@ -70,6 +72,26 @@ static void suggest_help() exit(1); } +static bool check_file_exists(const char *fileName) +{ + std::ifstream infile(fileName); + return infile.good(); +} + +static std::ifstream::pos_type get_file_size(const char *filename) +{ + std::ifstream in(filename, std::ios::ate | std::ios::binary); + return in.tellg(); +} + +static void read_file_bytes(const char *filename,size_t fileoff, + char *read_buf, size_t read_sz) +{ + std::ifstream in(filename, std::ios::in | std::ios::binary); + in.seekg(fileoff, std::ios::beg); + in.read(read_buf, read_sz); +} + static std::vector> make_mems(const char* arg) { // handle legacy mem argument @@ -110,6 +132,8 @@ int main(int argc, char** argv) bool dump_dts = false; bool dtb_enabled = true; size_t nprocs = 1; + size_t initrd_size; + reg_t initrd_start = 0, initrd_end = 0; reg_t start_pc = reg_t(-1); std::vector> mems; std::vector> plugin_devices; @@ -119,6 +143,7 @@ int main(int argc, char** argv) bool log_cache = false; bool log_commits = false; std::function extension; + const char* initrd = NULL; const char* isa = DEFAULT_ISA; const char* priv = DEFAULT_PRIV; const char* varch = DEFAULT_VARCH; @@ -215,6 +240,7 @@ int main(int argc, char** argv) parser.option(0, "extension", 1, [&](const char* s){extension = find_extension(s);}); parser.option(0, "dump-dts", 0, [&](const char *s){dump_dts = true;}); parser.option(0, "disable-dtb", 0, [&](const char *s){dtb_enabled = false;}); + parser.option(0, "initrd", 1, [&](const char* s){initrd = s;}); parser.option(0, "extlib", 1, [&](const char *s){ void *lib = dlopen(s, RTLD_NOW | RTLD_GLOBAL); if (lib == NULL) { @@ -248,7 +274,19 @@ int main(int argc, char** argv) if (!*argv1) help(); - sim_t s(isa, priv, varch, nprocs, halted, start_pc, mems, plugin_devices, htif_args, + if (initrd && check_file_exists(initrd)) { + initrd_size = get_file_size(initrd); + for (auto& m : mems) { + if (initrd_size && (initrd_size + 0x1000) < m.second->size()) { + initrd_end = m.first + m.second->size() - 0x1000; + initrd_start = initrd_end - initrd_size; + read_file_bytes(initrd, 0, m.second->contents() + (initrd_start - m.first), initrd_size); + break; + } + } + } + + sim_t s(isa, priv, varch, nprocs, halted, initrd_start, initrd_end, start_pc, mems, plugin_devices, htif_args, std::move(hartids), dm_config); std::unique_ptr remote_bitbang((remote_bitbang_t *) NULL); std::unique_ptr jtag_dtm(