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:
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
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 https://github.com/vowstar/k210-linux-nommu.git
cd k210-linux-nommu
export PROJ_ROOT=$(pwd)
cd $PROJ_ROOT
sh ./prepare_buildroot.sh
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
export PATH=/opt/riscv64-uclibc/bin:$PATH
cd "$PROJ_ROOT/busybox"
make k210_nommu_defconfig
make SKIP_STRIP=y
make SKIP_STRIP=y install
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
tcc.h:41:12: fatal error: dlfcn.h: No such file or directory
--- 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
--- 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
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);
// 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;
}
tcc -run -nostdlib main.c
cd $PROJ_ROOT
sh ./prepare_k210_cpio.sh
の最初の計画は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!」を出力できます.しました.