Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reading binary files. #650

Open
kodyvajjha opened this issue Jul 28, 2024 · 3 comments
Open

Reading binary files. #650

kodyvajjha opened this issue Jul 28, 2024 · 3 comments

Comments

@kodyvajjha
Copy link

Is there a sail module to parse and read instructions from a compiled binary file? If so, are there examples of usage which I can follow from somewhere?

@Timmmm
Copy link
Contributor

Timmmm commented Aug 7, 2024

Not really, that's something you'd normally do outside Sail (i.e. in C). If you give more details about what you're trying to do exactly I could point you in the right direction.

@kodyvajjha
Copy link
Author

Thanks for the reply! I'm trying to specify the 6502 ISA in Sail. I have a few instructions specified and have implemented a basic instruction decoder and a top-level fetch and execute loop function. I wanted to test it out on actual assembled binaries.

I noticed that the REPL has a :bin command which allows you to load a binary at a memory location. I thought that I could use that command to populate memory with an assembled ROM file and start fetching instructions from the loaded memory, but perhaps I'm missing something.

@Timmmm
Copy link
Contributor

Timmmm commented Aug 7, 2024

Yeah you're right - the way this is done in RISC-V is that you load the binary into memory, set the PC to your entry point and then call your step() function in a loop. I haven't really used the REPL much tbh, just the compiled C output.

Basically you would do this:

  1. Make a step function like:
register pc : bits(32)

function step() -> unit = {
   let instruction = mem_read(pc);
   ...
}

To implement mem_read there is built in memory support - see this. Tbh I'm not too sure about lots of that. E.g. instantiate seems new and undocumented. :-D A lot of it is related to the "concurrency model" which you don't need to care about if you are just doing a basic emulator.

  1. Compile to C and use --c-preserve=step so it doesn't dead-code eliminate the step function. In the generated C code it will be called zstep because the name mangling system basically prepends a z and doubles existing z's (i.e. doze -> zdozze).

  2. Load the binary into memory from C, either by calling load_elf() (I dunno if your binary is an ELF file), or you can do it manually with write_mem().

Btw when you compile your C program you have to compile the C files in that directory - at least rts.c and sail.c.

Probably would be good if there was a minimal example for this, but... there isn't, sorry!

I guess if the REPL lets you load a binary you could skip most of that. You just need to make sure your step() function loads the instruction from memory using the built-in memory functions (sail_mem_write() and sail_mem_read()).

Good luck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants