임베디드

FoxNux용 u-boot 빌드와 설치

FoxNux 2019. 12. 19. 18:50

타겟 보드의 RAM 용량이 크고 CPU가 빠르고 Debian 계열의 OS가 설치되어 있다면 보드에서 직접 컴파일(Native build)을 하는 경우가 많아 졌다.

그런데 FoxNux 보드는 CPU가 느린편이고 RAM 공간이 128MB 뿐이라 어려울 것이다.

쓸데없는 고생하지 말고 PC에서 Cross-toolchain을 이용하여 컴파일을 하자.

 

내가 사용하는 개발 PC는  x86-64bit용 Ubuntu 19.10이 동작하고 있다. 

작년 여름에 18.04를 설치하였고 6개월마다 업그레이드를 하였더니 19.10되었다.

업그레이드 할때마다 자잘한 문제가 있었으나 6~7년전에 부팅조차 망가지던 것에 비하면 애교로 보인다.

내년에 20.04 LTS로 올리고나면  Major 업그레이드 없이 자잘한 update만으로 2년 정도 유지해볼 계획이다.

 

1년 6개월 가까이 MS-Windows 없이 살아가고 있는데 내가봐도 신기하다. 이런날이 올지는 정말 몰랐다.

PCB 설계 툴 KiCad도 Ubuntu에서 잘 돌아가고, 금융거래는 스마트폰으로 하니 리눅스 컴퓨터 만으로도 살아갈 수 있다.

 

예전에 임베디드 리눅스 입문 과정을 보면 윈도우 컴퓨터에 VMware나 VirtualBox 같은 가상화 프로그램을 깔고, 그 위에 리눅스로 게스트 OS 깔고, Samba 나 Shared로 두개의 OS 사이에 파일 연결 고리만드느라 시간을 소모하였다.

세상이 많이 변했다. 리눅스가 아주 쓸만해졌다.

MS가 Visual Studio 코드 편집기를 무료로 풀어서 코딩 환경이 좋아졌다. 필수 명령어 20여개만 외우면 어느 시스템에서나 사용가능한 vim 에디터도 어느 정도 익숙해 졌다. 유료 프로그램이기는 하지만 UltraEdit도 리눅스에서 잘 돌아간다.

 

임베디드 리눅스 개발자는 리눅스 PC 사용과 문제해결에 익숙해지면 절대 손해볼 일이 없음을 잊지 말자.

 

서론이 무지 길었다. 닥치고 컴파일이나 한번 해보자.

모든 과정은 command terminal에서 하고, root 권한 사용이 거의 없도록 노력해 보자.

작업 폴더를 만들고 64비트 x86 리눅스 컴퓨터에서 동작하는 ARM용 크로스 컴파일러를 다운로드 받자.

아래 명령어를 실행하면 내 home 폴더에 다운로드 받은 툴체인의 압축해제까지 끝난다.

 

cd ~
mkdir crosstool
cd crosstool
wget https://releases.linaro.org/components/toolchain/binaries/latest/arm-linux-gnueabihf/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf.tar.xz
tar xvf gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf.tar.xz

 

홈폴더의 .bashrc 파일 수정하여 설치한 컴파일러의 경로를 실행 PATH에 추가하여 어느 폴더에서나 컴파일할 수 있도록 변경한다.

vi나 nano 또는 본인이 익숙한 text editor로 수정한다.

nano ~/.bashrc

맨 하단에 아래와 같이 한줄 추가하고 저장한다.

PATH="$PATH:~/crosstool/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin"

exit 명령으로 터미널을 닫고 다시 터미널을 열어 아래와 같이 경로 설정에 문제가 없는지 확인해 본다.

$ arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (Linaro GCC 6.3-2017.05) 6.3.1 20170404
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 

FoxNux용 u-boot 소스코드는 내가 관리하는 Github 저장소에서 받는다.

V3s용 u-boot 코드를 얻어서(Fork 하여) DDR3 설정 부분과 LCD 해상도 관련 부분을 주로 수정하여 i3에 맞게 포팅하였다.

 

먼저 필요한 패키지를 설치해야 한다. 추후에 커널 빌드할때 필요한 패키지까지 한번에 설치해 보자.

몇가지 빠진것이 있을수도 있다. 나중에 OS를 새로 설치한 상태에서 검증해 보겠으나 언제가 될지는 모르겠다.

sudo apt install git gcc g++ build-essential libssl-dev bc device-tree-compiler

 

소스코드를 받고 빌드하는 명령어 들이다.

마지막 빌드 명령을 실행하기전에 설정값을 확인/변경을 하려면 "make ARCH=arm menuconfig"를 입력하면 된다.

git clone https://github.com/foxnux/u-boot.git -b s3-foxnux
cd u-boot
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- foxnux_S3_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4

