
์์ํ๊ธฐ ์
์ฑ ์์ ์ฌ์ฉํ๋ ์์ค ์ฝ๋๋ค์ ํด๋น ๋ ํฌ์งํ ๋ฆฌ์์ ์ดํด๋ณผ ์ ์์ต๋๋ค.
๊นํ๋ธ ๋ ํฌ์งํ ๋ฆฌ ๋งํฌ
3.1 ๋ฆฌ์ ๋ฒกํฐ
ARM ์ฝ์ด์ ์ ์์ด ๋ค์ด๊ฐ๋ฉด ๋ฆฌ์ ๋ฒกํฐ์ ์๋ ๋ช ๋ น์ ๋จผ์ ์คํ์ํต๋๋ค.
๋ฆฌ์ ๋ฒกํฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ 0x00000000์ ๋๋ค.
Entry.S ์์ค ์ฝ๋
.text
.code 32
.global vector_start
.global vector_end
vector_start:
MOV R0, R1
vector_end:
.space 1024, 0
.end
.text ์น์ ์ ์ ์ํ๋ค .code 32๋ ํ ๋ช ๋ น์ด์ ํฌ๊ธฐ๊ฐ 32bits = 4Bytes์์ ์๋ฏธํ๋ค. .global ์ง์์ด๋ C์ extern๊ณผ ๋์ผํ๋ฉฐ ์ ์ญ๋ณ์๋ฅผ ์๋ฏธํ๋ค. vector_start ๋ ์ด๋ธ์์๋ R1์ ๊ฐ์ R0๋ก ์ฎ๊ธฐ๋ ์์ ์ ์ํํ๋ค. vector_end ๋ ์ด๋ธ์์๋ ํ์ฌ ์์น๋ก๋ถํฐ 1,024bytes๋ฅผ 0์ผ๋ก ์ฑ์ฐ๋ ์์ ์ ์ํํ๋ค.
Entry.S ํ์ผ์ ์ปดํ์ผํ๊ณ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋คํํด๋ดค์ต๋๋ค.
arm-none-eabi-as -march=armv7-a -mcpu=cortex-a8 -o Entry.o ./Entry.S
arm-none-eabi-objcopy -O binary Entry.o Entry.bin
hexdump Entry.bin
0001 e1a0์ด ๋ณด์ ๋๋ค.
์์ํ ๋๋ก ์ ๋๋ก ๋ฐ์ด๋๋ฆฌ ํ์ผ์ด ์์ฑ๋์ต๋๋ค.
3.2 ์คํ ํ์ผ ๋ง๋ค๊ธฐ
QEMU๊ฐ ํ์จ์ด ํ์ผ์ ์ฝ์ด์ ๋ถํ ํ๋ ค๋ฉด ์ง์ ํ ํ์จ์ด ๋ฐ์ด๋๋ฆฌ ํ์ผ์ด ELF ํ์ผ ํ์์ด์ฌ์ผ ํฉ๋๋ค.
arm-none-eabi-as๋ฅผ ์ด์ฉํ์ฌ ์์ฑํ Entry.o ํ์ผ์ด ELF ํ์ผ์ ๋๋ค.
ELF ํ์ผ์ ๋ง๋ค๋ ค๋ฉด ๋ง์ปค์ ๋์์ด ํ์ํฉ๋๋ค.
๋ง์ปค๊ฐ ๋์ํ๋ ค๋ฉด ๋ง์ปค ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
(๋ณดํต ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ๋๋ ์ ๊ฒฝ์ฐ์ง ์์ง๋ง, ํ์จ์ด๋ฅผ ๊ฐ๋ฐํ ๋๋ ๋ค๋ฅด๋ค๊ณ ํฉ๋๋ค.)
navilos.ld ์์ค์ฝ๋
ENTRY(vector_start)
SECTIONS
{
. = 0x0;
.text :
{
*(vector_start)
*(.text .rodata)
}
.data :
{
*(.data)
}
.bss :
{
*(.bss)
}
}
์๋ ๋ช ๋ น์ด๋ฅผ ์ด์ฉํ์ฌ ์คํ ํ์ผ์ ๋ง๋ค์ด์ค๋๋ค.
arm-none-eabi-ld -n -T ./navilos.ld -o navilos.axf boot/Entry.o
arm-none-eabi-objdump ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ํ์ผ์ด ์ด๋ค ๋ช ๋ น์ด๋ก ๊ตฌ์ฑ๋์ด ์๋์ง ํ์ธํด๋ดค์ต๋๋ค. ๋์ค์ด์ ๋ธํ ๊ฒฐ๊ณผ๋ฅผ ์ดํด๋ณด๋ฉด mov r0, r1 ๋ช ๋ น์ด๊ฐ ์ ๋ฐฐ์น๋์ด ์์ต๋๋ค.

