enjoy-digital / litex

Build your hardware, easily!
Other
3.02k stars 573 forks source link

Upload encoded file to Linux filesystem via UART #1492

Open ms3xy opened 2 years ago

ms3xy commented 2 years ago

Hello,

Please help me as I am struggling to upload even a small encoded file to a Linux on Litex on a VC707 FPGA. I am following the instructions from Loading Application Files via UART as well as general other internet wisdom. Several (about 22 characters) get transferred but then about 50 get skipped and then some other random segments get sent. The method is based on streaming a file to the UARD device, and similarly streaming from the UART device to a file on the other end. The final goal is to upload binaries and run them in Linux.

Does anyone have a better alternative? Perhaps it's worth augmenting litex_term with a kernel upload to the Linux filesystem? Thank you!

enjoy-digital commented 2 years ago

Hello @ms3xy,

this could be related to https://github.com/litex-hub/linux-on-litex-vexriscv/issues/187 that still need to be investigated. Until this is done, if you have Ethernet on your board you could eventually to it over SSH.

smosanu commented 2 years ago

Alternatively, one could build the Linux Image and file system with the binary included in it, though I don't know how to do that?!

gsomlo commented 2 years ago

On Sat, Nov 05, 2022 at 05:45:55AM -0700, Sergiu Mosanu wrote:

Alternatively, one could build the Linux Image and file system with the binary included in it, though I don't know how to do that?!

Check out https://github.com/litex-hub/linux-on-litex-rocket (README.md) for step by step instructions on how to build a busybox-based initrd image linked into the kernel as a cpio archive.

You probably want to ignore the part where the kernel image is subsequently embedded into BBL, but everything up to that point should be useful. In addition to the busybox binary, you could copy a (statically linked) binary of whatever else it is you need onto the initrd before embedding it into the kernel.

smosanu commented 1 year ago

The issue has to do with the UART fifo, specifically the case when it is full, because setting --uart-fifo-depth=2048 (an increase from the default of 16) results in successfully transferring moderately large files, though there were still a few errors for a larger file (20MB).

smosanu commented 1 year ago

It seems there is a problem at how the LiteUART interrupts are handled by the SoC/OS. I haven't debugged this to a point to be certain of it, but I suspect that the CPU processes the UART transfer too slow (when running the OS) and the UART FIFO fills up. So the solution is to run the UART port slow and have a large FIFO. Here is what worked, tested with a 20MB file.

Generate the SoC with large UART FIFO and slow baudrate: ./xilinx_alveo_u280.py --build --cpu-type=naxriscv --uart-baudrate=57600 --uart-fifo-depth=32768

Deploy and boot as usual (it will take time). Compile the binary using the RISC-V tools from the LinuX buildroot directory (buildroot/output/host/bin). Encode the binary: uuencode hello < hello > hello.encoded

On the host side, configure the UART port to the correct baudrate
stty -F /dev/ttyUSBx 57600 raw -echo -echoe -echoctl -echok

Connect to the FPGA board with picocom
picocom -b 57600 /dev/ttyUSBx

Start receiving stream redirect from serial port to file on the FPGA board then close picocom with Ctrl+A then Ctrl+X
cat > hello.encoded < /dev/ttyLXU0

Send file from your host machine
cat hello.encoded > /dev/ttyUSB7

When it is done, connect again with either picocom or litex_term, stop the stream with Ctrl+X then decode the received file, make it executable, and run.
uudecode hello.encoded -o hello
chmod +x hello & ./hello

It is also helpful to check the file hash with md5sum hello.encoded on both sender and receiver end and make sure they match.

gsomlo commented 1 year ago

On Mon, Jan 02, 2023 at 01:48:04PM -0800, Sergiu Mosanu wrote:

It seems there is a problem at how the LiteUART interrupts are handled by the SoC/OS.

On that note, does your Linux kernel actually have LiteUART IRQ support? I recently added that here:

https://github.com/litex-hub/linux/commit/20a262f6dd8

and I'd be curious to know if it alleviates the problem you're experiencing while still using default values for the uart fifo depth and baud rate.

NOTE: I'm not using the terminal to transfer data in/out of a linux system myself, but was running into other problems due to the lack of IRQ support in the original linux driver for liteuart, hence the proposed enhancement...

smosanu commented 1 year ago

does your Linux kernel actually have LiteUART IRQ support?

I didn't have that, and I am trying to include that commit, but am not sure how to!? I tried manually overwriting the file during build - that didn't work. 😀 I'll fiddle with buildroot config file and linux config, to somehow make it take your commit in.

sthornington commented 7 months ago

Does anyone have linux images (for Linux on Litex VexRISCV) which include this IRQ patch? I would like to try it on my Acorn SQRL board.