컴파일과 링크가 문제없이 끝나면  'u-boot'과 'u-boot-sunxi-with-spl' binary(.bin) 파일이 생성된다. 

아래와 같은 명령어로 SPL까지 포함된 u-boot 바이너리를 SD카드의 시작점의 8KB 뒷부분에 기록한다.

sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8
sync
sync

sdX의 "X"는 SD카드의 장치 노드 이름이다. "cat /proc/partitions" 명령으로 확인 후 기록하길 바란다.

 

부트로더를 기록한 SD 카드를 FoxNux 보드에 꼽고 전원을 키면 LCD에 리눅스 로고가 보이고 시리얼 콘솔에는 아래와 같이 나오면 정상이다.

U-Boot SPL 2017.01-rc2-00076-g677f793d4b-dirty (Dec 14 2019 - 18:41:13)
DRAM: 128 MiB
Trying to boot from MMC1

U-Boot 2017.01-rc2-00076-g677f793d4b-dirty (Dec 14 2019 - 18:41:13 +0900) Allwinner Technology

CPU:   Allwinner S3/V3s (SUN8I 1681)
Model: FoxNux One
DRAM:  128 MiB
MMC:   SUNXI SD/MMC: 0
Setting up a 1024x600 lcd console (overscan 0x0)
dotclock: 51000kHz = 51000kHz: (1 * 3MHz * 102) / 6
In:    serial@01c28000
Out:   serial@01c28000
Err:   serial@01c28000


U-Boot 2017.01-rc2-00076-g677f793d4b-dirty (Dec 14 2019 - 18:41:13 +0900) Allwinner Technology

CPU:   Allwinner S3/V3s (SUN8I 1681)                                                                                                        
Model: FoxNux One                                                                                                                           
DRAM:  128 MiB                                                                                                                              
MMC:   SUNXI SD/MMC: 0                                                                                                                      
Setting up a 1024x600 lcd console (overscan 0x0)                                                                                            
dotclock: 51000kHz = 51000kHz: (1 * 3MHz * 102) / 6                                                                                         
In:    serial@01c28000                                                                                                                      
Out:   serial@01c28000                                                                                                                      
Err:   serial@01c28000                                                                                                                      
Net:   No ethernet found.                                                                                                                   
starting USB...                                                                                                                             
No controllers found                                                                                                                        
Hit any key to stop autoboot:  0 

 

아직 u-boot에서 Ethernet 드라이버가 올라오지 않는다. TFTP 기능을 위해서 꼭 해결할 문제다.

http://zero.lichee.pro/%E9%A9%B1%E5%8A%A8/Ethernet.html

조만간 해당 드라이버 추가해서 github 코드에 반영할 예정이다. 수정할 부분이 간단하면 좋겠다.

 

LCD 해상도와 프레임버퍼 사이즈와의 관계와 코드 변경 포인트를 기록해 보았다.

LCD Framebuffer의 메모리 할당 크기는 해상도에 4바이트(unpacked RGB-888) 곱해서 계산한다.

해상도 별로 필요한 메모리는 다음과 같다.
* 800x480x4 = 1.5M 

* 800x600x4 = 1.8M 

* 1024x600x4 = 2.4M 

* 1024x768x4 = 3M 

u-boot의 기본 FB 크기 설정은 2MB이므로 1024x600 이상의 LCD는 정상 동작하지 않는다.
그래서 uboot 코드의 "u-boot/include/configs/sunxi-common.h 파일의 309번째 라인을 아래와 같이 수정해서 4MB가 할당되도록 변경했다.

Before
#define CONFIG_SUNXI_MAX_FB_SIZE (2 << 20)

After
#define CONFIG_SUNXI_MAX_FB_SIZE (3 << 20)

그리고 1024x600 LCD에 맞는 TCON 타이밍 설정값도 config 파일에 적용하였다.

CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:51000,le:159,ri:160,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0"

 

u-boot 은 부팅 후 boot.scr이라는 스크립트를 자동으로 실행하는데, 보통은 이 스크립트 내부에 리눅스 커널과 디바이스 트리 파일을 로딩하고 커널을 기동하는지를 기록한다.

boot.cmd라는 텍스트 파일을 만들어 아래와 같이 작성했다.

setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=10 earlyprintk rw
load mmc 0:1 0x41000000 zImage
load mmc 0:1 0x41800000 sun8i-s3-foxnux-one.dtb
bootz 0x41000000 - 0x41800000

스크립트는 mkimage라는 유틸을 이용해서 text파일을 scr 포맷으로 변경하여야 한다.

아래 명령어를 실행하면 u-boot이 인식하여 실행이 가능한 boot.scr 파일이 생성되며, 이 파일은 커널 이미지와 디바이스 트리 파일과 함께 저장장치의 Boot partition에 넣어주어야 한다.

mkimage -C none -A arm -T script -d boo.com boot.scr