From 51cedf1964a934659cebf7818e989e1539d6962f Mon Sep 17 00:00:00 2001 From: asterich Date: Fri, 29 Sep 2023 17:45:47 +0800 Subject: [PATCH 1/4] add article: 20230919-elf2flt-elf2flt-build-1 --- articles/20230919-elf2flt-elf2flt-build-1.md | 151 +++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 articles/20230919-elf2flt-elf2flt-build-1.md diff --git a/articles/20230919-elf2flt-elf2flt-build-1.md b/articles/20230919-elf2flt-elf2flt-build-1.md new file mode 100644 index 0000000..982fe6f --- /dev/null +++ b/articles/20230919-elf2flt-elf2flt-build-1.md @@ -0,0 +1,151 @@ + + +# elf2flt 篇三 使用 + +[TOC] + +## 前言 + +在本机安装完 elf2flt 后,我们就可以使用它构建 bFLT 程序,并放到 no-mmu 的 linux 系统中运行。 + +我们首先需要一个 no-mmu riscv 的系统,这里我们使用 buildroot 构建的 qemu 镜像来进行测试。 + +## 准备 + +准备工作主要是 buildroot 的构建。首先我们进入 cloud-lab 里面的 riscv64 实验环境。 + +```bash +$ tools/docker/run riscv-lab +``` + +等待片刻,我们就可以进入到 riscv64 的实验环境了。理论上本机并不需要 riscv64 的环境,有交叉编译工具链即可,真正需要 riscv64 的是无 MMU 的目标环境。 + +而后,我们在 riscv-lab 里面安装 buildroot 。首先我们把 buildroot 仓库克隆下来,进入到 buildroot 目录: +```sh +$ cd /home/ubuntu +$ git clone git://git.buildroot.net/buildroot +$ cd buildroot +``` + +进入后,我们可能需要先安装 CMake。如果本机是 riscv64 环境且没有安装 CMake(例如我们的 riscv-lab 环境),buildroot 会自己构建一份,此时会出现与 libatomic 库有关的错误。 +```sh +$ sudo apt-get update +$ sudo apt-get install cmake # riscv-lab needed +``` + +然后我们开始配置 buildroot。由于我们是在 QEMU 上运行的 riscv64 no-mmu系统,因此采用`qemu_riscv64_nommu_virt_defconfig`配置: +```sh +$ make qemu_riscv64_nommu_virt_defconfig +``` + +最后开始构建: +```sh +$ make +``` + +构建完成后,生成的镜像在`/home/ubuntu/buildroot/output/images`下面。我们看一下这个目录下有什么: +```sh +$ cd /home/ubuntu/buildroot/output/images +$ ls +Image rootfs.ext2 rootfs.tar start-qemu.sh +``` + +这里的`Image`是系统镜像,`rootfs.ext2`是磁盘镜像,`start-qemu.sh`是系统镜像在 QEMU 上运行的启动脚本。由于下文需要将我们自己的 bFLT 文件拷贝到磁盘镜像下,我们先将其挂载: +```sh +$ sudo mkdir /mnt/buildroot-nommu +$ sudo mount rootfs.ext2 /mnt/buildroot-nommu +``` + +然后我们启动镜像: +```sh +$ ./start-qemu.sh + +[ 0.000000] Linux version 6.1.44 (ubuntu@riscv-lab) (riscv64-buildroot-linux-uclibc-gcc.br_real (Buildroot -gbdab4577-dirty) 12.3.0, GNU ld (GNU Binutils) 2.40) #1 SMP Tue Sep 26 00:35:20 CST 2023 +[ 0.000000] random: crng init done +[ 0.000000] Machine model: riscv-virtio,qemu +[ 0.000000] Forcing kernel command line to: root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0 +... +[ 2.438788] Run /sbin/init as init process +Seeding 256 bits and crediting +Saving 256 bits of creditable seed for next boot + +Welcome to Buildroot +buildroot login: root +Jan 1 00:00:10 login[34]: root login on 'console' +~ # +``` + +至此,buildroot 的准备工作已经完成。 + +## 使用 + +elf2flt 的使用实际上非常简单,只要安装完成,它就已经整合到我们的交叉编译工具链里面。 + +bFLT 程序的构建过程是将源程序编译成 ELF,再将其与同为 ELF 格式的运行时库(例如 uClibc)进行静态链接,因此,理论上只要是 libc,无论其是 glibc、uClibc 还是 musl libc ,都可以通过此种方式链接到 bFLT 程序里。这里以 uClibc 为例,讲解如何用整合进 elf2flt 的工具链编译一个可以运行的 bFLT 文件。 + +首先,我们以一个简单的程序作为例子(`hello.c`): +```c +#include +int main() { + int num = 0; + printf("enter your number here:\n"); + scanf("%d", &num); + printf("hello world from number %d!\n", num); + return 0; +} +``` + +接下来我们编译源程序。理论上在 buildroot 外部编译的 uClibc 也能使用,但是为省却麻烦,我们直接使用 buildroot 编译好的 uClibc 库进行编译: +```sh +$ gcc -o hello-b-gcc hello.c -nostdinc -nostdlib \ +-I/usr/bin/../lib/gcc/riscv64-linux-gnu/11/include \ +-I/usr/bin/../lib/gcc/riscv64-linux-gnu/11/include-fixed \ +-I/home/ubuntu/buildroot/output/host/riscv64-buildroot-linux-uclibc/sysroot/usr/include \ +/home/ubuntu/buildroot/output/build/uclibc-1.0.44/lib/crt1.o \ +/usr/lib/gcc/riscv64-linux-gnu/11/crti.o \ +/usr/lib/gcc/riscv64-linux-gnu/11/crtbeginT.o \ +-L/usr/lib/gcc/riscv64-linux-gnu/11 \ +-L/usr/lib/gcc \ +-L/home/ubuntu/buildroot/output/build/uclibc-1.0.44/lib \ +-Wl,--build-id=none -Wl,-elf2flt=-r --static -lc -lgcc \ +/usr/lib/gcc/riscv64-linux-gnu/11/crtend.o \ +/usr/lib/gcc/riscv64-linux-gnu/11/crtn.o +``` + +注意到这里的链接过程所使用的库有两个来源:gcc 和 uClibc。很显然,来自 gcc 的库使用本机的也可以。 + +生成可执行文件后,我们使用 flthdr 查看它的 header: +```sh +$ flthdr ./hello-b-gcc +./hello-b-gcc + Magic: bFLT + Rev: 4 + Build Date: Fri Sep 29 08:20:22 2023 + Entry: 0x44 + Data Start: 0x99a0 + Data End: 0xb2d8 + BSS End: 0xd420 + Stack Size: 0x1000 + Reloc Start: 0xb2d8 + Reloc Count: 0x1f + Flags: 0x3 ( Load-to-Ram Has-PIC-GOT ) +``` +可以看到,编译过程没有问题,这个可执行文件确实是 bFLT 格式。 + +然后我们把构建好的源程序放到挂载好的磁盘镜像中: +```sh +$ sudo cp ./hello-b-gcc /mnt/buildroot-nommu/root +``` + +最后我们运行 linux 系统镜像,并在上面运行我们的 bFLT 程序: +```sh +$ cd /home/ubuntu/buildroot/output/images/ +$ ./start-qemu.sh + +~ # ls +hello-b-gcc +~ # ./hello-b-gcc +enter your number here: +114514 +hello world from number 114514! +``` \ No newline at end of file -- Gitee From c6c8120d682066662861962c8952605ff9683026 Mon Sep 17 00:00:00 2001 From: asterich Date: Fri, 29 Sep 2023 22:59:05 +0800 Subject: [PATCH 2/4] rename article "20230919-elf2flt-elf2flt-build-1.md" to "20230929-elf2flt-elf2flt-build-1.md" --- ...flt-elf2flt-build-1.md => 20230929-elf2flt-elf2flt-build-1.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename articles/{20230919-elf2flt-elf2flt-build-1.md => 20230929-elf2flt-elf2flt-build-1.md} (100%) diff --git a/articles/20230919-elf2flt-elf2flt-build-1.md b/articles/20230929-elf2flt-elf2flt-build-1.md similarity index 100% rename from articles/20230919-elf2flt-elf2flt-build-1.md rename to articles/20230929-elf2flt-elf2flt-build-1.md -- Gitee From 840f16ac91fe5ed9b53d7aedef018d5b9d9ca9f1 Mon Sep 17 00:00:00 2001 From: asterich Date: Fri, 29 Sep 2023 23:08:02 +0800 Subject: [PATCH 3/4] edit article: 20230929-elf2flt-elf2flt-build-1.md --- articles/20230929-elf2flt-elf2flt-build-1.md | 44 +++++++++++++------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/articles/20230929-elf2flt-elf2flt-build-1.md b/articles/20230929-elf2flt-elf2flt-build-1.md index 982fe6f..924651b 100644 --- a/articles/20230929-elf2flt-elf2flt-build-1.md +++ b/articles/20230929-elf2flt-elf2flt-build-1.md @@ -1,39 +1,43 @@ - +> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.2-rc2 - [spaces toc urls refs pangu]
+> Author: Odysseus <320873791@qq.com>
+> Date: 2023/09/19
+> Revisor: walimis <>
+> Project: [RISC-V Linux 内核剖析](https://gitee.com/tinylab/riscv-linux)
+> Proposal: [为 ELF2FLT 完善独立编译与安装支持](https://gitee.com/tinylab/riscv-linux/issues/I79PO2)
+> Sponsor: PLCT Lab, ISCAS # elf2flt 篇三 使用 -[TOC] - ## 前言 -在本机安装完 elf2flt 后,我们就可以使用它构建 bFLT 程序,并放到 no-mmu 的 linux 系统中运行。 +在本机安装完 elf2flt 后,我们就可以使用它构建 bFLT 程序,并放到 no-MMU 的 Linux 系统中运行。 -我们首先需要一个 no-mmu riscv 的系统,这里我们使用 buildroot 构建的 qemu 镜像来进行测试。 +我们首先需要一个 no-MMU RISC-V 的系统,这里我们使用 Buildroot 构建的 qemu 镜像来进行测试。 ## 准备 -准备工作主要是 buildroot 的构建。首先我们进入 cloud-lab 里面的 riscv64 实验环境。 +准备工作主要是 Buildroot 的构建。首先我们进入 cloud-lab 里面的 RISC-V 64 位实验环境。 ```bash $ tools/docker/run riscv-lab ``` -等待片刻,我们就可以进入到 riscv64 的实验环境了。理论上本机并不需要 riscv64 的环境,有交叉编译工具链即可,真正需要 riscv64 的是无 MMU 的目标环境。 +等待片刻,我们就可以进入到 RISC-V 64 位的实验环境了。理论上本机并不需要 RISC-V 64位的环境,有交叉编译工具链即可,真正需要 RISC-V 64 位的是无 MMU 的目标环境。 -而后,我们在 riscv-lab 里面安装 buildroot 。首先我们把 buildroot 仓库克隆下来,进入到 buildroot 目录: +而后,我们在 riscv-lab 里面安装 Buildroot 。首先我们把 Buildroot 仓库克隆下来,进入到 Buildroot 目录: ```sh $ cd /home/ubuntu $ git clone git://git.buildroot.net/buildroot $ cd buildroot ``` -进入后,我们可能需要先安装 CMake。如果本机是 riscv64 环境且没有安装 CMake(例如我们的 riscv-lab 环境),buildroot 会自己构建一份,此时会出现与 libatomic 库有关的错误。 +进入后,我们可能需要先安装 CMake。如果本机是 RISC-V 64 位环境且没有安装 CMake(例如我们的 riscv-lab 环境),Buildroot 会自己构建一份,此时会出现与 libatomic 库有关的错误。 ```sh $ sudo apt-get update $ sudo apt-get install cmake # riscv-lab needed ``` -然后我们开始配置 buildroot。由于我们是在 QEMU 上运行的 riscv64 no-mmu系统,因此采用`qemu_riscv64_nommu_virt_defconfig`配置: +然后我们开始配置 Buildroot。由于我们是在 QEMU 上运行的 RISC-V 64 位 no-MMU 系统,因此采用`qemu_riscv64_nommu_virt_defconfig`配置: ```sh $ make qemu_riscv64_nommu_virt_defconfig ``` @@ -75,7 +79,7 @@ Jan 1 00:00:10 login[34]: root login on 'console' ~ # ``` -至此,buildroot 的准备工作已经完成。 +至此,Buildroot 的准备工作已经完成。 ## 使用 @@ -95,7 +99,7 @@ int main() { } ``` -接下来我们编译源程序。理论上在 buildroot 外部编译的 uClibc 也能使用,但是为省却麻烦,我们直接使用 buildroot 编译好的 uClibc 库进行编译: +接下来我们编译源程序。理论上在 Buildroot 外部编译的 uClibc 也能使用,但是为省却麻烦,我们直接使用 Buildroot 编译好的 uClibc 库进行编译: ```sh $ gcc -o hello-b-gcc hello.c -nostdinc -nostdlib \ -I/usr/bin/../lib/gcc/riscv64-linux-gnu/11/include \ @@ -137,7 +141,7 @@ $ flthdr ./hello-b-gcc $ sudo cp ./hello-b-gcc /mnt/buildroot-nommu/root ``` -最后我们运行 linux 系统镜像,并在上面运行我们的 bFLT 程序: +最后我们运行 Linux 系统镜像,并在上面运行我们的 bFLT 程序: ```sh $ cd /home/ubuntu/buildroot/output/images/ $ ./start-qemu.sh @@ -148,4 +152,16 @@ hello-b-gcc enter your number here: 114514 hello world from number 114514! -``` \ No newline at end of file +``` + +## 总结 + +本篇文章主要内容为 elf2flt 工具的使用,由于其能够整合进已有的交叉工具链中,故使用起来比较方便,但是需要注意编译时使用的 libc 库和头文件。 + +## 参考资料 + +- [https://gitee.com/tinylab/elf2flt][001] +- [https://buildroot.org/downloads/manual/manual.html][002] + +[001]: https://gitee.com/tinylab/elf2flt +[002]: https://buildroot.org/downloads/manual/manual.html \ No newline at end of file -- Gitee From 36a28260d74496fbc3264627590c459a6f4a1926 Mon Sep 17 00:00:00 2001 From: asterich Date: Fri, 29 Sep 2023 23:08:28 +0800 Subject: [PATCH 4/4] elf2flt-elf2flt-build-1.md: commit correct result of tinycorrect Signed-off-by: asterich --- articles/20230929-elf2flt-elf2flt-build-1.md | 33 ++++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/articles/20230929-elf2flt-elf2flt-build-1.md b/articles/20230929-elf2flt-elf2flt-build-1.md index 924651b..62d62db 100644 --- a/articles/20230929-elf2flt-elf2flt-build-1.md +++ b/articles/20230929-elf2flt-elf2flt-build-1.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.2-rc2 - [spaces toc urls refs pangu]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.2-rc2 - [spaces codeblock codeinline pangu autocorrect]
> Author: Odysseus <320873791@qq.com>
> Date: 2023/09/19
> Revisor: walimis <>
@@ -12,7 +12,7 @@ 在本机安装完 elf2flt 后,我们就可以使用它构建 bFLT 程序,并放到 no-MMU 的 Linux 系统中运行。 -我们首先需要一个 no-MMU RISC-V 的系统,这里我们使用 Buildroot 构建的 qemu 镜像来进行测试。 +我们首先需要一个 no-MMU RISC-V 的系统,这里我们使用 Buildroot 构建的 QEMU 镜像来进行测试。 ## 准备 @@ -22,9 +22,10 @@ $ tools/docker/run riscv-lab ``` -等待片刻,我们就可以进入到 RISC-V 64 位的实验环境了。理论上本机并不需要 RISC-V 64位的环境,有交叉编译工具链即可,真正需要 RISC-V 64 位的是无 MMU 的目标环境。 +等待片刻,我们就可以进入到 RISC-V 64 位的实验环境了。理论上本机并不需要 RISC-V 64 位的环境,有交叉编译工具链即可,真正需要 RISC-V 64 位的是无 MMU 的目标环境。 + +而后,我们在 RISC-V-lab 里面安装 Buildroot。首先我们把 Buildroot 仓库克隆下来,进入到 Buildroot 目录: -而后,我们在 riscv-lab 里面安装 Buildroot 。首先我们把 Buildroot 仓库克隆下来,进入到 Buildroot 目录: ```sh $ cd /home/ubuntu $ git clone git://git.buildroot.net/buildroot @@ -32,35 +33,41 @@ $ cd buildroot ``` 进入后,我们可能需要先安装 CMake。如果本机是 RISC-V 64 位环境且没有安装 CMake(例如我们的 riscv-lab 环境),Buildroot 会自己构建一份,此时会出现与 libatomic 库有关的错误。 + ```sh $ sudo apt-get update $ sudo apt-get install cmake # riscv-lab needed ``` -然后我们开始配置 Buildroot。由于我们是在 QEMU 上运行的 RISC-V 64 位 no-MMU 系统,因此采用`qemu_riscv64_nommu_virt_defconfig`配置: +然后我们开始配置 Buildroot。由于我们是在 QEMU 上运行的 RISC-V 64 位 no-MMU 系统,因此采用 `qemu_riscv64_nommu_virt_defconfig` 配置: + ```sh $ make qemu_riscv64_nommu_virt_defconfig ``` 最后开始构建: + ```sh $ make ``` -构建完成后,生成的镜像在`/home/ubuntu/buildroot/output/images`下面。我们看一下这个目录下有什么: +构建完成后,生成的镜像在 `/home/ubuntu/buildroot/output/images` 下面。我们看一下这个目录下有什么: + ```sh $ cd /home/ubuntu/buildroot/output/images $ ls Image rootfs.ext2 rootfs.tar start-qemu.sh ``` -这里的`Image`是系统镜像,`rootfs.ext2`是磁盘镜像,`start-qemu.sh`是系统镜像在 QEMU 上运行的启动脚本。由于下文需要将我们自己的 bFLT 文件拷贝到磁盘镜像下,我们先将其挂载: +这里的 `Image` 是系统镜像,`rootfs.ext2` 是磁盘镜像,`start-qemu.sh` 是系统镜像在 QEMU 上运行的启动脚本。由于下文需要将我们自己的 bFLT 文件拷贝到磁盘镜像下,我们先将其挂载: + ```sh $ sudo mkdir /mnt/buildroot-nommu $ sudo mount rootfs.ext2 /mnt/buildroot-nommu ``` 然后我们启动镜像: + ```sh $ ./start-qemu.sh @@ -76,7 +83,7 @@ Saving 256 bits of creditable seed for next boot Welcome to Buildroot buildroot login: root Jan 1 00:00:10 login[34]: root login on 'console' -~ # +~ # ``` 至此,Buildroot 的准备工作已经完成。 @@ -85,9 +92,10 @@ Jan 1 00:00:10 login[34]: root login on 'console' elf2flt 的使用实际上非常简单,只要安装完成,它就已经整合到我们的交叉编译工具链里面。 -bFLT 程序的构建过程是将源程序编译成 ELF,再将其与同为 ELF 格式的运行时库(例如 uClibc)进行静态链接,因此,理论上只要是 libc,无论其是 glibc、uClibc 还是 musl libc ,都可以通过此种方式链接到 bFLT 程序里。这里以 uClibc 为例,讲解如何用整合进 elf2flt 的工具链编译一个可以运行的 bFLT 文件。 +bFLT 程序的构建过程是将源程序编译成 ELF,再将其与同为 ELF 格式的运行时库(例如 uClibc)进行静态链接,因此,理论上只要是 libc,无论其是 glibc、uClibc 还是 musl libc,都可以通过此种方式链接到 bFLT 程序里。这里以 uClibc 为例,讲解如何用整合进 elf2flt 的工具链编译一个可以运行的 bFLT 文件。 首先,我们以一个简单的程序作为例子(`hello.c`): + ```c #include int main() { @@ -100,6 +108,7 @@ int main() { ``` 接下来我们编译源程序。理论上在 Buildroot 外部编译的 uClibc 也能使用,但是为省却麻烦,我们直接使用 Buildroot 编译好的 uClibc 库进行编译: + ```sh $ gcc -o hello-b-gcc hello.c -nostdinc -nostdlib \ -I/usr/bin/../lib/gcc/riscv64-linux-gnu/11/include \ @@ -119,6 +128,7 @@ $ gcc -o hello-b-gcc hello.c -nostdinc -nostdlib \ 注意到这里的链接过程所使用的库有两个来源:gcc 和 uClibc。很显然,来自 gcc 的库使用本机的也可以。 生成可执行文件后,我们使用 flthdr 查看它的 header: + ```sh $ flthdr ./hello-b-gcc ./hello-b-gcc @@ -134,14 +144,17 @@ $ flthdr ./hello-b-gcc Reloc Count: 0x1f Flags: 0x3 ( Load-to-Ram Has-PIC-GOT ) ``` + 可以看到,编译过程没有问题,这个可执行文件确实是 bFLT 格式。 然后我们把构建好的源程序放到挂载好的磁盘镜像中: + ```sh $ sudo cp ./hello-b-gcc /mnt/buildroot-nommu/root ``` 最后我们运行 Linux 系统镜像,并在上面运行我们的 bFLT 程序: + ```sh $ cd /home/ubuntu/buildroot/output/images/ $ ./start-qemu.sh @@ -164,4 +177,4 @@ hello world from number 114514! - [https://buildroot.org/downloads/manual/manual.html][002] [001]: https://gitee.com/tinylab/elf2flt -[002]: https://buildroot.org/downloads/manual/manual.html \ No newline at end of file +[002]: https://buildroot.org/downloads/manual/manual.html -- Gitee