주희아빠의 헝그리 라이딩

ARM 환경에서 둠 실행하기. III편 - Buildroot 본문

나름 IT 이야기

ARM 환경에서 둠 실행하기. III편 - Buildroot

도림천 버섯돌이 2023. 11. 11. 18:10

2023.11.28

사실 'arm 에서 doom 실행하기' 의 주요 내용은 2편에서 얼추 마무리 되었습니다. 3편은 앞으로 크로스 컴파일에 도움이 되는 내용에 대해 추가합니다.

크로스 컴파일이 처음이라면 본 블로그에 있는 다른 글을 먼저 참고 하시기 바랍니다.

 

1. Buildroot 란 무엇인가?

앞서 소개한 'arm 환경에서 둠 실행하기 I, II편' 에서는 prboom 에서 사용하기 위한 sdl 재료를 직접 컴파일하였습니다. 또한 openssh 컴파일에서도 zlib 와 openssl 라이브러리를 직접 컴파일하여 준비하였습니다.

이렇게 컴파일에 필요한 부가 재료들을 하나 하나 직접 준비하지 않고 한방으로 사용할 수 있게 준비해 놓은 부지런한 무리들이 있다고 합니다. 

원래는 임베디드 시스템 등의 독립된 파일 시스템 구성을 위해 사용하는 툴이라는데 이것이 크로스 컴파일의 재료 공급용으로도 딱 제격입니다.

환경:  x86 이고 Ubuntu 20.04 LTS 에서 진행하였습니다.  Windows 10 에 있는 WSL2 환경입니다.
          Ubuntu 22.04 의 경우 올드버전의 buildroot 컴파일 시 문제가 생겨서 아래에 추가로 기록합니다.
 

-- make 중 다음 패키지가 없으면 에러가 나므로 미리 설치해 줍니다.
$ sudo apt install libncurses-dev unzip

-- https://buildroot.org/
-- Long Term Suuport 버전인 2023.02.7 을 다운받습니다.
$ wget https://buildroot.org/downloads/buildroot-2023.02.7.tar.gz
$ tar xvf buildroot-2023.02.7.tar.gz
$ cd buildroot-2023.02.7/

-- 옵션 선택은 아래 화면 참고
$ make menuconfig

$ make

 

$ make menuconfig 하면 다음과 같은 화면이 나옵니다. 언젠가 먼 옛날 보았던 커널 컴파일 화면과 비슷하군요..
(화면 캡춰 후에 stable 버전이 2023.02.7 버전으로 바뀌었군요.)

Target Option --->에서 Enter 를 눌러 들어가 적당한 architecture 를 골라줍니다.

이번에는 '라즈베리파이 3B - Ubuntu 64bit ' 에서 돌려볼 예정이므로 aarch64(little endian) 을 골라줍니다.

참고. 다음 명령어를 통해  cpu 종류와 endian 을 알 수 있습니다.

arm 이나 aarch64 나 둘다 little endian 이며 사실 i386 이나 x86_64 도 little endian 입니다.

-- 32bit 환경
pi@raspberrypi:~ $ lscpu
Architecture:                    armv7l
Byte Order:                      Little Endian
CPU(s):                          4
On-line CPU(s) list:             0-3
Thread(s) per core:              1
Core(s) per socket:              4
Socket(s):                       1
Vendor ID:                       ARM
Model:                           4
Model name:                      Cortex-A53

-- 64bit 환경
pi@raspberrypi:~$ lscpu
Architecture:                       aarch64
CPU op-mode(s):                     32-bit, 64-bit
Byte Order:                         Little Endian
CPU(s):                             4
On-line CPU(s) list:                0-3
Thread(s) per core:                 1
Core(s) per socket:                 4
Socket(s):                          1
Vendor ID:                          ARM
Model:                              4
Model name:                         Cortex-A53

 

ESC 를 두번 누르면 상위 메뉴로 나오게 됩니다.

Target packages---> 를 눌러서 Graphic libraries and application(graphic/text) ---> 를 골라줍니다.

 

여기서는 SDL 에 체크해 줍니다. 하위에 메뉴가 더 열리는데 우선은 체크하지 않았습니다. (원래 가이드 문서에서는 SDL_mixer 와 SDL_net 도 준비하라고 하는데 최근 진행하다보니 그냥 없이 해도 설치하는데 지장이 없더군요.)

