K 210-NOMMU linuxの実行


紹介する


 これは初心者向けのチュートリアルで、主にk 210上でNOMMU linuxを実行するためにカーネルをコンパイルする方法について説明します.また、このチュートリアルでは、k 210上でtccを使用してCプログラムを実行できるように、tccをクロスコンパイルする方法を示します.カーネルソースhttps://www.kernel.orgダウンロードし、Damien Le Moal’s k 210を適用patch@damien-lemoal(Damien Le Moalのk 210パッチ)

ビルド前


 buildの前に、プロジェクトをクローンし、buildroot依存パッケージをインストールする必要があります.
Debian bullseye or Ubuntu 18.04.4
	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
	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

	git clone https://github.com/vowstar/k210-linux-nommu.git
	
	cd k210-linux-nommu
	
	export PROJ_ROOT=$(pwd)

Buildroot


 まず、Damien Le Moalのk 210パッチの説明に従って、修正されたbuildrootによってツールチェーンをコンパイルする必要があります.最初はgitサブモジュールとして追加する予定でしたが、初心者向けのチュートリアルだと言われていたのでbuildrootソースコードがプロジェクトに追加されました.
Damien Le Moal@damien-lemoalの元のbuildroot:
https://github.com/damien-lemoal/riscv64-nommu-buildroot

カーネルの移植

sh ./prepare_buildroot.shを実行して、ファイルエラーが見つからないように、カーネルアーカイブファイルをriscv64-nommu-buildroot/package/kernelに格納します.
cd $PROJ_ROOT
sh ./prepare_buildroot.sh

ツールチェーンの構築


カーネルを構築する前に、riscv 64 nommu uClibcツールチェーンを構築する必要があります.
このプロセスには、コンパイル時に多くのソフトウェアがダウンロードされるため、良好なネットワーク接続状況が必要です.
cd "$PROJ_ROOT/riscv64-nommu-buildroot"
make riscv64_nommu_defconfig
make

ツールチェーンの取り付け
cd "$PROJ_ROOT/riscv64-nommu-buildroot"
sudo cp -r output/host /opt/riscv64-uclibc
export PATH=/opt/riscv64-uclibc/bin:$PATH

Rootfsの構築


Busybox
busyboxはcloneからgit://git.busybox.net/busybox.git最初はgitサブモジュールとして追加する予定でしたが、初心者向けのチュートリアルと言われていたため、busyboxソースコードがプロジェクトに追加されました.$PROJ_ROOT/busybox/configs/k210_nommu_defconfigファイルを修正することによりk 210 nommu linuxに適合する.
export PATH=/opt/riscv64-uclibc/bin:$PATH
cd "$PROJ_ROOT/busybox"
make k210_nommu_defconfig
make SKIP_STRIP=y
make SKIP_STRIP=y install

インストール後、すべてのデータは$PROJ_ROOT/rootfs_k210にインストールされます.

Tiny Cコンパイラ


Tinycc-この最小のANSI Cコンパイラ.k 210には、k 210 Cプログラムを開発できるCコンパイラがあることを望んでいます.そこで,tccをクロスコンパイルした.
このTiny Cコンパイラのソースコードは:https://github.com/mirror/tinycc.gitから来ている.最初はgitサブモジュールとして追加する予定でしたが、初心者のチュートリアルだと言われていたのでtinyccソースコードがプロジェクトに追加されました.
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

--extra-cflags="-CONFIG_TCC_STATIC=1"が追加されていない場合、コンパイル中にエラーが発生します.
tcc.h:41:12: fatal error: dlfcn.h: No such file or directory

このコマンドで修復できます:-DCONFIG_TCC_STATIC=1また、現在のk 210 nommu uclibcはスレッドをサポートしていないため、コードを変更して-lpthreadを削除しました.
--- 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

tccをコンパイルすると、大量のメモリが消費され、k 210 nommu linuxで実行できません.@minuxは10分以内に理由を見つけ、次のようにコードを編集します.
--- 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

そして正常に動作します.
そして、tcc-runのとき、mprotectの問題に遭遇しました.@minuxは原因を見つけ、k 210 nommu linuxはmprotectを必要としない.コードの編集:
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);

そして、基本的には完全です.
待機事項:elf 2 fltサポートを追加します.tccの出力フォーマットはelfであり、k 210 nommu linuxで直接実行できないため、いくつかの変換が必要である.
しかし、tcc -runは、例えば、
// 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!!!
"
); return 0; }

Run with:
tcc -run -nostdlib main.c

The result:
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.
cd $PROJ_ROOT
sh ./prepare_k210_cpio.sh

カーネルの構築


linux-5.6-rc 1ソースコードはDamien Le Moalのk 210パッチを適用した.
次の人たちの貢献に感謝します.signed-off-by commiters:
  • Damien Le Moal [email protected]
  • Anup Patel [email protected]
  • Christoph Hellwig [email protected]

  •  の最初の計画はgitサブモジュールとして追加されたが、初心者のチュートリアルであるため、カーネルソースコードがプロジェクトに追加されたという人もいる.
     コンパイルを円滑に行うために、ROOTSS k 210が既に作成する.cpioバイナリファイルはカーネルソースディレクトリに格納されます.このファイルはソースディレクトリにコミットすべきではありません.これはマイナスの例ですから、私のようにしないでください.
    cd "$PROJ_ROOT/linux-kernel"
    export PATH=/opt/riscv64-uclibc/bin:$PATH
    make ARCH=riscv CROSS_COMPILE=riscv64-linux- nommu_k210_defconfig
    make ARCH=riscv CROSS_COMPILE=riscv64-linux- -j
    

    テスト


     k 210開発ボードをプログラミングし、linuxを楽しむ.Sipeed MAIX dan開発ボードを使用している場合、シリアルポートは/dev/ttyUSB 0です.ユーザー${whoami)のシリアルポートを使用するには、uucpまたは/およびDialoutグループに${whoami)を追加する必要があります.
    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
    

    viエディタを使用してファイルを追加:main.c
    #include 
    
    int 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!!!
    "
    ); return 0; }

    次に、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!!!
    

    最後に「hello world!」を出力できます.しました.