Hi there! At 2020-12-11T21:29:05-0000, porter.188@osu.edu wrote:
I'm trying to build a low memory footprint of RISC-V based seL4. I'm using QEMU/spike for now.
In seL4 12.0 I can modify spike.dts to 8.5 MB of memory 0x00880000.
42 memory@80000000 { 43 device_type = "memory"; 44 reg = <0x00000000 0x80000000 0x00000000 0x00880000>; 45 };
This is the smallest value that builds, lower than this I get the error: [...] What do I need to modify to get to < 2 MB? [...] shoehorn: fatal error: ELF-loader image "/mnt/data/femur_12.0/build/elfloader-tool/archive.o" of size 0x107548 does not fit within any memory region described in "{'devices': [{'end': 2147483648, 'start': 0}, {'end': 549755809792, 'start': 2155872256}], 'memory': [{'end': 2155872256, 'start': 2149580800}]}" ninja: build stopped: subcommand failed.
With a bit of hex-to-decimal arithmetic and sorting, maybe the complaint will become more obvious. The archive is 1078600 bytes in decimal, a little over 1 megabyte. Your memory map looks like this: 000000000000 - 002147483648: (2GB) device memory 002149580800 - 002155872256: physical memory 002155872256 - 549755809792: device memory The device memory is not backed by real storage, or at least cannot be used that way by the boot loader, ELF-loader, or operating system. Your physical memory window lies between 2149580800 and 2155872256. The difference is 6291456. More readably, 6 291 456. So, a bit over 6 megabytes. What are the demands on physical memory at the time the ELF-loader is running? There is the ELF-loader itself, and the payload it is trying to unpack. That payload typically consists of the seL4 kernel itself, a device tree blob/binary (DTB) that the kernel will parse as part of its initialization, and the root server, analogous to the Unix init process. Moreover, the contents of the archive will, once it is unpacked, briefly be in memory twice: first in the archive itself, and as its unpacked contents with the kernel, device tree, and root server mapped to their "final" locations. These objects have to be page aligned, which is not usually a big deal, but they also have to fit within the existing state of memory usage at the time the ELF-loader runs, and the ELF-loader was loaded into memory by the boot loader. The ELF-loader strives to be simple and the shoehorn tool, pessimistic; that is, it assumes a worst-case unpacking scenario with maximal duplication. You might be able to get some space wins by studying the former, carefully planning memory usage, adjusting the boot loader to put the ELF-loader in a convenient place (perhaps arranging so that parts of it get overwritten by the unpacking payload after the last point at which an ELF-loader page will be used). I think there is probably not an easy answer to your question, no knob you can fiddle to get things packed in tighter. Remember that the size of the kernel plus DTB plus rootserver is an absolute lower bound on the amount of physical memory you have to configure. In practice the limit will be higher; any loader program will take up non-zero space, and any loader program that is clever enough to unpack the CPIO file archive.o in chunks so that it can unmap pages of it as it goes will be more complex and therefore larger. Optimization is an iterative process that requires study of the running system's actual needs and aggressive culling of anything that isn't used. To truly get a minimal memory footprint at boot, you might need to write your own bootloader, and engineer your own solution for unpacking the kernel+DTB+rootserver in a way that has minimal overhead. Let me know if this helps, or doesn't. Regards, Branden