ESC 를 눌러서 나오면 저장 여부를 물어보고 Yes 를 골라 저장하고 나옵니다.

make 진행....

$ make

 

WSL 환경이라 그런지 다음과 같은 에러가 발생했습니다. 일반 Ubuntu 에서는 발생하지 않습니다.

-- 참고. 다음 에러는 WSL 이라 나오는 듯 합니다. 일반 ubuntu 에서는 나지 않습니다.
Your PATH contains spaces, TABs, and/or newline (\n) characters.
This doesn't work. Fix you PATH.

--PATH 내용중 공백이 있어서라는데 지워주고 진행해도 다음과 같은 에러가 나며 진행이 안됩니다.
PATH=..중략 /usr/lib/wsl/lib:/mnt/c/Program Files/WindowsApps/CanonicalGroupLimited.Ubuntu_2204.2.33.0_x64__79rhkp1fndgsc:/mnt/c/Windows/system32:...


You seem to have the current working directory in your
PATH environment variable. This doesn't work.
make: *** [support/dependencies/dependencies.mk:27: dependencies] Error 1

-- PATH 중 Windows 가 들어간 부분은 다 제거하고 실행하니 됩니다.

 

중간중간 필요한 파일소스들을 다운받아 가면서  컴파일을 진행하는데 완료되는데까지 시간이 상당히 걸립니다. cpu 팬 돌아가는 소리가 엄청나게 들리는군요.

제 오래된 개발 노트북은 i7-2640M 이라서 1시간 좀 넘게 걸렸습니다. 최신 cpu 에서는 10~20분 정도면 컴파일 가능할 겁니다.

 

주요 디렉토리는 다음과 같습니다.

* ./buildroot-2023.02.7/output/build 

중간에 busybox-1.36.1 이 보이네요. 이것은 경량화된 리눅스 명령어들을 담고 있는 명령어 묶음입니다.

뒤에서 다시 언급하겠지만 glibc-2.36 버전이 사용되었군요. 우리가 선택한 SDL-1.2 도 보입니다.

