Skip to content

Commit

Permalink
Ramdisk (#4)
Browse files Browse the repository at this point in the history
* Some works towards ramdisk

* PMEM ramdisk working

* DTS cleanup

* Added some docs on ramdisk

* Change back to original memory size, added comment

* Cleanup

---------

Co-authored-by: Egil <egil.moller@freecode.no>
  • Loading branch information
redhog and Egil committed Feb 21, 2024
1 parent 807af14 commit b921774
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 8 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,18 @@ Please see https://github.com/franzflasch/linux_for_riscv_em
```sh
./build/riscv_em -f <linux_for_riscv_em-path>/output_mmu_rv32/opensbi/build/platform/generic/firmware/fw_payload.bin -d dts/riscv_em32_linux.dtb
```

### RAM disk

Make a filesystem image using the normal filesystem tools (e.g.
mkfs.ext3, mksquashfs etc) with a maximum size of 200Mb. Then run

```sh
./build/riscv_em -f <linux_for_riscv_em-path>/output/linux/loader_64.bin -d dts/riscv_em.dtb -i mydiskimage.ext3
```

The filesystem will be available as `/dev/pmem0`, which can be either
mounted from userspace, or specified as the root filesystem. Note that
this does not use the initrd or initramdisk functionality, as that has
severe size limitations (tries to unpack/copy the whole filesystem at
boot).
15 changes: 13 additions & 2 deletions dts/riscv_em.dts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,21 @@
};
};

/* Make sure these adresses and sizes match the actual
configuration in src/core/riscv_config.h */
sram: memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0x8000000>;
reg = <0x0 0x80000000 0x0 0x8000000>;
/* Example alternative configuration with much more RAM
reg = <0x0 0x80000000 0x0 0x40000000>;
*/
};


rom: memory@c0000000 {
compatible = "pmem-region";
reg = <0x0 0xc0000000 0x0 0xc800000>;
};

soc {
#address-cells = <2>;
#size-cells = <2>;
Expand Down Expand Up @@ -74,4 +84,5 @@
compatible = "simple-uart";
};
};

};
6 changes: 6 additions & 0 deletions src/core/riscv_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

#define RAM_BASE_ADDR 0x80000000UL
#define RAM_SIZE_BYTES 0x8000000UL /* 128MB such as the default for the qemu virt machine */
/* Example alternative configuration with much more RAM
#define RAM_SIZE_BYTES 0x40000000UL
*/

#define CLINT_BASE_ADDR 0x2000000UL
#define CLINT_SIZE_BYTES 0x10000UL
Expand All @@ -30,4 +33,7 @@
RV_EXTENSION_TO_MISA('S') | \
RV_EXTENSION_TO_MISA('U') )

#define FROM_BASE_ADDR 0xc0000000UL
#define FROM_SIZE_BYTES 0xc800000UL

