TinyLinux 是泰晓科技 Linux 技术社区创始人发起的项目,已经有 10 多年的历史,该项目致力于 Linux 内核裁剪,以便应用到存储和内存极端有限的硬件平台,该提案的目标是把 TinyLinux 移植到最新的 RISC-V Linux 内核,研究应用新型的 Linux 裁剪技术,并在极小存储和内存的目标系统上运行(可以直接用 QEMU 模拟)。
该项目曾经把 MIPS 内核优化到 386k 左右:
Now, we get:
$ ls -lh vmlinuz
-rwxr-xr-x 1 root root 386K 2011-01-30 03:27 vmlinuz
除了早期 TinyLinux 的工作,还有一些新兴的技术可以应用:
Nolibc
一个以头文件方式提供的,已经内置到内核源码的 C 库,本身很小,也很方便分析调用到的内核资源(特别是系统调用)。
M-Mode Linux
内核中的 nonMMU 配置选项,如何开启后支持运行 Nolibc 库,完全避免系统调用运行?见 RISC-V NoMMU Linux 相关支持调研与分析
Unikernel
更进一步地,把应用直接编译进内核,
Kexec bootloader
基于上述功能开发具体的应用案例,验证可行性:
有些工作虽然不一定能 Upstream,但是绝对可以值得尝试,比如:
未来可能用到的硬件平台,rv32,小内存,小ROM:
更多资料:
已经开展的工作:
目前成果:
By enabling CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION and setting
CONFIG_SYSCALLS_USED, It is able to remove the left 'dead' syscalls.
For example, if setting CONFIG_SYSCALLS_USED="write exit reboot", a
'used' variant of the *syscall_table.c will be generated.
Here is a test result on qemu with a small rv64 config.
| rv64 | config
----------------|-----------------|-------------------
vmlinux | 4893488 | https://pastebin.com/crz82T0s
+ gc-sections | 4376400 (-10.5%)| CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
+ syscalls_used | 4172112 (-4.67%)| CONFIG_SYSCALLS_USED="pselect6"
+ syscalls_used | 4172848 (-4.65%)| CONFIG_SYSCALLS_USED="write exit reboot"
A even smaller config is tested:
| rv64 | config
----------------|-----------------|-------------------
vmlinux | 1698960 | https://pastebin.com/C3LR4UbT
+ gc-sections | 1319400 (-22.3%)| CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
+ syscalls_used | 1233392 (-6.52%)| CONFIG_SYSCALLS_USED="write exit reboot"
notes:
- The shrink ratios of the syscalls_used lines are based on the
gc-sections line.
- "write exit reboot" are used by a hello.c to simply print "Hello,
World!", exit and shutdown qemu.
- "pselect6" is used by rcutorture to do a long-time sleep.
做完 strip 后的 Image 已经可以小于 1M,还是很大:
ubuntu@linux-lab:/labs/linux-lab$ ls -l build/riscv64/virt/linux/v6.2-rc8/vmlinux
-rwxr-xr-x 1 ubuntu ubuntu 1319400 2月 19 11:00 build/riscv64/virt/linux/v6.2-rc8/vmlinux
ubuntu@linux-lab:/labs/linux-lab$ ls -l build/riscv64/virt/linux/v6.2-rc8/arch/riscv/boot/Image
-rwxr-xr-x 1 ubuntu ubuntu 947792 2月 19 11:09 build/riscv64/virt/linux/v6.2-rc8/arch/riscv/boot/Image
ubuntu@linux-lab:/labs/linux-lab$ ls -lh build/riscv64/virt/linux/v6.2-rc8/arch/riscv/boot/Image
-rwxr-xr-x 1 ubuntu ubuntu 926K 2月 19 11:09 build/riscv64/virt/linux/v6.2-rc8/arch/riscv/boot/Image
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
最近几天的一些进展:
$ pwd
/labs/linux-lab/build/riscv64/virt/linux/v6.2-rc8/arch/riscv/boot
$ ls -lh Image*
-rwxr-xr-x 1 ubuntu ubuntu 762K 2月 22 00:31 Image
-rw-r--r-- 1 ubuntu ubuntu 396K 2月 22 00:59 Image.bz2
-rw-r--r-- 1 ubuntu ubuntu 419K 2月 22 00:59 Image.gz
-rw-r--r-- 1 ubuntu ubuntu 455K 2月 22 01:01 Image.lz4
-rw-r--r-- 1 ubuntu ubuntu 368K 2月 22 00:57 Image.lzma
-rw-r--r-- 1 ubuntu ubuntu 449K 2月 22 00:58 Image.lzo
-rw-r--r-- 1 ubuntu ubuntu 392K 2月 22 00:57 Image.zst
新增自解压支持,采用 lzma 压缩后:
$ ls -lh build/riscv64/virt/linux/v6.2-rc8/arch/riscv/boot/compressed/vmlinuz
-rwxr-xr-x 1 ubuntu ubuntu 371K 2月 22 22:33 build/riscv64/virt/linux/v6.2-rc8/arch/riscv/boot/compressed/vmlinuz
新增 M mode kernel 支持:
$ ls -lh build/riscv64/virt/linux/v6.2/arch/riscv/boot/compressed/vmlinuz
-rwxr-xr-x 1 ubuntu ubuntu 337K 2月 23 07:00 build/riscv64/virt/linux/v6.2/arch/riscv/boot/compressed/vmlinuz
新增 M Mode Application 支持:
$ ls -l /labs/linux-lab/build/riscv64/virt/linux/v6.2/nolibc/initramfs/init
-rwxr--r-- 1 ubuntu ubuntu 864 3月 2 22:09 /labs/linux-lab/build/riscv64/virt/linux/v6.2/nolibc/initramfs/init
$ ls -lh build/riscv64/virt/linux/v6.2/arch/riscv/boot/compressed/vmlinuz
-rwxr-xr-x 1 ubuntu ubuntu 334K 3月 2 22:11 build/riscv64/virt/linux/v6.2/arch/riscv/boot/compressed/vmlinuz
在 Linux Lab 下编译和运行 !MMU
应用,开启内核支持的方法在 这里。
$ export NOLIBC=1
$ export NOMMU=1
$ make kernel vmlinuz nolibc_src=$PWD/src/examples/assembly/riscv64/riscv64-hello.s
$ make boot
Linux version 6.2.0-00047-gf9a88b15cf5a (ubuntu@linux-lab) (riscv64-linux-gnu-gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #353 Thu Mar 2 22:20:24 CST 2023
...
Freeing unused kernel image (initmem) memory: 72K
This architecture does not have kernel memory protection.
Run /init as init process
Hello, RISC-V 64!
reboot: Power down
社区正在尝试新增 Non-MMU ELF-FDPIC 格式支持,目前只是内核部分:
rv32 nolibc 支持,已提交一组 patchset: https://lore.kernel.org/linux-riscv/cover.1684425792.git.falcon@tinylab.org/T/#t
make B=riscv32/virt; export nolibc=1; make kernel; make boot
$ make nolibc nolibc_src=src/linux-stable/tools/testing/selftests/nolibc/nolibc-test.c
$ make kernel
$ make boot
$ make run-user ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -C src/linux-stable/tools/testing/selftests/nolibc O=/labs/linux-lab/build/riscv64/virt/linux/v6.4-rc2
$ make qemu-clone QEMU_NEW=v8.0.0
$ make qemu
$ make qemu-save
$ env PATH=$PWD/boards/riscv64/virt/bsp/qemu/v8.0.0/bin/:/usr/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin BIOS=$PWD/boards/riscv64/virt/bsp/bios/opensbi/generic/fw_jump.elf make O=/labs/linux-lab/build/riscv64/virt/linux/v6.4-rc2 -C /labs/linux-lab/src/linux-stable/tools/testing/selftests/nolibc/ ARCH=riscv LOADADDR=0x84000000 CROSS_COMPILE=riscv64-linux-gnu- run IMAGE=../../build/riscv64/virt/linux/v6.4-rc2/arch/riscv/boot/Image
TODO:
!vdso support for risc-v: riscv: Allow disable vdso support
pure kernel deployment 后续阶段:基于 nolibc 的 shell 或者 busybox 支持。
https://github.com/ziyao233/kdsh
http://mirbsd.de/mksh
https://www.busybox.net/
https://github.com/ksh93/ksh
DCE/DSE support for mips and riscv, part1: https://lore.kernel.org/lkml/cover.1695679700.git.falcon@tinylab.org/
登录 后才可以发表评论