multitab@MULTITAB-T420S:~/tmp/buildroot-2023.02.7/output/build$ ll
total 452
drwxr-xr-x 34 multitab multitab   4096 Nov 17 22:18 ./
drwxr-xr-x  6 multitab multitab   4096 Nov 17 22:18 ../
-rw-r--r--  1 multitab multitab  22740 Nov 17 22:18 build-time.log
drwxr-xr-x  4 multitab multitab   4096 Nov 17 21:09 buildroot-config/
drwxr-xr-x  3 multitab multitab   4096 Nov 17 22:18 buildroot-fs/
drwxr-xr-x 36 multitab multitab   4096 Nov 17 22:16 busybox-1.36.1/
drwxr-xr-x 69 multitab multitab   4096 Nov 17 21:49 glibc-2.36-118-g22955ad85186ee05834e47e665056148ca07699c/
drwxr-xr-x 14 multitab multitab   4096 Nov 17 21:13 host-acl-2.3.1/
drwxr-xr-x 14 multitab multitab   4096 Nov 17 21:12 host-attr-2.5.1/
drwxr-xr-x  9 multitab multitab   4096 Nov 17 22:17 host-autoconf-2.71/
drwxr-xr-x 11 multitab multitab   4096 Nov 17 22:17 host-automake-1.16.5/
drwxr-xr-x 19 multitab multitab   4096 Nov 17 21:17 host-binutils-2.38/
drwxr-xr-x 14 multitab multitab   4096 Nov 17 21:15 host-bison-3.8.2/
drwxr-xr-x  9 multitab multitab   4096 Nov 17 21:13 host-fakeroot-1.30.1/
drwxr-xr-x 16 multitab multitab   4096 Nov 17 21:15 host-gawk-5.2.0/
drwxr-xr-x 39 multitab multitab   4096 Nov 17 22:14 host-gcc-final-11.4.0/
drwxr-xr-x 39 multitab multitab   4096 Nov 17 21:33 host-gcc-initial-11.4.0/
drwxr-xr-x 16 multitab multitab   4096 Nov 17 21:17 host-gmp-6.2.1/
drwxr-xr-x  7 multitab multitab   4096 Nov 17 22:16 host-libtool-2.4.6/
drwxr-xr-x 11 multitab multitab   4096 Nov 17 21:14 host-m4-1.4.19/
drwxr-xr-x  2 multitab multitab   4096 Nov 17 21:13 host-makedevs/
drwxr-xr-x  8 multitab multitab   4096 Nov 17 21:18 host-mpc-1.2.1/
drwxr-xr-x  9 multitab multitab   4096 Nov 17 21:18 host-mpfr-4.1.1/
drwxr-xr-x  5 multitab multitab   4096 Nov 17 22:16 host-patchelf-0.13/
drwxr-xr-x  2 multitab multitab   4096 Nov 17 21:12 host-skeleton/
drwxr-xr-x  2 multitab multitab   4096 Nov 17 22:16 ifupdown-scripts/
drwxr-xr-x  2 multitab multitab   4096 Nov 17 22:16 initscripts/
drwxr-xr-x 26 multitab multitab   4096 Nov 17 21:34 linux-headers-6.1.62/
-rw-r--r--  1 multitab multitab     23 Nov 17 22:18 locales.nopurge
-rw-r--r--  1 multitab multitab 148800 Nov 17 22:18 packages-file-list-host.txt
-rw-r--r--  1 multitab multitab 107021 Nov 17 22:18 packages-file-list-staging.txt
-rw-r--r--  1 multitab multitab  17144 Nov 17 22:18 packages-file-list.txt
drwxr-xr-x 13 multitab multitab  12288 Nov 17 22:18 sdl-1.2.15/
drwxr-xr-x  2 multitab multitab   4096 Nov 17 21:33 skeleton/
drwxr-xr-x  2 multitab multitab   4096 Nov 17 21:33 skeleton-init-common/
drwxr-xr-x  2 multitab multitab   4096 Nov 17 21:33 skeleton-init-sysv/
drwxr-xr-x  2 multitab multitab   4096 Nov 17 22:14 toolchain/
drwxr-xr-x  2 multitab multitab   4096 Nov 17 22:14 toolchain-buildroot/
drwxr-xr-x  2 multitab multitab   4096 Nov 17 22:18 urandom-scripts/
multitab@MULTITAB-T420S:~/tmp/buildroot-2023.02.7/output/build$

 

* ./buildroot-2023.02.7/output/host/aarch64-buildroot-linux-gnu/sysroot

일반 리눅스의 디렉토리 구조와 유사하지 않습니까? 모든 디렉토리에 파일이 꽉 찬것은 아니지만 bin 디렉토리는 아까 위에서 설명한 Busybox 가 명령어를 채워주게 되고 /lib 에는 아까 위에서 말한 glibc 2.36 이 위치하고 있습니다.

/usr 부분에는 우리가 선택한 sdl-1.2 등이 위치하게 됩니다.

$ tree -d -L 2
.
├── bin
├── dev
├── etc
│   └── profile.d
├── lib
├── lib64 -> lib
├── media
├── mnt
├── opt
├── proc
├── root
├── run
│   └── lock
├── sbin
├── sys
├── tmp
├── usr
│   ├── bin
│   ├── include
│   ├── lib
│   ├── lib64 -> lib
│   ├── libexec
│   ├── sbin
│   └── share
└── var
    └── db

 

* ./buildroot-2023.02.7/output/images

이 디렉토리에는 rootfs.tar 라는 파일이 한개 생기는데 그 안을 열어 보면 위에서 만든 파일 시스템과 같습니다. 필요한 곳에 이 파일을 복사해 놓고 사용하는 모양입니다.

multitab@MULTITAB-T420S:~/tmp/buildroot-2023.02.7/output/images$ $ tar tvf rootfs.tar
...중략...
-rwsr-xr-x 0/0          821704 2023-11-17 23:57 ./bin/busybox
lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./bin/cat -> busybox
lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./bin/chattr -> busybox
lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./bin/chgrp -> busybox
lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./bin/chmod -> busybox
lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./bin/chown -> busybox
lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./bin/cp -> busybox
lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./bin/cpio -> busybox
lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./bin/date -> busybox
lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./bin/dd -> busybox
lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./bin/df -> busybox

