-
임베디드 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
를 사용했다. 이부분에서 에러가 많이 나는 것을 보았다. 아래 참조의 글들을 참고하면 좋을듯하다
지금까지 정리해보자
지금까지의 과정을 생성부터 실행이라고 본다.
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. 개발 매커니즘이 참 비슷함.
웹이든, 임베디드든,
쉽게 작성하고 직관적으로 실행하려는 욕심?이 참 유사하다는 것이 신기했다.
참고자료
'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