#endif /* RISCV_CONFIG_H */
22 changes: 18 additions & 4 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,19 @@ void start_uart_rx_thread(void *p)
static void parse_options(int argc,
char** argv,
char **fw_file,
char **dtb_file,
char **dtb_file,
char **initrd_file,
rv_uint_xlen *success_pc,
uint64_t *num_cycles)
{
int c;
char *arg_fw_file = NULL;
char *arg_dtb_file = NULL;
char *arg_initrd_file = NULL;
char *arg_success_pc = NULL;
char *arg_num_cycles = NULL;

while ((c = getopt(argc, argv, "s:f:d:n:")) != -1)
while ((c = getopt(argc, argv, "s:f:d:i:n:")) != -1)
{
switch (c)
{
Expand Down Expand Up @@ -113,6 +115,11 @@ static void parse_options(int argc,
// }
break;
}
case 'i':
{
arg_initrd_file = optarg;
break;
}
case 'n':
{
arg_num_cycles = optarg;
Expand Down Expand Up @@ -144,26 +151,33 @@ static void parse_options(int argc,
printf("No dtb specified! Linux will probably not work\n");
}

if(arg_initrd_file == NULL)
{
printf("No initrd specified!\n");
}

printf("FW file: %s\n", arg_fw_file);
printf("Success PC: " PRINTF_FMT "\n", *success_pc);
printf("Num Cycles: %ld\n", *num_cycles);

*fw_file = arg_fw_file;
*dtb_file = arg_dtb_file;
*initrd_file = arg_initrd_file;
}


int main(int argc, char *argv[])
{
char *fw_file = NULL;
char *dtb_file = NULL;
char *initrd_file = NULL;
rv_uint_xlen success_pc = 0;
uint64_t num_cycles = 0;

parse_options(argc, argv, &fw_file, &dtb_file, &success_pc, &num_cycles);
parse_options(argc, argv, &fw_file, &dtb_file, &initrd_file, &success_pc, &num_cycles);

rv_soc_td rv_soc;
rv_soc_init(&rv_soc, fw_file, dtb_file);
rv_soc_init(&rv_soc, fw_file, dtb_file, initrd_file);

#ifndef RISCV_EM_DEBUG
start_uart_rx_thread(&rv_soc);
Expand Down
9 changes: 8 additions & 1 deletion src/soc/riscv_example_soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static void rv_soc_init_mem_access_cbs(rv_soc_td *rv_soc)
INIT_MEM_ACCESS_STRUCT(rv_soc, count++, uart_bus_access, &rv_soc->uart8250, UART8250_TX_REG_ADDR, UART_NS8250_NR_REGS);
#endif
INIT_MEM_ACCESS_STRUCT(rv_soc, count++, memory_bus_access, rv_soc->mrom, MROM_BASE_ADDR, MROM_SIZE_BYTES);
INIT_MEM_ACCESS_STRUCT(rv_soc, count++, memory_bus_access, rv_soc->from, FROM_BASE_ADDR, FROM_SIZE_BYTES);
}

static rv_ret rv_soc_bus_access(void *priv, privilege_level priv_level, bus_access_type access_type, rv_uint_xlen address, void *value, uint8_t len)
Expand Down Expand Up @@ -74,7 +75,7 @@ void rv_soc_dump_mem(rv_soc_td *rv_soc)
}
}

void rv_soc_init(rv_soc_td *rv_soc, char *fw_file_name, char *dtb_file_name)
void rv_soc_init(rv_soc_td *rv_soc, char *fw_file_name, char *dtb_file_name, char *initrd_file_name)
{
#define RESET_VEC_SIZE 10
#define MiB 0x100000
Expand All @@ -86,11 +87,13 @@ void rv_soc_init(rv_soc_td *rv_soc, char *fw_file_name, char *dtb_file_name)
uint64_t fdt_size = 0;
uint64_t tmp = 0;

static uint8_t __attribute__((aligned (4))) soc_from[FROM_SIZE_BYTES] = { 0 };
static uint8_t __attribute__((aligned (4))) soc_mrom[MROM_SIZE_BYTES] = { 0 };
static uint8_t __attribute__((aligned (4))) soc_ram[RAM_SIZE_BYTES] = { 0 };

/* Init everything to zero */
memset(rv_soc, 0, sizeof(rv_soc_td));
rv_soc->from = soc_from;
rv_soc->mrom = soc_mrom;
rv_soc->ram = soc_ram;

Expand All @@ -113,6 +116,10 @@ void rv_soc_init(rv_soc_td *rv_soc, char *fw_file_name, char *dtb_file_name)

write_mem_from_file(fw_file_name, soc_ram, sizeof(soc_ram));

if (initrd_file_name != NULL) {
write_mem_from_file(initrd_file_name, soc_from, FROM_SIZE_BYTES);
}

/* this is the reset vector, taken from qemu v5.2 */
uint32_t reset_vec[RESET_VEC_SIZE] = {
0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */
Expand Down
3 changes: 2 additions & 1 deletion src/soc/riscv_example_soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ typedef struct rv_soc_struct
rv_core_td rv_core0;
uint8_t *mrom; /* Contains reset vector and device-tree? */
uint8_t *ram;
uint8_t *from; /* Contains filesystem */

clint_td clint;
plic_td plic;
Expand All @@ -38,7 +39,7 @@ typedef struct rv_soc_struct
} rv_soc_td;

void rv_soc_dump_mem(rv_soc_td *rv_soc);
void rv_soc_init(rv_soc_td *rv_soc, char *fw_file_name, char *dtb_file_name);
void rv_soc_init(rv_soc_td *rv_soc, char *fw_file_name, char *dtb_file_name, char *initrd_file_name);
void rv_soc_run(rv_soc_td *rv_soc, rv_uint_xlen success_pc, uint64_t num_cycles);

#endif /* RISCV_EXAMPLE_SOC_H */

0 comments on commit b921774

Please sign in to comment.