lrwxrwxrwx 0/0               0 2023-11-15 04:50 ./dev/fd -> ../proc/self/fd
lrwxrwxrwx 0/0               0 2023-11-15 04:50 ./dev/log -> ../tmp/log

-rw-r--r-- 0/0              40 2023-11-17 23:57 ./etc/hosts
-rwxr-xr-x 0/0            1243 2023-11-17 23:57 ./etc/init.d/S01seedrng

-rwxr-xr-x 0/0          178168 2023-11-17 23:57 ./lib/ld-linux-aarch64.so.1
-rwxr-xr-x 0/0            5848 2023-11-17 23:57 ./lib/libanl.so.1
lrwxrwxrwx 0/0               0 2023-11-17 23:54 ./lib/libatomic.so -> libatomic.so.1.2.0
lrwxrwxrwx 0/0               0 2023-11-17 23:54 ./lib/libatomic.so.1 -> libatomic.so.1.2.0
-rwxr-xr-x 0/0           34808 2023-11-17 23:57 ./lib/libatomic.so.1.2.0
-rwxr-xr-x 0/0         1392848 2023-11-17 23:57 ./lib/libc.so.6
-rwxr-xr-x 0/0           30496 2023-11-17 23:57 ./lib/libcrypt.so.1
-rwxr-xr-x 0/0            5848 2023-11-17 23:57 ./lib/libdl.so.2
-rw-r--r-- 0/0             132 2023-11-17 23:54 ./lib/libgcc_s.so
-rw-r--r-- 0/0           75968 2023-11-17 23:57 ./lib/libgcc_s.so.1
-rwxr-xr-x 0/0          476968 2023-11-17 23:57 ./lib/libm.so.6

drwxr-xr-x 0/0               0 2023-11-15 04:50 ./media/
drwxr-xr-x 0/0               0 2023-11-15 04:50 ./mnt/
drwxr-xr-x 0/0               0 2023-11-15 04:50 ./opt/
drwxr-xr-x 0/0               0 2023-11-15 04:50 ./proc/
drwx------ 0/0               0 2023-11-15 04:50 ./root/
drwxr-xr-x 0/0               0 2023-11-17 23:57 ./run/

lrwxrwxrwx 0/0               0 2023-11-17 23:55 ./sbin/halt -> ../bin/busybox

대략적인 설명이 끝났으니 prboom 을 다시 컴파일해 봅시다.

 

2. 크로스 컴파일 재방송

환경:  x86 이고 Ubuntu 20.04 LTS 에서 진행하였습니다.  Windows 10 에 있는 WSL2 환경입니다. 

지난 과정에서 SDL 을 컴파일하는 부분은 Buildroot 가 대신했기 때문에 prboom 부터 진행합니다.

with-sdl-prefix 와 with-sdl-exec-prefix 부분을 이번에 만든 buildroot 의 경로로 수정해줍니다.

-- 다운 받고 압축을 풀어줍니다.
$ wget -O prboom-2.5.0.tar.gz https://sourceforge.net/projects/prboom/files/prboom%20stable/2.5.0/prboom-2.5.0.tar.gz/download
$ tar xvf prboom-2.5.0.tar.gz
$ cd prboom-2.5.0

-- 64bit
$ ./configure --prefix=$HOME/doom_prboom_br_aarch64 --disable-gl --without-net \
  --build=x86_64-pc-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu \
  --with-sdl-prefix=$HOME/tmp/buildroot-2023.02.7/output/host/aarch64-buildroot-linux-gnu/sysroot/usr \
  --with-sdl-exec-prefix=$HOME/tmp/buildroot-2023.02.7/output/host/aarch64-buildroot-linux-gnu/sysroot/usr

$ make
$ make install

 

prboom 64bit 컴파일 정보 추가합니다.

-- 64bit 로 진행시 알수 없는 넘이라고 오류를 내는데요.
checking host system type... Invalid configuration `aarch64-linux-gnu': machine `aarch64' not recognized
configure: error: /bin/bash autotools/config.sub aarch64-linux-gnu failed