3.3 QEMU์์ ์คํํด๋ณด๊ธฐ
์คํ ํ์ผ์ ๋ง๋ค์ด๋ดค์ง๋ง ํฐ๋ฏธ๋์์ ์คํ์ํค๋ ค ์๋ํด๋ณด๋ฉด ์ ๋ฉ๋๋ค.
ARM ๊ฐ๋ฐ ๋ณด๋์ ๋ค์ด๋ก๋ ์์ผ์ ๋์์ ํ์ธํ๊ฑฐ๋ QEMU๋ก ์คํํด๋ณด๋ฉด ๋ฉ๋๋ค.
qemu-system-arm -M realview-pb-a8 -kernel navilos.axf -S gdb tcp::1234, ipv4
์ค์ต์ ํ๋ ๋์ค ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
arm-none-eabi-gdb ํ์ผ์ด ์ด๋์๋์ง ์ฐพ์ ์๊ฐ ์๋ค๊ณ ํฉ๋๋ค.

askubuntu ์ฌ์ดํธ์์ ์ ๋ ๊ฐ์ ๋ฌธ์ ๋ฅผ ๊ฒช์ ์ฌ๋๋ค์ ์ฐพ์๋ดค๊ณ ์ค์ ๋ก ์กด์ฌํ์ต๋๋ค.
๋ด์ฉ์ ์ดํด๋ณด๋, gdb-multiarch ํจํค์ง๋ฅผ ์ค์นํ๋ ๊ฒ์ ์ถ์ฒํ๋ ๋ต๋ณ์ด ์์์ต๋๋ค.
sudo apt-get update
sudo apt-get install gdb-multiarch
์ ๋์ํ๋ ๊ฒ์ ๋ณด์, ์ค์ต์ ์งํํ๋ ๋ฐ ๋ฑํ ๋ฌธ์ ๋ ์์ด๋ณด์ ๋๋ค.
gdb-multiarch

