diff --git a/docs/README.md b/docs/README.md index 8a8c8a069f187..002dd7b800fe2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,4 @@ Some notes on NuttX How [clean](leakless-ostest) is NuttX? - +How does [NuttX with rv64ilp32](nuttx-rv64ilp32) feel like? diff --git a/docs/nuttx-rv64ilp32.md b/docs/nuttx-rv64ilp32.md new file mode 100644 index 0000000000000..8a844924f5a68 --- /dev/null +++ b/docs/nuttx-rv64ilp32.md @@ -0,0 +1,68 @@ +# NuttX and RV64ILP32 + +This page shares information about NuttX built with the `rv64ilp32` toolchain. + +## The Problem + +Many AIoT chips using RISC-V on the market are following 64 bit profiles but with small sized memory. They can run 64-bit system software but resource usage isn't optimized, as almost all 64 bit pointers only have their lower 32-bit carry valid information. + +So the industry has attempted to run software using 32-bit pointers to reduce memory footprint while improve cache performance, while at same time enjoy the 64-bit CPU processing power, with the help of a toolchain that supports the `rv64ilp32` ABI, read this [LWN page](https://lwn.net/Articles/951187) for background information. + +Though the requirements for `rv64ilp32` from Linux looks more urgent, but essentially RTOS is of no exception as efficiency is also key for RTOS. + +So can we have `nuttx-rv64ilp32` as well? + +## The toolchain + +After downloading the [RuyiSDK rv64ilp32 toolchain](https://github.com/ruyisdk/riscv-gnu-toolchain-rv64ilp32/releases/tag/2024.05.23), playing the `hello world` on the QEMU in the toolchain and raising questions to experts to learn how it works. + +Here are the major findings: + +- The `rv64ilp32` program is of ELF-32 class, but with flag 0x25; +- The `qemu-riscv64ilp32` in the toolchain can the `rv64ilp32` program by supporting the new program format and ignoring the higher 32-bit addresses generated by the compiler; +- The toolchain uses `-march=rv64`, `-mabi=ilp32` to generate rv64ilp32 binaries; +- The compiler has `__riscv_xlen_t==64` and `sizeof(void*)==32` at the same time; + + +Requirements for the RV64 chips is still to be checked. + +## Building NuttX + +With toolchain knowledge and a few tweaks in the following steps: + +- Add `rv64ilp32` toolchain in `arch/risc-v` Kconfig and Toolchain.cmake to support generation of nuttx-rv64ilp32 binary. +- Add a type for register width data in `arch/risc-v` layer, with some tweaking of the code base to support both existing 64-bit and 32-bit ABIs and the new rv64ilp32 ABI. + +Thanks to NuttX's well designed structure, the generated nuttx image can boot smoothly on the QEMU from the toolchain, though there are still some cleanups left behind. The `ostest` check passed smoothly as well. + +## Comparison + +Here are initial comparisons between normal `rv64lp64` and the `rv64ilp32`, the baseline configuration is `rv-virt/nsh64`. + +Static footprints: + +``` +$ cd /tmp && size nuttx-* + text data bss dec hex filename + 176861 397 10256 187514 2dc7a nuttx-ilp32 + 173171 681 12416 186268 2d79c nuttx-lp64 +``` + +Dynamic footprints: + +``` +nsh> cat /proc/version +NuttX version 12.4.0 77abbe5a43-dirty Jun 6 2024 16:22:56 rv-virt/nsh64ilp32 +nsh> free + total used free maxused maxfree nused nfree + Umem: 33364764 8068 33356696 8052 33356664 21 2 + +nsh> cat /proc/version +NuttX version 12.4.0 5ce64a46a5-dirty Jun 6 2024 16:23:33 rv-virt/nsh64 +nsh> free + total used free maxused maxfree nused nfree + Umem: 33366008 10344 33355664 10312 33355616 21 2 +``` + +We can see that the code size if `rv64ilp32` is about 2.13% bigger, and data memory reduced 18% or 22% for static or heap memory. +