-- prboom 의 config 파일 중 다음 부분을 수정해 줍니다.
-- arm 문구 뒤에 | aarch64 를 추가해 줍니다..
$ vi ./autotools/config.sub - 1608 라인에
 | arc | arm | aarch64 | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
 
 --이제 다시 configure 를 수행하면 올바르게 수행완료됩니다.

 

얼마간 컴파일 화면이 넘어가다가 다음과 같은 에러가 나옵니다. 1편에서 소개한 블로그에 해당 내용이 잘 나와 있습니다. 당황하지 말고 살짝 소스를 수정해 줍니다. 

-- 아마 다음과 같은 에러가 나올텐데 해당 라인은 주석으로 막아주면 됩니다. //

./../config.h:191:15: error: two or more data types in declaration specifiers
  191 | #define gid_t int
      |               ^~~
../../config.h:209:15: error: two or more data types in declaration specifiers
  209 | #define uid_t int

$ vi config.h
191 라인과 209 라인 // 으로 주석처리 후 다시 make.

-- 컴파일중 다음과 같은 에러가 발생했습니다. sdl 패키지로 컴파일시에는 나지 않던 에러군요.
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find /lib64/libc.so.6
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find /usr/lib64/libc_nonshared.a
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find /lib/ld-linux-aarch64.so.1

collect2: error: ld returned 1 exit status
make[3]: *** [Makefile:355: prboom] Error 1


-- 이것저것 해보느라 시간을 많이 허비했는데 아무래도 링크시에 / 경로로 부터 해당 라이브러리를 찾는 것으로 보입니다.
-- 좀 위험하긴 하지만 해당 파일의 링크를 걸어줍니다.
$ sudo ln -s /home/multitab/tmp/buildroot-2023.02.7/output/host/aarch64-buildroot-linux-gnu/sysroot/lib/libc.so.6 /lib64/libc.so.6
$ sudo ln -s /home/multitab/tmp/buildroot-2023.02.7/output/host/aarch64-buildroot-linux-gnu/sysroot/usr/lib/libc_nonshared.a /usr/lib64/libc_nonshared.a
$ sudo ln -s /home/multitab/tmp/buildroot-2023.02.7/output/host/aarch64-buildroot-linux-gnu/sysroot/lib/ld-linux-aarch64.so.1 /lib/ld-linux-aarch64.so.1

-- 다시 make 시작.
-- 컴파일 완료 이후 설치.
$ make install


