u-boot 에뮬레이터로 hello world를 출력해 보는 글이 되겠습니다.
우선 이지부트 소스를 다운받아야 합니다.
$ wget http://forum.falinux.com/_zdownload/data/ezboot.x5.v18.tar.gz
$ tar -zxf ezboot.x5.v18.tar.gz
다운로드 후 압축을 풀면 'v18.org' 디렉토리가 생성될 것입니다.
디렉토리에 들어간 후 ls를 해보면 아래와 같은 디렉토리가 있을 것입니다.
여기서 사용할 폴더는 include, main 디렉토리 입니다.
따라서 이 두개를 따로 빼줍니다.
$ mkdir ~/navilnux
$ cp main/ ~/navilnux -r
$ cp include/ ~/navilnux -r
그 후 main 디렉토리에 있는 serial.c 파일을 수정해 줍니다.
19번째 줄 제거.
34번째 줄 제거.
64번째 줄 함수인 'void SerailInit( eBauds baudrate )' 부분 전부 제거. (64 ~ 114 line)
config.h 파일은 이지부트의 설정을 담고 있는 헤더 파일 입니다.
현재 책에서 진행하고 있는 나빌룩스는 해당 설정파일이 필요 없기 때문에 지워도 된다고 합니다.
수정이 완료되었으면 main.c 파일을 수정할 차례입니다.
다음과 같이 수정하면 됩니다.
$ mv main.c navilnux.c
$ vim navilnux.c
#include <pxa255.h>
#include <time.h>
#include <gpio.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
while(1){
printf("hello world!\n");
msleep(1000);
}
return 0;
}
※지금은 <pxa255.h> 경로를 따로 지정해주지 않아 gcc를해도 pxa255.h 파일을 찾을 수 없다고 나올 것입니다.
물론, -l 명령어로 해더파일을 동적으로 참조할 수 있지만 굳이 안해도 makefile을 통해 만들 것이니 신경 쓰지 마시기 바랍니다.
그 후 main, include 디렉토리에 있는 파일 중 다음 파일을 제외한 모든 파일을 제거해 주시기 바랍니다.
main
entry.S lib1funcs.S navilnux.c serial.c time.c gpio.c main-ld-script printf.c string.c vsprintf.c
include
gpio.h pxa255.h serial.h stdarg.h stdio.h string.h time.h
위 목록의 파일들을 제외한 모든 파일을 제거해 주세요.
제거가 완료되면 makefile을 만들 차례입니다.
Makefile
CC = arm-linux-gcc
LD = arm-linux-ld
OC = arm-linux-objcopy
CFLAGS = -nostdinc -I. -I../include
CFLAGS += -Wall -Wstrict-prototypes -Wno-trigraphs -O2
CFLAGS += -fno-strict-aliasing -fno-common -pipe -mapcs-32
CFLAGS += -mcpu=xscale -mshort-load-bytes -msoft-float -fno-builtin
LDFLAGS = -static -nostdlib -nostartfiles -nodefaultlibs -p -X -T ./main-ld-script
OCFLAGS = -O binary -R .note -R .comment -S
all: ~/navilnux/main/navilnux.c
$(CC) -c $(CFLAGS) -o entry.o entry.S
$(CC) -c $(CFLAGS) -o gpio.o gpio.c
$(CC) -c $(CFLAGS) -o time.o time.c
$(CC) -c $(CFLAGS) -o vsprintf.o vsprintf.c
$(CC) -c $(CFLAGS) -o printf.o printf.c
$(CC) -c $(CFLAGS) -o string.o string.c
$(CC) -c $(CFLAGS) -o serial.o serial.c
$(CC) -c $(CFLAGS) -o lib1funcs.o lib1funcs.S
$(CC) -c $(CFLAGS) -o navilnux.o navilnux.c
$(LD) $(LDFLAGS) -o navilnux_elf entry.o gpio.o time.o vsprintf.o printf.o string.o serial.o lib1funcs.o navilnux.o
$(OC) $(OCFLAGS) navilnux_elf navilnux_img
$(CC) -c $(CFLAGS) -o serial.o serial.c -D IN_GUMSTIX
$(LD) $(LDFLAGS) -o navilnux_gum_elf entry.o gpio.o time.o vsprintf.o printf.o string.o serial.o lib1funcs.o navilnux.o
$(OC) $(OCFLAGS) navilnux_gum_elf navilnux_gum_img
clean:
rm *.o
rm navilnux_elf
rm navilnux_img
rm navilnux_gum_elf
rm navilnux_gum_img
혹시 makefile을 만들기가 불편하시거나 어려우신 분들은 제 github에 makefile을 올려놨으니 받으시기 바랍니다.
$ git clone https://github.com/dnfwlq8054/navilnux_makefile.git
그리고 main/serial.c파일을 수정해 줘야 합니다.
serial.c
1
2
3
4
5
6
|
#ifdef IN_GUMSTIX
static volatile Word *UART = (volatile Word *) FFUART;
#else
static volatile Word *UART = (volatile Word *) STUART; // UART 베이스 어드레스
#endif
|
cs |
저기에 있는 'static volatile Word *UART = (volatile Word *) STUART' 부분에 STUART는
pxa255.h에 정의되어 있습니다.
이는 pxa255칩을 소프트웨어적으로 구현한 것인데 저기서 STUART는 보드간의 통신에 대한 코드 입니다.
이 부분까지 언급하면 내용이 길어지니 다음 글에서 설명하겠습니다.
다음으로 main/main-ld-script 파일을 수정해줘야 합니다.
해당 파일은 navilnux가 커널에 포팅될 때 커널 이미지의 시작 주소 값을 갖고 있는 파일로써 해당 파일을 수정하지 않으면
에뮬레이터로 실행이 되지 않습니다.(정확히는 커널이 실행되지 않습니다.)
6번 line을 보면 . = 0xA0F00800 이라고 되어 있습니다. 이것을 다음과 같이 바꿔줍니다.
. = 0xA0008000
여기까지 완료 되었다면 80%이상 하신 겁니다.
이제 makefile로 이미지 파일을 생성해 봅시다.
우선 위에서 작성한 makefile을 main 디렉토리로 옮겨줍니다.
navilnux$ mv Makefile main/
navilnux$ cd main
navilnux/main$ make
make가 성공적으로 되셨다면 navilnux_gum_img 파일이 생성되었을 것입니다.
이제 uImage를 만들어 봅시다.
이미지를 만들기 위해선 mkimage 프로그램이 있어야 하는데 앞서 u-boot설치 시 있던 mkimage를 사용합시다.
navilnux$ mkdir navilnuximg
navilnux$ cp ~/gumstix_uboot/tools/mkimage navilnuximg
//gumstix_uboot 파일은 제 home 디렉토리에 있어서 저렇게 경로를 설정한 것입니다.
navilnux$ cd navilnuximg
navilnux/navilnuximg$ cp ../main/navilnux_gum_img .
navilnux/navilnuximg$ cp ~/gumstix_uboot/flash.bin .
//현재 제가 사용하고 있는 운영체제는 64bit라 책에 있는 u-boot.bin이 아닌
flash.bin파일을 만들었기 때문에 이걸 사용합니다.
uImage 형식으로 변환
navilnux/navilnuximg$ ./mkimage -A arm -O linux -T kernel -C none -a a0008000 -e a0008000 -n 'Navilnux 0.0.0.1' -d navilnux_gum_img uImage
명령어 설명
-A : 어떤 아키텍쳐인지
-O : 어떤 OS인지
-T : 이미지가 어떤 종류인지
-C : 압축여부
-a : 로딩될 메모리 주소
-e : entry 포인트를 지정
-n : 메시지 입력
-d : 변환할 대상 이미지 파일
자.... 이제 램 디스크 이미지를 만든 후 에뮬레이터로 실행시키면 끝납니다.!!!
램 디스크를 만들기 전 'mtd-utils' 패키지를 설치해 주세요.
※ Memory Technology Device(MTD)의 약자로 하드웨어와 운영체제 사이에서 인터페이스 역할을 해주는 녀석입니다.
jffs2파일 이미지를 만들때도 해당 기능을 제공해 주고 있습니다.
$ sudo apt-get install mtd-utils
navilnux/navilnuximg$ mkdir navilnuxkernel
navilnux/navilnuximg$ mkdir navilnuxkernel/boot
navilnux/navilnuximg$ mv uImage navilnuxkernel/boot
navilnux/navilnuximg$ mkfs.jffs2 -e 0x20000 -d navilnuxkernel/ -p -o navilnux.jffs2
navilnux/navilnuximg$ dd of=navilnuximg bs=1k conv=notrunc seek=180 if=navilnux.jffs2
//새로 만들 navlinuximg파일에 램 디스크로 만든 navlinux.jffs를 붙여줍니다.
단, 바이트를 180만큼 건너 뛰고 출력을 시작합니다. 왜 180만큼 뛰는지는 저도 잘 모르겠습니다....
navilnux/navilnuximg$ qemu-system-arm -M connex -pflash navilnuximg -nographic
고생하셨습니다.!!!!
이제 에뮬레이터로 hello world를 출력하는 것 까지 완료한 것입니다.!! ^^
P.S
앞으로 navilnux.c 파일을 수정하면서 위 과정대로 명령어를 쳐가면서 컴파일 해야할 겁니다.
그래서 .sh파일을 만들어 좀 더 편하게 컴파일을 할 수 있습니다.
만들어서 제 github에 올려놨으니 받으실 분들은 받으시기 바랍니다.
navilnux/navilnuximg$ git clone https://github.com/dnfwlq8054/navilnux_sh.git
반드시 navilnux/navilnuximg 경로에서 실행해 주시기 바랍니다.
'프로그래밍 > Embeded' 카테고리의 다른 글
Embedded] Exception Vector table (0) | 2019.09.08 |
---|---|
도전 임베디드 OS 만들기 - qemu, u-boot 설치(Ubuntu 18.04 64bit ver) (0) | 2019.08.27 |
크로스 컴파일러란? 크로스 컴파일러 설치 방법!! (도전 임베디드 OS 만들기) (0) | 2019.08.22 |
Embedded] MCU와 SoC의 개념과 차이점은? (0) | 2019.08.08 |
Embeded] ARM이란? (0) | 2019.08.08 |
댓글