-
임베디드 OS개발 CH3Share/OS 2021. 2. 20. 14:58
이만우 선생님의 "임베디드 OS개발 프로젝트" 를 기반으로 작성하였으며,
학습목적으로 작성한 것이며, 자세한 내용을 모두 기술하진 않았습니다.ch2
설치는 책을 보고...^^
서론
기본개념이 필요하다
- 컴파일
- Linker
- Makefile 역할
- 레지스터 등
목적
대목적: OS를 만들어보자
이번챕터 #CH3의 목적 :
- Entry.S를 만들고,링커 스크립트를 작성하자
- makefile을 만드는 방법과 qemu를 통한 gdb 를 사용했을때, 레지스터 변화를 살펴보고 깨닫자.
- gdb 사용방법을 익히고, 펌웨어개발 기본을 파악한다.
일단 시작
$mkdir boot
일단 작성하는 Entry.S
.text .code 32 .global vector_start .global vector_end vector_start: LDR R0, R1 vector_end: .space 1024, 0 .end
여기서 주의하게 볼 것은
vector_start 부분이다
ARM 이라는 하드웨어안에 많은 "레지스터" 가 있을 것이다.
그 레지스터에 이름이 R0, R1, R2, 이런식으로 이름을 붙여놨다. (ARM 회사가 )
ARM 레지스터에 대한 자세한 내용은 Google로 더 쌓아가기
Entry.S를 일단 작성은 했는데... 그래서 뭐.... what ?!
이 코드를 "컴파일" 해서 "바이너리 덤프"를 만들자.
/boot$ arm-none-eabi-as -march=armv7-a -mcpu=cortex-a8 -o Entry.o ./Entry.S /boot$ arm-none-eabi-objcopy -O binary Entry.o Entry.bin /boot$ ls Entry.bin Entry.o Entry.S /boot$ hexdump Entry.bin 0000000 0001 e1a0 0000 0000 0000 0000 0000 0000 0000010 0000 0000 0000 0000 0000 0000 0000 0000 * 0000404
- arm-none-eabi-as 라는 ARM용 어셈블러
- 대략, 첫줄만 보고 예상할 수 있는 것은 cortex-a8 arm 코어를 사용할 것이고~ 아키텍쳐는 armv7-a를 사용하겟다~~등등 그리고 object 파일은 어떻게 뽑아라~ 라는 명령
어찌되었던, 실행 파일 만들자
"QEMU가 펌웨어 파일을 읽어서 부팅하려면 입력으로 지정한 펌웨어 바이너리 파일이 ELF 파일 형식이어야 한다"
ELF : 리눅스의 표준 실행 파일 형식.
링커가 동작하려면 링커에 정보를 던져주는 파일이 필요한데, 이것이 바로 "링커 스크립트"
계속해서 나오는 개념들 단어들 에 대한 의미를 구글링하고 찾아가면서 책을보는 것을 추천한다.
그래야 booting 되는 과정에서 코드들이 컴파일되고 링킹되는 과정과 메모리가 바뀌는 부분들을 더 깊게 이해할 수 있다.
navilos.ld
ENTRY(vector_start) SECTIONS { . = 0x0; .text : { *(vector_start) *(.text .rodata) } .data : { *(.data) } .bss : { *(.bss) } }
QEMU 사용
QEMU는 하드웨어 가상머신/Emulator 이라고 생각한다.
보통 우분투나 다른 OS를 윈도우에서 VM를 쓰듯이...
개발할때 구조는 쉽게 표현하면 이렇다.
한 터미널에서 qemu를 생성하여 서버를 열고
다른 한 터미널에서 gdb를 이용해서 그 서버에 접속하는 방식이다
처음시작할때는 이 구조가 어떤지 조차 몰라서, 터미널을 어떻게 켜야되고 어떻게 어디서 명령을 실행해야되는 것 조차 헷갈릴 수 있다.
QEMU를 통해서 지금까지 작성햇던 boot , linking에 필요한 코드들을 실행한다,
$ qemu-system-arm -M realview-pb-a8 -kernel navilos.axf -S -gdb tcp::1234,ipv4 VNC server running on 127.0.0.1:5900
혹시나 같은 주소로 열었다면, 안열리니 주의 !
저 상태는 qemu를 통해서 실행이 되었고 서버를 열어놨다는 뜻이니,
터미널2, 하나 더 만들어서 저기에 연결을 시도하자.
(gdb말고도 다른 것들이많은데 일단 책 따라 이것을 쓰자)
*책에서는
arm-none-eabi-gdb를 사용했으나,
환경문제로인해(우분투 18.04 및 VM 사용)
gdb-multiarch
를 사용했다. 이부분에서 에러가 많이 나는 것을 보았다. 아래 참조의 글들을 참고하면 좋을듯하다
qemu <----> gdb 연결 지금까지 정리해보자
지금까지의 과정을 생성부터 실행이라고 본다.
1.파일을 생성하고,
2. 그것을 실행하기 위해서는 컴파일 하고 가상머신안에서 돌려야 되고 빌드 등등의 일련의 작업이 했다.
Makefile을 통해 빌드를 자동화 하자
*자세한 설명은 책 참고
참고로 작성시 Tab으로 초기 칸을 띄어야 한다는 것 !
Makefile
makefile 작성도 책 참조...
*뜬금없는 이야기지만,
명령어를 써서 하는 이런 느낌?이 웹개발시 nodejs npm환경설정하는 것도 그렇고, front와 연동할때 많이 쓰이는 웹팩같은 환경설정과 유사하네..
무튼
makefile을 만든 이후에는
#terminal1
make
make debug
#terminal2
make gdb
#물리자~
(gdb) target remote:1234
(gdb) file build/navilos.axf
디버깅을 시작할 수 있다.
느낀점
1. 하드웨어 기본개념/ 용어에 대한 깊은 이해의 필요성
CH3의 내용을 한줄 요약하자면 ,
작성 - 컴파일 -링킹 - 빌드 - 설치 - 실행
인데, 이과정속에서 컴파일러를 다운받고,
컴파일러를 통해서 오브젝트 파일을 링커에 물리고
실행 하는 과정
Makefile 을 이용해서 더욱 간편하게 자동화 빌드환경을 구축하는 것을 한것이다.
한줄이 좀 길었지만, 이렇다고 본다.
여기서 중요한것은, 한줄한줄을 따라하는 것도 중요하고,
그 각개념이 어떻게 무엇을 하는것인지 대강 감을 잡아야 할것같다.
왜냐면 이것이 GUI기반으로 추후 개발을 하는 과정에 있어서도,
porting을 한다거나 하는 경우에 어느 과정에서 어떻게 적용시켜야될지를 알아야 하기때문이다
2. 커널 디버깅이란 무엇인가
난 커널 디버깅이라는게, 커널은 계속 "스스로" 돌아가는 와중에
내가 잡은 breakpoint에서 멈추고 결과를 보는 것으로 생각했는데,
이번과정을 통해서 생각이 조금 바뀌었다.
커널을 스스로 돌아가는 어떠한 프로그램이 아니라,
내가 "구동"을 시키면서 메모리변화 (추후에는 여러 I/O가 되겠지?) 를 보는 것이구나.
를 깨닫게 되었음.
3. 개발 매커니즘이 참 비슷함.
웹이든, 임베디드든,
쉽게 작성하고 직관적으로 실행하려는 욕심?이 참 유사하다는 것이 신기했다.
참고자료
펌웨어 RTOS 책을 썼습니다. | KLDP
10년만에 책을 한 권 썼습니다. 10년전에 KLDP에 쓴 글을 바탕으로 책을 냈었습니다. 이 책이죠. 아직도 절판되지 않고 팔리고 있습니다. 10년동안 꾸준히 일정 권수만큼 매년 팔리는 것 보면 아마
kldp.org
'Share > OS' 카테고리의 다른 글
[error] apt-get update 에러 , apt install net-tools 설치 에러, could not get lock /var/lib/dpkg/lock (2) 2021.11.23 VirtualBox 해상도 및 복사붙여넣기 에러 (could not get lock dpkg ) dpkg 오류 (0) 2021.10.01 임베디드 OS 개발 [8,9,10장] 요약 (0) 2021.03.27 임베디드 OS 개발 [5장] (0) 2021.03.06 임베디드 OS 개발프로젝트 [4장] (0) 2021.03.03