-- 파일 확인...aarch 64bit 인것을 확인합니다.
$ file ~/doom_prboom_br_aarch64/games/*
/home/multitab/doom_prboom_br_aarch64/games/aarch64-linux-gnu-prboom:             ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=3e37c3b652239f1d3be2bde4291dfa721ae1ed80, for GNU/Linux 3.7.0, with debug_info, not stripped
/home/multitab/doom_prboom_br_aarch64/games/aarch64-linux-gnu-prboom-game-server: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=d93d9c1d49883c0a6f81224bfa69518d1f5d8731, for GNU/Linux 3.7.0, with debug_info, not stripped

-- wad 파일 복사하거나 다운받아 줍니다.
$ cd  ~/doom_prboom_br_aarch64/games/
$ wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad


-- 압축후 대상 시스템으로 전송
$ cd ~
$ tar cvfz doom_br64.tar.gz doom_prboom_br_aarch64
$ scp doom_br64.tar.gz pi@rasp:~/


라즈베리파이로 이동을 해서 압축을 풀고 실행을 해줍니다. 

-- 참고로 실행중인 라즈베리파이의 OS 는 Ubuntu 20.04 64bit 이며 glibc 는 2.31 입니다.
-- 대상 시스템으로 이동후 압축을 풀고 디렉토리 이동
$ tar xvf doom_br64.tar.gz
$ cd doom_prboom_br_aarch64/games/


-- 부푼 마음을 가지고 실행시켜 봅니다. 짜잔~
pi@raspberrypi:~/doom_prboom_br_aarch64/games$ ./aarch64-linux-gnu-prboom
./aarch64-linux-gnu-prboom: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./aarch64-linux-gnu-prboom)
./aarch64-linux-gnu-prboom: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by ./aarch64-linux-gnu-prboom)
pi@raspberrypi:~/doom_prboom_br_aarch64/games$

 

처음엔 컴파일을 한 시스템이 Ubuntu 22.04 라서 그런가 싶어서 이 과정을 ubuntu 20.04 에서 다시 진행하였습니다. buildroot 컴파일 1시간. 그런데 결과는 동일하더군요. 흠냐.

좀 더 확인해 보니 Ubuntu 22.04 의 GLIBC 버전은 2.35 입니다. 즉, 컴파일시키는 녀석의 환경과 상관 없이 Buildroot 시스템이 구축되면서 자체적인 glibc 버전(2023.02.7 버전은 glibc-2.36)을 다운 받아서 특정 버전으로 구성이 됩니다. 이전 버전들은 어떤가 하고 다운 받아서 구성해 보니 시간 순서대로 glibc 버전이 증가하고 있습니다 . 이게 어떻게 보면 장점이긴하겠지만 어떤 glibc 로 구성이 될지 알 수가 없어 좀 답답하군요. 

menuconfig 옵션중에 glibc 버전을 선택할 수 있는 옵션이 있으면 좋은데 불행히도 그런 기능은 없어 보입니다. (옵션중 toolchain 을 내장으로 할지 외장으로 할지가 있긴한데 이건 또 다른 문제...)

 

* 노가다로 직접 확인한 buildroot 별 GLIBC 버전 정리

buildroot 버전 glibc 버전 비고
buildroot-2019.02.9 glibc-2.28-133 이상 동일 할듯
buildroot-2020.02.1 glibc-2.30-20 이상 동일 할듯
buildroot-2020.08.1 glibc-2.31-54 ubuntu 22.04 버전에서 에러
buildroot-2021.02.9 glibc-2.32-50  
buildroot-2023.02.6 glibc-2.36-118  

https://buildroot.org/downloads/ Buildroot 의 이전 버전들은 여기에서 다운 받을 수 있습니다.

 

glibc 의 버전이 2.31-54 로 적당해 보이는 2020.08.1 버전을 다운 받아서 다시 컴파일을 합니다.

이전 버전들은 원래 glibc 가 아니고 경량버전인 uClibc-ng 가 선택되어 있네요. 위에서 선택한 값 외에 추가로  Toolchain 메뉴에서 glibc 로 변경해 줍니다.

 

저장하고 나와서 다시 make 를 실행해 줍니다. 다행히 무사히 컴파일 완료되었습니다. 

라즈베리파이로 보내고 실행을 해 봅니다. 왜인지는 모르겠는데 doom.wad 외에 prboom.wad 까지 모두 한 디렉토리에 넣어야 실행이 됩니다.

pi@raspberrypi:~/doom_prboom_br_aarch64/games$ ll
total 8716
drwxrwxr-x 2 pi pi    4096 Nov 28 12:31 ./
drwxrwxr-x 4 pi pi    4096 Nov 28 12:27 ../
-rwxr-xr-x 1 pi pi 4417808 Nov 28 12:27 aarch64-linux-gnu-prboom*
-rwxr-xr-x 1 pi pi   15344 Nov 28 12:27 aarch64-linux-gnu-prboom-game-server*
-rw-rw-r-- 1 pi pi 4196020 May 13  2010 doom1.wad
-rw-r--r-- 1 pi pi  281020 Nov 28 12:31 prboom.wad

 

사실 아래 화면을 보기까지 거의 2주일 정도의 시간이 소비되었습니다. ubuntu 22.04 에서 했던 것을 포기하고 20.04 에서 진행하면 큰 문제 없이 진행됩니다.

 

3. Ubuntu 22.04 이후 버전에서의 트러블 슈팅

환경:  x86 이고 Ubuntu 22.04 LTS 에서는 Buildroot 를 최근 버전으로 실행하면 문제가 없습니다. 하지만 타겟 시스템이 오래된 경우라면 부득이하게 이전 버전을 구해서 사용해야 할 수도 있습니다.

여기서는 그에 대한 트러블슈팅 기록을 남겨봅니다. 

-- Ubuntu 22.04 버전. GLIBC 2.35 

-- 문제 1. prboom 컴파일 1분여만에 다음과 같은 에러와 함께 중단되었습니다.
make[4]: Entering directory '/home/multitab/tmp/buildroot-2020.08.1/output/build/host-m4-1.4.18/lib'
  CC       gl_avltree_oset.o
  CC       binary-io.o
  CC       c-ctype.o
  CC       c-stack.o
  CC       c-strcasecmp.o
In file included from /usr/include/signal.h:328,
                 from ./signal.h:52,
                 from c-stack.c:49:
c-stack.c:55:26: error: missing binary operator before token "("
   55 | #elif HAVE_LIBSIGSEGV && SIGSTKSZ < 16384
      |                          ^~~~~~~~

-- m4-1.4.18 버전의 SIGSTKSZ 상수값이 glibc 2.34 이후버전에서는 문제가 있다고 합니다. ㅠㅠ
-- 어쨌든 다음에서 제공되는 패치파일을 통해 m4-1.4.19 로 설치를 진행할 수 있습니다.
-- 아래의 경로에 있는 m4.hash 와 m4.mk 파일을 github 의 것으로 교체해 주고 새로 진행하면 됩니다.

https://github.com/buildroot/buildroot/tree/master/package/m4

multitab@MULTITAB-T420S:~/tmp/buildroot-2020.08.1/package/m4$ pwd
/home/multitab/tmp/buildroot-2020.08.1/package/m4
multitab@MULTITAB-T420S:~/tmp/buildroot-2020.08.1/package/m4$ ll
total 84
drwxrwxr-x    2 multitab multitab  4096 Nov 27 23:07 ./
drwxrwxr-x 2414 multitab multitab 69632 Oct 12  2020 ../
-rw-rw-r--    1 multitab multitab   259 Nov 27 23:02 m4.hash
-rw-rw-r--    1 multitab multitab   343 Nov 27 23:01 m4.mk


-- 문제 2. 이후 또 다른 에러가 출현하였습니다. 
libfakeroot.c: In function ‘fremovexattr’:
libfakeroot.c:101:42: error: ‘_STAT_VER’ undeclared (first use in this function)
  101 | #define INT_NEXT_FSTAT(a,b) NEXT_FSTAT64(_STAT_VER,a,b)
...
make[4]: *** [Makefile:652: libfakeroot.lo] Error 1

-- 이것도 glibc 2.33 이후 _STAT_VER 값이 없어져서 생기는 문제라고 합니다.
-- 또 열심히 구글링을 해 줍니다. 다음 사이트에 있는 .bz 를 다운 받아 줍니다.
-- https://git.busybox.net/buildroot/commit/?id=f45925a951318e9e53bead80b363e004301adc6f
$ wget https://git.busybox.net/buildroot/snapshot/buildroot-f45925a951318e9e53bead80b363e004301adc6f.tar.bz2

-- 다른 곳에서 압축을 풀어준후 package/fakeroot 경로의 파일만 복사를 해 옵니다. 원래 있던 파일은 지워줍니다.
$ cd ~/tmp/buildroot-2020.08.1/package/fakeroot
$ rm *
$ cp ~/tmp/buildroot-f45925a951318e9e53bead80b363e004301adc6f/package/fakeroot/* .

 

마무리.

여기서는 Doom 을 크로스 컴파일하기 위한 중간 재료로 사용했지만 임베디드 시스템을 구성하시는 분들에게는 훨씬 더 유용하게 사용되는 것 같습니다. 

중간에 잠시 등장한 busybox 역시 경량화된 리눅스 시스템을 구성하는데 큰 도움이 된다고 합니다. 이것만 다운 받아서 사용하는 경우도 있습니다.

이전 크로스컴파일 글에서도 언급했지만 타겟 시스템의 GLIBC 를 확인하고 시작하는 것이 가장 중요해 보입니다.

멀고도 험했던 2주간의 삽질을 마치고 이후에는 GLIBC 의 버전이 다른 경우 해결을 위한 방법들에 대해 고민해 보기로 합니다.

 

추가 1.

ubuntu 20.04 에서 buildroot 2023.02.7 버전으로 다시 진행해 보는데 다음처럼 에러가 나오면서 진행이 막히네요. 현재로서는 ubuntu 20.04 에서는 buildroot 2020.08.1 버전으로는 잘 돌아 갑니다.

/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/lib/../lib/Scrt1.o: in function `_start':
(.text+0x20): undefined reference to `__libc_csu_init'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: (.text+0x24): undefined reference to `__libc_csu_init'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: (.text+0x28): undefined reference to `__libc_csu_fini'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: (.text+0x2c): undefined reference to `__libc_csu_fini'
collect2: error: ld returned 1 exit status

multitab@PRETTY-LOOPY:~/tmp/prboom-2.5.0$

 

추가 2. Buildroot 에서 바로 Doom 컴파일 하기

아무래도 주제가 Doom 이다보니..

Buildroot 의 항목중 Target 부분에 Games 항목이 있습니다. 여기에서 prboom 을 체크해 주면 buildroot 구성시 prboom 도 함께 컴파일해 줍니다. 위에는 chocolate-doom 도 있네요. 

 

이렇게 해서 나온 결과입니다. 다음 경로의 파일들을 복사하여 타겟으로 이동하면 위에서 수동으로 컴파일한 것과 동일하게 동작 합니다.

-- chocolate-doom 은 다음 경로에서 찾을 수 있습니다.
$ pwd
/home/multitab/tmp/buildroot-2020.08.1/output/target/usr/bin

$ ls chocolate-*
chocolate-doom        chocolate-heretic        chocolate-hexen        chocolate-server  chocolate-strife-setup
chocolate-doom-setup  chocolate-heretic-setup  chocolate-hexen-setup  chocolate-strife


-- prboom 은 다음 경로에서 찾을 수 있습니다.
$ pwd
/home/multitab/tmp/buildroot-2020.08.1/output/target

$ find . -name prboom*
./usr/share/games/doom/prboom.wad
./usr/games/prboom
./usr/games/prboom-game-server

-- 실행했을 때 관련 라이브러리가 없다고 에러를 내면 이것도 가져와서 연결을 해주거나 복사해 주면 됩니다.
$ ./chocolate-doom
./chocolate-doom: error while loading shared libraries: libSDL2_mixer-2.0.so.0: cannot open shared object file: No such file or directory

$ sudo ln -s /home/multitab/tmp/buildroot-2023.02.7/output/target/usr/lib/libSDL2_mixer-2.0.so.0 /lib/libSDL2_mixer-2.0.so.0
$ sudo ln -s /home/multitab/tmp/buildroot-2023.02.7/output/target/usr/lib/libSDL2_net-2.0.so.0 /lib/libSDL2_net-2.0.so.0

pi@raspberrypi:/lib$ ll
...중략...
lrwxrwxrwx  1 root root     40 Nov 28 23:26 libSDL2-2.0.so.0 -> /home/pi/target/usr/lib/libSDL2-2.0.so.0*
lrwxrwxrwx  1 root root     46 Nov 28 23:27 libSDL2_mixer-2.0.so.0 -> /home/pi/target/usr/lib/libSDL2_mixer-2.0.so.0*
lrwxrwxrwx  1 root root     44 Nov 28 23:27 libSDL2_net-2.0.so.0 -> /home/pi/target/usr/lib/libSDL2_net-2.0.so.0*
lrwxrwxrwx  1 root root     45 Nov 28 23:33 libSDL_mixer-1.2.so.0 -> /home/pi/target/usr/lib/libSDL_mixer-1.2.so.0*
lrwxrwxrwx  1 root root     43 Nov 28 23:32 libSDL_net-1.2.so.0 -> /home/pi/target/usr/lib/libSDL_net-1.2.so.0*

 

마무리 2 . 지금까지는 Linux OS 가 있는 대상들에 대한 작업이었는데요. 앞으로는 OS 가 없는 혹은 임베디드 OS 라고 불리우는 그런 타겟에 대해 둠을 넣기 위해 작업을 준비중입니다.

지금까지는 그냥 남들이 만들어 놓은 소스를 컴파일하는 것에 그쳤는데, 이후로는 어느정도 C 에 대해서 알고 작업을 해야 진행이 가능하겠더군요. 시간이 얼마나 걸릴지 모르겠지만 'ARM 환경에서 Doom 실행하기 4편' 으로 돌아오도록 하겠습니다.

반응형