3.4 ๋น๋ ์๋ํํ๊ธฐ
์ผ๋จ make์ ๊ด๋ จ๋ ํจํค์ง๋ค์ ์ค์นํ์ต๋๋ค.
sudo apt-get install make
Makefile์ ๋ง๋ค์ด์ ๋น๋๋ฅผ ์๋ํํด๋ดค์ต๋๋ค.
์ฑ ์์ ๋์จ ์ฝ๋์ ์กฐ๊ธ ๋ฌ๋ผ์ง ์ ์ด ์กด์ฌํฉ๋๋ค.
# ํ๊ฒ ์ํคํ
์ฒ์ CPU๋ฅผ ์ง์ ํฉ๋๋ค.
ARCH = armv7-a
MCPU = cortex-a8
# GNU ARM Embedded Toolchain์ ๋๊ตฌ๋ค์ ์ง์ ํฉ๋๋ค.
CC = arm-none-eabi-gcc
AS = arm-none-eabi-as
LD = arm-none-eabi-ld
OC = arm-none-eabi-objcopy
# ๋ง์ปค ์คํฌ๋ฆฝํธ ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ์ง์ ํฉ๋๋ค.
LINKER_SCRIPT = ./navilos.ld
# boot ๋๋ ํ ๋ฆฌ ๋ด์ ๋ชจ๋ ์ด์
๋ธ๋ฆฌ ์์ค ํ์ผ๋ค์ ์ฐพ์ต๋๋ค.
ASM_SRCS = $(wildcard boot/\*.S)
# ์ด์
๋ธ๋ฆฌ ์์ค ํ์ผ๋ค์ ๋์ํ๋ ์ค๋ธ์ ํธ ํ์ผ ๊ฒฝ๋ก๋ก ๋ณํํฉ๋๋ค.
ASM_OBJS = $(patsubst boot/%.S, build/%.o, $(ASM_SRCS))
# ์ต์ข
์์ฑ๋ ์คํ ํ์ผ๊ณผ ๋ฐ์ด๋๋ฆฌ ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ์ง์ ํฉ๋๋ค.
navilos = build/navilos.axf
navilos_bin = build/navilos.bin
# ์ค์ ํ์ผ๊ณผ ๊ด๋ จ์ด ์๋ ํ๊ฒ๋ค์ ์ง์ ํฉ๋๋ค.
.PHONY: all clean run debug gdb
# ๊ธฐ๋ณธ ํ๊ฒ์ผ๋ก, navilos ์คํ ํ์ผ์ ์์ฑํฉ๋๋ค.
all: $(navilos)
# ๋น๋ ๊ณผ์ ์์ ์์ฑ๋ ํ์ผ๋ค์ ์ ๋ฆฌํฉ๋๋ค.
clean:
@rm -fr build
# QEMU ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๋ ์ปค๋์ ์คํํฉ๋๋ค.
run: $(navilos)
qemu-system-arm -M realview-pb-a8 -kernel $(navilos)
# ๋๋ฒ๊น
๋ชจ๋์์ QEMU๋ฅผ ์ฌ์ฉํ์ฌ ์ปค๋์ ์คํํฉ๋๋ค.
# GDB ์๋ฒ๊ฐ TCP ํฌํธ 1234๋ฅผ ํตํด ๋๊ธฐ ์ํ๊ฐ ๋ฉ๋๋ค.
debug: $(navilos)
qemu-system-arm -M realview-pb-a8 -kernel $(navilos) -S -gdb tcp::1234,ipv4
# GNU Debugger(GDB)๋ฅผ ์์ํฉ๋๋ค.
gdb:
arm-none-eabi-gdb
# navilos ์คํ ํ์ผ์ ์์ฑํ๋ ๊ท์น์
๋๋ค.
# ์ด์
๋ธ๋ฆฌ ์ค๋ธ์ ํธ ํ์ผ๋ค๊ณผ ๋ง์ปค ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋งํฌํฉ๋๋ค.
# ๊ทธ๋ฐ ๋ค์ objcopy๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ด๋๋ฆฌ ํ์ผ๋ก ๋ณํํฉ๋๋ค.
$(navilos): $(ASM_OBJS) $(LINKER_SCRIPT)
$(LD) -n -T $(LINKER_SCRIPT) -o $(navilos) $(ASM_OBJS)
$(OC) -O binary $(navilos) $(navilos_bin)
# ๊ฐ ์ด์
๋ธ๋ฆฌ ์์ค ํ์ผ์ ์ค๋ธ์ ํธ ํ์ผ๋ก ์ปดํ์ผํ๋ ๊ท์น์
๋๋ค.
# ํ์ํ ๋๋ ํ ๋ฆฌ๋ฅผ ์์ฑํ ํ ์ด์
๋ธ๋ฆฌ ํ์ผ์ ์ปดํ์ผํฉ๋๋ค.
build/%.o: boot/%.S
mkdir -p $(shell dirname $@)
$(AS) -march=$(ARCH) -mcpu=$(MCPU) -g -o $@ $<
3.5 ํ๋์จ์ด ์ ๋ณด ์ฝ์ด์ค๊ธฐ - ๋ฐ์ดํฐ์ํธ๋ฅผ ์ฝ๋ ๋ฐฉ๋ฒ
ํ๋์จ์ด์ ์ ๋ณด๋ฅผ ์ฝ์ด์ค๋ ๊ฐ๋จํ ์ฝ๋๋ฅผ ๋ง๋ค์ด๋ดค์ต๋๋ค.
Entry.S ์์ค ์ฝ๋
.text
.code 32
.global vector_start
.global vector_end
vector_start:
LDR R0, =0x10000000
LDR R1, [R0]
vector_end:
.space 1024, 0
.end
0x10000000์๋ ์ด๋ค ๋ฐ์ดํฐ๊ฐ ๋ค์ด์์๊น ๊ถ๊ธํ์ฌ ์ ์ ธ ๊ฐ์ด๋ ๋ฌธ์๋ฅผ ์ฐพ์๋ดค์ต๋๋ค. SYS_ID ๋ ์ง์คํฐ๋ 0x10000000 ์ฃผ์์ ์์นํ๊ณ ์์ผ๋ฉฐ ์ค๋ก์ง ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์๋ง ์๋ต๋๋ค. 32bit ํฌ๊ธฐ์ ๋ฐ์ดํฐ๋ฅผ 5๊ฐ์ ํญ๋ชฉ์ผ๋ก ์ชผ๊ฐ๋์๊ณ ๊ฐ ํญ๋ชฉ์ด ๊ฐ์ง๋ ๊ฐ์ ๋ฐ๋ผ ์๋ฏธ๊ฐ ์กด์ฌํฉ๋๋ค.

