Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/vowstar/k210-linux-nommu
K210 run linux nommu (From Damien Le Moal's patch)
https://github.com/vowstar/k210-linux-nommu
Last synced: 21 days ago
JSON representation
K210 run linux nommu (From Damien Le Moal's patch)
- Host: GitHub
- URL: https://github.com/vowstar/k210-linux-nommu
- Owner: vowstar
- Created: 2020-02-16T06:05:51.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2023-07-02T16:42:56.000Z (over 1 year ago)
- Last Synced: 2024-10-11T13:36:15.464Z (about 1 month ago)
- Language: C
- Size: 279 MB
- Stars: 154
- Watchers: 13
- Forks: 34
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# k210-linux-nommu
## Introduction
This is a tutorial for beginners, mainly describes how to compile the kernel to run NOMMU linux on k210. And, this tutorial will show how to cross compile a tcc so that you can execute a C program with tcc on the k210. The kernel source is download from https://www.kernel.org, and applied [Damien Le Moal's k210 patch](https://lore.kernel.org/linux-riscv/BYAPR04MB5816C1EADCEF92F1F1DE60E0E7140@BYAPR04MB5816.namprd04.prod.outlook.com/T/#t) [@damien-lemoal](https://github.com/damien-lemoal)
## Before build
Before build, you should clone this project first and install the packages that buildroot depends on.
### Debian bullseye or Ubuntu 18.04.4
```bash
DEBIAN_FRONTEND=noninteractive apt-get update -qq && \
DEBIAN_FRONTEND=noninteractive apt-get install -yq \
build-essential \
device-tree-compiler \
bison \
flex \
file \
git \
curl \
wget \
cpio \
python \
unzip \
rsync \
bc
```### Fedora 31 or CentOS 8
```bash
RUN dnf -y update && \
dnf -y groupinstall 'Development Tools' && \
dnf -y --enablerepo=PowerTools install \
autoconf \
gperf \
bison \
flex \
wget \
curl \
git \
python36 \
perl \
sudo \
cpio
```### Git clone
```bash
git clone https://github.com/JAicewizard/k210-linux-nommu.gitcd k210-linux-nommu
export PROJ_ROOT=$(pwd)
```## Init kernel tree
First we need to download the kernel sources. This is done by
```
cd $PROJ_ROOT
git submodule update --init
```This might take a while as the kernel tree is very large.
If you want to try out a specific version you can run the following to start using kernel version x.y
```
cd "$PROJ_ROOT/linux-kernel"
git checkout vx.y
```To top it off we need to apply a small patch that allows us to start a shell:
```
cd "PROJ_ROOT/linux-kernel"
git apply ../fixk210.patch
```## Buildroot
After this we need to compile the toolchain, according to the description of Damien Le Moal's k210 patch, the toolchain can be obtained through [modified buildroot](https://github.com/damien-lemoal/riscv64-nommu-buildroot). Originally planned to be added as a git submodule, but some people said that this is a tutorial for beginners, so the [buildroot source code](./riscv64-nommu-buildroot) was added to this project.
Original buildroot by Damien Le Moal @damien-lemoal:
https://github.com/damien-lemoal/riscv64-nommu-buildroot
### Move kernel
Run ``sh ./prepare_buildroot.sh`` to put kernel archive into ``riscv64-nommu-buildroot/package/kernel`` to prevent file not found error.
```bash
cd $PROJ_ROOT
sh ./prepare_buildroot.sh
```### Build toolchain
Before build kernel, we should build riscv64 nommu uClibc toolchain first.
This process needs to ensure a good network connection. A lot of software is downloaded when compiling.
```bash
cd "$PROJ_ROOT/riscv64-nommu-buildroot"
make riscv64_nommu_defconfig
make
```### Install toolchain
```bash
cd "$PROJ_ROOT/riscv64-nommu-buildroot"
sudo cp -r output/host /opt/riscv64-uclibc
export PATH=/opt/riscv64-uclibc/bin:$PATH
```## Build Rootfs
### Busybox
This busybox clone from git://git.busybox.net/busybox.git. Originally planned to be added as a git submodule, but some people said that this is a tutorial for beginners, so the [busybox source code](./busybox) was added to this project.
I modified the ``$PROJ_ROOT/busybox/configs/k210_nommu_defconfig`` file to fit k210 nommu linux.
```bash
export PATH=/opt/riscv64-uclibc/bin:$PATH
cd "$PROJ_ROOT/busybox"
make k210_nommu_defconfig
make SKIP_STRIP=y
make SKIP_STRIP=y install
```After install, all the data installed to ``$PROJ_ROOT/rootfs_k210``
### Tiny C Compiler
C Scripting Everywhere - The Smallest ANSI C compiler. We have a wish is to have a C compiler on k210 that can develop k210 C programs.
So we cross-compiled tcc. This process is done by [@minux](https://github.com/minux) and me together.The Tiny C Compiler source code from https://github.com/mirror/tinycc.git. Originally planned to be added as a git submodule, but some people said that this is a tutorial for beginners, so the [tinycc source code](./tinycc) was added to this project.
```bash
export PATH=/opt/riscv64-uclibc/bin:$PATH
cd "$PROJ_ROOT/tinycc"
./configure --prefix=/usr --cross-prefix=riscv64-linux- --cpu=riscv64 --extra-cflags="-DCONFIG_TCC_STATIC=1" --extra-ldflags=-Wl,-elf2flt=-r
make
make DESTDIR=../rootfs_k210 install
```If not add ``--extra-cflags="-DCONFIG_TCC_STATIC=1"``, when compile it will get error:
```
tcc.h:41:12: fatal error: dlfcn.h: No such file or directory
```[@minux](https://github.com/minux) fix it using ``-DCONFIG_TCC_STATIC=1``
Also the current k210 nommu uclibc have no threading support, so I changed the code and removed the ``-lpthread``:
```diff
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,8 @@ ifdef CONFIG_WIN32
CFGWIN = -win
NATIVE_TARGET = $(ARCH)-win$(if $(findstring arm,$(ARCH)),ce,32)
else
- LIBS=-lm -lpthread
+ #LIBS=-lm -lpthread
+ LIBS=-lm
ifneq ($(CONFIG_ldl),no)
LIBS+=-ldl
endif
```When tcc is compiled, it consumes a lot of memory, which makes it impossible to run on k210 nommu linux. [@minux](https://github.com/minux) found the reason in only 10 minutes, and edit the code as follows:
```diff
--- a/tccpp.c
+++ b/tccpp.c
@@ -130,9 +130,9 @@ ST_FUNC void expect(const char *msg)
#define TAL_DEBUG_FILE_LEN 40
#endif
-#define TOKSYM_TAL_SIZE (768 * 1024) /* allocator for tiny TokenSym in table_ident */
-#define TOKSTR_TAL_SIZE (768 * 1024) /* allocator for tiny TokenString instances */
-#define CSTR_TAL_SIZE (256 * 1024) /* allocator for tiny CString instances */
+#define TOKSYM_TAL_SIZE (64 * 1024) /* allocator for tiny TokenSym in table_ident */
+#define TOKSTR_TAL_SIZE (64 * 1024) /* allocator for tiny TokenString instances */
+#define CSTR_TAL_SIZE (16 * 1024) /* allocator for tiny CString instances */
#define TOKSYM_TAL_LIMIT 256 /* prefer unique limits to distinguish allocators debug msgs */
#define TOKSTR_TAL_LIMIT 128 /* 32 * sizeof(int) */
#define CSTR_TAL_LIMIT 1024
```And then it is works.
Then, we encountered the mprotect problem when ``tcc -run``. [@minux](https://github.com/minux) found the reason, k210 nommu linux don't need mprotect. Edit the code:
```diff
diff --git a/tccrun.c b/tccrun.c
index 4bf709d..42a0852 100644
--- a/tccrun.c
+++ b/tccrun.c
@@ -304,6 +304,13 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
static void set_pages_executable(TCCState *s1, void *ptr, unsigned long length)
{
+#if defined TCC_TARGET_RISCV64
+ /* RISC-V NON MMU don't need mprotect */
+ void __clear_cache(void *beginning, void *end);
+ __clear_cache(ptr, (char *)ptr + length);
+ return;
+#endif
+
#ifdef _WIN32
unsigned long old_protect;
VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
```It almost works.
TODO: Add elf2flt support. The tcc output format is elf, can't run under k210 nommu linux directly, so need some convert.
But ``tcc -run`` works, example:
```c
// main.c
int fib(int n){
if(n < 2){
return 1;
}
return fib(n-1) + fib(n-2);
}int _start() {
int i;
for (i = 0; i < 15; i++)
printf("%d ", fib(i));
printf("Hello world from K210!!!\n");
return 0;
}
```Run with:
```bash
tcc -run -nostdlib main.c
```The result:
![RUN TCC](./images/k210_nommu_linux_run_tcc.png "k210 nommu linux run tcc")
### k210 cpio image
Run ``sh ./prepare_k210_cpio.sh`` to put k210 rootfs cpio image into ``linux-kernel/k210.cpio`` to update images.
```bash
cd $PROJ_ROOT
sh ./prepare_k210_cpio.sh
```## Build Kernel
The [linux-5.6-rc1 source](https://www.kernel.org) applied [Damien Le Moal's k210 patch](https://lore.kernel.org/linux-riscv/BYAPR04MB5816C1EADCEF92F1F1DE60E0E7140@BYAPR04MB5816.namprd04.prod.outlook.com/T/#t).
Thank you so much for their efforts, signed-off-by commiters:
- Damien Le Moal
- Anup Patel
- Christoph HellwigOriginally planned to be added as a git submodule, but some people said that this is a tutorial for beginners, so the [kernel source code](./linux-kernel) was added to this project.
In order to be able to compile smoothly, I shamelessly put the ROOTFS ``k210.cpio`` binary file into the kernel source directory. This file should not be submitted to the source directory. This is a negative example, please do not do this like me.
```bash
export PATH=/opt/riscv64-uclibc/bin:$PATH
cd "$PROJ_ROOT/linux-kernel"
make ARCH=riscv CROSS_COMPILE=riscv64-linux- nommu_k210_defconfig
make ARCH=riscv CROSS_COMPILE=riscv64-linux- -j
```### Build kernel with SD support
You can also use the SD card for rootfs. This can be done with the patched config as follows:
```bash
export PATH=/opt/riscv64-uclibc/bin:$PATH
cd "$PROJ_ROOT/linux-kernel"
make ARCH=riscv CROSS_COMPILE=riscv64-linux- nommu_k210_sdcard_defconfig
make ARCH=riscv CROSS_COMPILE=riscv64-linux- -j
```## Play
Program the k210 board and enjoy linux. Suppose you are using Sipeed MAIX dan development board and the serial port is ``/dev/ttyUSB0``.
To use serial port whith user $(whoami), you need add $(whoami) into uucp or/and dialout group.
```bash
sudo usermod -a -G uucp $(whoami)
sudo usermod -a -G dialout $(whoami)
sudo python3 -m pip install kflash
su $(whoami)kflash -B dan -b 3000000 -p /dev/ttyUSB0 arch/riscv/boot/loader.bin
python3 -m serial.tools.miniterm --raw --filter colorize /dev/ttyUSB0 115200
```Using vi editor to add a file ``main.c``
```c
#includeint fib(int n){
if(n < 2){
return 1;
}
return fib(n-1) + fib(n-2);
}int main(int argc, char* argv[]) {
int i;
for (i = 0; i < 15; i++)
printf("%d ", fib(i));
printf("Hello world from K210!!!\n");
return 0;
}
```And run with ``tcc -run main.c``
```
tcc -run main.c
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 Hello world from K210!!!
```You will get the hello world output.
Enjoy!
## Using u-boot
This is a short list of commands to download and build u-boot, and setup linux booting.
These instructions are MAIX-BIT specifix, for other boards you need diferent configs. Look these up for your board. The u-boot config and the `CONFIG_SOC_CANAAN_K210_DTB_SOURCE`, `arch/riscv/configs/nommu_k210_sdcard_defconfig`, and the dtb moved to the SD card needs to be changesClone the sources:
```
git clone https://source.denx.de/u-boot/u-boot.git
```Build for RISC-V:
```
export PATH=/opt/riscv64-uclibc/bin:$PATH
make sipeed_maix_bitm_defconfig
make CROSS_COMPILE=
```### prepare SD card
Grab an SD card, and partition it with partition 1 being FAT32 and partition 2 EXT2.
If you intend to use non-SDcard linux config, the second partition is not needed, and all instructions using it can be skipped.
Mount both partiions, here the mountpoints will be called P1 and P2.
Go to the u-boot root and execute:
```
tools/mkimage -A riscv -O linux -T kernel -C none -a 0x80000000 -e 0x80000000 -n linux -d {Path to linux "Image" file} P1/uImage
```Note that the Image file is called Image, it is not the loader.bin used above, but is in the same directory.
Copy the dtb over (required by u-boot)
```
cd $PROJ_ROOT
cp arch/riscv/boot/dts/canaan/sipeed_maix_bit.dtb P1/k210.dtb
```Copy the rootfs:
```
cd "$PROJ_ROOT/rootfs_k210"
cp * P2 -r
```Unmount the SD card, put it in your device.
Then flash u-boot:
```
kflash -tp /dev/ttyUSB0 -B goE u-boot-dtb.bin
```This will automatically open the miniterm, you should see u-boot booting. It should show a countdown until automatic boot, once it hits 0 it should boot linux with the shell as earlier.