[RISC-V] RISC-V 툴체인으로 리눅스 커널 빌드하기

AustinKim의 이미지

이번 포스트에서는 RISC-V 툴체인을 설치해 리눅스 커널을 빌드하는 방법을 소개합니다.

먼저 RISC-V 툴체인을 설치하는 명령어를 입력합시다.

<< RISC-V 툴체인 소스를 내려받기 >>

다음 명령어를 입력해 RISC-V 툴체인 소스를 내려받습니다.

$ git clone --recursive https://github.com/riscv/riscv-gnu-toolchain

아래는 리눅스 터미널에서 위 명령어를 입력한 후의 출력 결과입니다. 소스를 내려받는데 1시간 정도 걸리네요.

austindh.kim:~/src/risc-v_toolchain$ git clone --recursive https://github.com/riscv/riscv-gnu-toolchain

 
Cloning into 'riscv-gnu-toolchain'...
remote: Enumerating objects: 21, done.
remote: Counting objects: 100% (21/21), done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 7795 (delta 7), reused 16 (delta 4), pack-reused 7774
Receiving objects: 100% (7795/7795), 4.75 MiB | 970.00 KiB/s, done.
Resolving deltas: 100% (3940/3940), done.
Submodule 'qemu' (<a href="https://git.qemu.org/git/qemu.git" rel="nofollow">https://git.qemu.org/git/qemu.git</a>) registered for path 'qemu'
Submodule 'riscv-binutils' (<a href="https://github.com/riscv/riscv-binutils-gdb.git" rel="nofollow">https://github.com/riscv/riscv-binutils-gdb.git</a>) registered for path 'riscv-binutils'
Submodule 'riscv-dejagnu' (<a href="https://github.com/riscv/riscv-dejagnu.git" rel="nofollow">https://github.com/riscv/riscv-dejagnu.git</a>) registered for path 'riscv-dejagnu'
Submodule 'riscv-gcc' (<a href="https://github.com/riscv/riscv-gcc.git" rel="nofollow">https://github.com/riscv/riscv-gcc.git</a>) registered for path 'riscv-gcc'
Submodule 'riscv-gdb' (<a href="https://github.com/riscv/riscv-binutils-gdb.git" rel="nofollow">https://github.com/riscv/riscv-binutils-gdb.git</a>) registered for path 'riscv-gdb'
...

시간이 오래 걸리니 밥 먹기 전에 명령어를 입력해 놔야 겠습니다.

<< RISC-V 툴체인 소스 빌드하고 설치하기 >>

소스를 전부 내려받은 다음에 아래와 같이 디렉터리를 생성합니다.

 
$ mkdir -p opt/riscv
$ mkdir build
$ cd build
$ ../configure --prefix=/home001/austindh.kim/src/risc-v_toolchain/riscv-gnu-toolchain/opt/riscv --enable-multilib

아래는 리눅스 터미널에서 위 명령어를 실행한 후 출력 결과입니다. 빌드되는데 2시간 정도가 소요됩니다.

 
austindh.kim:~/src/risc-v_toolchain$ mkdir -p opt/riscv
austindh.kim:~/src/risc-v_toolchain$ mkdir build
austindh.kim:~/src/risc-v_toolchain$ cd build
austindh.kim:~/src/risc-v_toolchain/build$ ../configure --prefix=/home001/austindh.kim/src/risc-v_toolchain/riscv-gnu-toolchain/opt/riscv --enable-multilib
...
make[4]: Entering directory '/home001/austindh.kim/src/risc-v_toolchain/riscv-gnu-toolchain/build/build-gdb-linux/libctf'
make[4]: Leaving directory '/home001/austindh.kim/src/risc-v_toolchain/riscv-gnu-toolchain/build/build-gdb-linux/libctf'
make[3]: Leaving directory '/home001/austindh.kim/src/risc-v_toolchain/riscv-gnu-toolchain/build/build-gdb-linux/libctf'
make[2]: Nothing to be done for 'install-target'.
make[2]: Leaving directory '/home001/austindh.kim/src/risc-v_toolchain/riscv-gnu-toolchain/build/build-gdb-linux'
make[1]: Leaving directory '/home001/austindh.kim/src/risc-v_toolchain/riscv-gnu-toolchain/build/build-gdb-linux'
mkdir -p stamps/ && touch stamps/build-gdb-linux
austindh.kim:~/src/risc-v_toolchain/riscv-gnu-toolchain/build$

빌드가 끝나고 "~src/risc-v_toolchain/riscv-gnu-toolchain/opt/riscv/bin" 디렉터리로 이동하니, 다음과 같은 파일이 생성됐음을 확인할 수 있습니다.

 
austindh.kim:~/src/risc-v_toolchain/riscv-gnu-toolchain/opt/riscv/bin$ ls
riscv64-unknown-linux-gnu-addr2line  riscv64-unknown-linux-gnu-gcc         riscv64-unknown-linux-gnu-gdb            riscv64-unknown-linux-gnu-objcopy  ... 
riscv64-unknown-linux-gnu-elfedit    riscv64-unknown-linux-gnu-gcov-dump   riscv64-unknown-linux-gnu-lto-dump       riscv64-unknown-linux-gnu-strings
riscv64-unknown-linux-gnu-g++        riscv64-unknown-linux-gnu-gcov-tool   riscv64-unknown-linux-gnu-nm             riscv64-unknown-linux-gnu-strip

이제 RISC-V 툴체인 소스 빌드를 마무리했습니다.

<< RISC-V 툴체인으로 리눅스 커널 빌드하기>>

다음 명령어를 입력해 리눅스 커널 소스 코드를 내려 받습니다.

$ git clone https://kernel.googlesource.com/pub/scm/linux/kernel/git/next/linux-next

소스를 내려 받은 다음에 확인한 디렉터리 정보는 다음과 같습니다.

austindh.kim:~/src/dev_kernel/59_linux_kernel$ ls
linux-next

'riscv_kernel_build.sh' 이름으로 셸 스크립트 파일을 생성한 다음에, 아래 빌드 스크립트를 입력합니다.

 
#!/bin/bash
 
export PATH=$PATH:/home001/austindh.kim/src/risc-v_toolchain/riscv-gnu-toolchain/opt/riscv/bin
 
echo "configure build output path"
TOP_PATH=$( cd "$(dirname "$0")" ; pwd )
OUTPUT="$TOP_PATH/out"
 
BUILD_LOG="$TOP_PATH/rpi_build_log.txt"
 
OUTPUT_PATH=$( cd "$(dirname "$0")" ; pwd )
OUTPUT="$OUTPUT_PATH/out"
 
pushd linux-next > /dev/null
 
# configure defconfig
make ARCH=riscv O=$OUTPUT CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig -j16  2>&1
 
# build kernel with riscv tool-chain
make ARCH=riscv O=$OUTPUT CROSS_COMPILE=riscv64-unknown-linux-gnu- modules dtbs -j16  2>&1 | tee $BUILD_LOG
 
popd > /dev/null
<code> 
 
위 빌드 스크립트에서 가장 중요한 명령어는 아래와 같습니다.
<code> 
# configure defconfig
make ARCH=riscv O=$OUTPUT CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig -j16  2>&1
 
# build kernel with riscv tool-chain
make ARCH=riscv O=$OUTPUT CROSS_COMPILE=riscv64-unknown-linux-gnu- modules dtbs -j16  2>&1 | tee $BUILD_LOG

'arch/riscv/configs/defconfig' 파일을 다음과 같이 수정해 vmlinux에 디버깅 심벌이 추가되도록 합시다.

 
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index d58c93e..6ea8e83 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -20,6 +20,7 @@ CONFIG_SMP=y
 CONFIG_JUMP_LABEL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
+CONFIG_DEBUG_INFO=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y

'riscv_kernel_build.sh' 빌드 셸 스크립트를 실행해, RISCV 툴 체인으로 커널을 빌드합니다.

아래는 'riscv_kernel_build.sh' 빌드 셸 스크립트를 터미널에서 실행한 출력 화면입니다.

 
austindh.kim:~/src/dev_kernel/59_linux_kernel$ ./riscv_kernel_build.sh
configure build output path
make[1]: Entering directory '/home001/austindh.kim/src/dev_kernel/59_linux_kernel/out'
  GEN     Makefile
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
...
  KSYMS   .tmp_vmlinux.kallsyms2.S
  AS      .tmp_vmlinux.kallsyms2.S
  LD      vmlinux
  SYSMAP  System.map
  MODPOST Module.symvers
  CC [M]  fs/nfs/flexfilelayout/nfs_layout_flexfiles.mod.o
  LD [M]  fs/nfs/flexfilelayout/nfs_layout_flexfiles.ko

'out' 폴더를 가니 제대로 커널이 빌드됐음을 확인할 수 있습니다.

 
austindh.kim:~/src/dev_kernel/59_linux_kernel/out$ ls
arch   crypto   include  kernel    mm                       modules.order   scripts   source      virt       vmlinux.symvers
block  drivers  init     lib       modules.builtin          Module.symvers  security  System.map  vmlinux
certs  fs       ipc      Makefile  modules.builtin.modinfo  net             sound     usr         vmlinux.o

<< RISC-V 바이너리 유틸리티 사용해보기 >>

이번엔 다음 명령어를 입력해 vmlinux의 셉션 정보를 확인해보겠습니다.

 
$ ./riscv64-unknown-linux-gnu-objdump -x vmlinux | more

아래는 './riscv64-unknown-linux-gnu-objdump -x vmlinux | more' 빌드 셸 스크립트를 터미널에서 실행한 출력 화면입니다.

 
austindh.kim:~/src/dev_kernel/59_linux_kernel/out$ ./riscv64-unknown-linux-gnu-objdump -x vmlinux | more
 
vmlinux:     file format elf64-littleriscv
vmlinux
architecture: riscv:rv64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0xffffffe000000000
 
Program Header:
    LOAD off    0x0000000000001000 vaddr 0xffffffe000000000 paddr 0x0000000000000000 align 2**12
         filesz 0x0000000000025af4 memsz 0x0000000000025af4 flags r-x
    LOAD off    0x0000000000027000 vaddr 0xffffffe000026000 paddr 0x0000000000026000 align 2**12
         filesz 0x0000000000019de8 memsz 0x0000000000019de8 flags rwx
    LOAD off    0x0000000000041000 vaddr 0xffffffe000200000 paddr 0x0000000000200000 align 2**12
         filesz 0x00000000006ce0a2 memsz 0x00000000006ce0a2 flags r-x
    LOAD off    0x0000000000710000 vaddr 0xffffffe000a00000 paddr 0x0000000000a00000 align 2**12
         filesz 0x000000000022a9fc memsz 0x000000000022a9fc flags rw-
    LOAD off    0x000000000093b000 vaddr 0xffffffe000e00000 paddr 0x0000000000e00000 align 2**12
         filesz 0x0000000000002400 memsz 0x0000000000002400 flags r--
    LOAD off    0x000000000093e000 vaddr 0xffffffe001000000 paddr 0x0000000001000000 align 2**12
         filesz 0x00000000000e19b4 memsz 0x0000000000131920 flags rw-
    NOTE off    0x000000000093a9c0 vaddr 0xffffffe000c2a9c0 paddr 0x0000000000c2a9c0 align 2**2
         filesz 0x000000000000003c memsz 0x000000000000003c flags r--
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-


출력 결과를 보니 아키텍처의 정보는 'riscv:rv64'이고 스타트업 코드의 위치는 0xffffffe000000000 주소임을 알 수 있습니다.

(개인블로그)
http://rousalome.egloos.com/

Forums: 

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.