ํ์ฌ ํด๋น ์ ๋ณด๋ฅผ ์ด๋์ ์ฌ์ฉํ ์ ์์์ง ๊ฐ์ด ์กํ์ง ์์ต๋๋ค. ๋ค๋ง ์ค์ต์ด ์ฑ๊ณตํ๋์ง ํ์ ํ๋ ์ฉ๋๋ก๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํ ๊ฒ ๊ฐ์ต๋๋ค. ์์ค ์ฝ๋๋ฅผ ์ปดํ์ผํ์ฌ ์ค์ต์ ์งํํด๋ณด๊ฒ ์ต๋๋ค.
R0 ๋ ์ง์คํฐ์ 0x10000000๊ฐ ๋ค์ด๊ฐ ๊ฒ์ ํ์ธํ ์ ์๊ณ ...

R1 ๋ ์ง์คํฐ์ 0x1780500 ๊ฐ์ด ์ ์ฅ๋ ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค. ์ฝ๋๋ฅผ ์์ฑํ์ฌ ์ฝ์ด์จ ์ ๋ณด๋ฅผ ๋ถ์ํด๋ณด๊ฒ ์ต๋๋ค.
SYS_ID_analysis.py ์์ค ์ฝ๋
data = input("input data : ")
data = int(data,16)
fpga = (data & 0xFF)
arch = (data & 0xF00) >> 8
build = (data & 0xF000) >> 12
hbi = (data & 0xFFF0000) >> 16
rev = (data & 0xF0000000) >> 28
if rev == 0 :
print("Board revision : Rev A")
elif rev == 1 :
print("Board revision : Rev B")
elif rev == 2 :
print("Board revision : Rev C")
else :
print("rev : {0}".format(rev))
print("hbi board number : {0}".format(hex(hbi)))
if arch == 0x4 :
print("Bus architecture : AHB")
elif arch == 0x5 :
print("Bus architecture : AXI")
else :
print("Bus : {0}".format(hex(bus)))

์คํ์์ผ๋ณด๋ฉด ์ฑ ์์ ๋์จ ์ ๋ณด์ ์ผ์นํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
3.6 ์์ฝ
์ฝ๋๋ฅผ ์์ฑํ๊ณ ํ๋์จ์ด์์ ์คํํด๋ดค์ต๋๋ค.
์ ๋๋ก ๋์ํ๋์ง ํ์ธํด๋ณด๊ธฐ ์ํด ํ๋์จ์ด์ ๋ ์ง์คํฐ์ ์ ๊ทผํด๋ดค์ต๋๋ค.
๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๊ธฐ ์ํด gdb๋ ์ฌ์ฉํด๋ดค์ต๋๋ค.
3.7 ๋น๊ณ
gdb, Make, ๋ง์ปค ์คํฌ๋ฆฝํธ์ ๋ํ ๊ฐ๋จํ ์ ๋ฆฌ๊ฐ ํ์ํ ๊ฒ ๊ฐ์ต๋๋ค.
์ผ๋จ ์ค์ต์ ๊ณ์ ์งํํ๋ฉด์ ์๊ฐ์ ์ผ๋ก ์ฌ์ ๊ฐ ์๊ธฐ๋ฉด ๋ธ๋ก๊ทธ์ ๋ด์ฉ์ ์ ๋ฆฌํ์ฌ ํฌ์คํธ๋ก ์ฌ๋ฆฌ๊ฒ ์ต๋๋ค.