아래 Trace32 스크립트를 실행하면 라즈베리파이 커널 vmlinux를 Trace32에 올릴 수 있습니다.
sys.cpu cortexa7
sys.u
d.load.elf vmlinux
라즈베리파이 리눅스 커널 정보를 확인하겠습니다.
각 섹션 정보는 아래와 같습니다.
y.l.sec
_____address________|path\section___________________________|acc|init|physical
P:80008000--8000826B|\\vmlinux\.head.text |R-X|L- |
P:80100000--80707797|\\vmlinux\.text |R-X|L- |
P:80707798--807077B3|\\vmlinux\.fixup |R-X|L- |
D:80800000--809C2C83|\\vmlinux\.rodata |RW-|L- |
D:809C2C88--809C91AF|\\vmlinux\__bug_table |RW-|L- |
D:809C91B0--809D0AC7|\\vmlinux\__ksymtab |R--|L- |
D:809D0AC8--809D71FF|\\vmlinux\__ksymtab_gpl |R--|L- |
D:809D7200--809DAE8B|\\vmlinux\__kcrctab |R--|L- |
D:809DAE8C--809DE227|\\vmlinux\__kcrctab_gpl |R--|L- |
D:809DE228--809FF435|\\vmlinux\__ksymtab_strings |R--|L- |
D:809FF438--80A007AB|\\vmlinux\__param |R--|L- |
D:80A007AC--80A00FFF|\\vmlinux\__modver |R--|L- |
D:80A01000--80A01F1F|\\vmlinux\__ex_table |R--|L- |
D:80A01F20--80A36E9F|\\vmlinux\.ARM.unwind_idx |R--|L- |
D:80A36EA0--80A86443|\\vmlinux\.ARM.unwind_tab |R--|L- |
P:80A86444--80A86467|\\vmlinux\.notes |R-X|L- |
P:80B002E0--80B42A3B|\\vmlinux\.init.text |R-X|L- |
P:80B42A3C--80B43EF7|\\vmlinux\.exit.text |R-X|L- |
D:80B43EF8--80B44133|\\vmlinux\.init.proc.info |R--|L- |
D:80B44134--80B44203|\\vmlinux\.init.arch.info |R--|L- |
D:80B44204--80B44213|\\vmlinux\.init.tagtable |R--|L- |
D:80B44214--80B52FFB|\\vmlinux\.init.smpalt |R--|L- |
D:80B52FFC--80B538A3|\\vmlinux\.init.pv_table |R--|L- |
D:80B54000--80B76B93|\\vmlinux\.init.data |RW-|L- |
D:80B77000--80B7D3FF|\\vmlinux\.data..percpu |RW-|L- |
D:80C00000--80C798E3|\\vmlinux\.data |RW-|L- |
D:80C7A000--80C7AFFF|\\vmlinux\.data..page_aligned |RW-|L- |
D:80C7B000--80D3B9A3|\\vmlinux\.bss |RW-|-- |
P:FFFF0000--FFFF001F|\\vmlinux\.vectors |R-X|L- |
P:FFFF1000--FFFF12BF|\\vmlinux\.stubs |R-X|L- |
리눅스 버젼은 4.9.80-v7입니다.
v.v % linux_banner
(static char [188]) linux_banner = "Linux version 4.9.80-v7+ (austin.kim@LGEARND7B16) (gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) ) #1 S
_text 즉 전원을 키면 처음 실행되는 스타트업 코드 주소는 0x80008000입니다.
NSR:80008000|EB042DB6___text:____bl______0x801136E0_______;___hyp_stub_install
NSR:80008004|E10F9000 mrs r9,cpsr
NSR:80008008|E229901A eor r9,r9,#0x1A ; r9,r9,#26
NSR:8000800C|E319001F tst r9,#0x1F ; r9,#31
NSR:80008010|E3C9901F bic r9,r9,#0x1F ; r9,r9,#31
NSR:80008014|E38990D3 orr r9,r9,#0xD3 ; r9,r9,#211
NSR:80008018|1A000004 bne 0x80008030
NSR:8000801C|E3899C01 orr r9,r9,#0x100 ; r9,r9,#256
NSR:80008020|E28FE00C adr r14,0x80008034
NSR:80008024|E16FF009 msr spsr_cxsf,r9
NSP:80008028|E12EF30E dcd 0xE12EF30E
NSP:8000802C|E160006E dcd 0xE160006E
NSR:80008030|E121F009 msr cpsr_c,r9
Calling Convention
1. start_kernel 함수 호출 전 스택 주소가 0xD000C000라고 가정합니다. 또한 강제로 R14 링크드 레지스터를 __irq_svc 심볼로 설정합니다.
[1]: 스택에 {r4-r12,r14,pc} 레지스터를 푸쉬하며 이 동작 스택 주소는 0xD000BFD4로 변경됩니다.
[2]: 스택 주소가 D000BFB8 = (0xD000BFD4 - 0x1C) 로 업데이트됩니다.
NSR:80B00970|E1A0C00D start_kernel: cpy r12,r13
NSR:80B00974|E92DDFF0 push {r4-r12,r14,pc} // <<--[1]
NSR:80B00978|E24CB004 sub r11,r12,#0x4 ; r11,r12,#4
NSR:80B0097C|E24DD01C sub r13,r13,#0x1C ; r13,r13,#28 // <<--[2]
스택 덤프
_____address|_data________|value_____________|symbol
NSD:D000BFB0| 00 00 00 00 0x0
NSD:D000BFB4| 00 00 00 00 0x0
NSD:D000BFB8| 00 00 00 00 0x0 // <<--[2]
NSD:D000BFBC| 00 00 00 00 0x0
NSD:D000BFC0| 00 00 00 00 0x0
NSD:D000BFC4| 00 00 00 00 0x0
NSD:D000BFC8| 00 00 00 00 0x0
NSD:D000BFCC| 00 00 00 00 0x0
NSD:D000BFD0| 00 00 00 00 0x0
NSD:D000BFD4| 04 00 00 00 0x4 // <<--[1]
NSD:D000BFD8| 05 00 00 00 0x5
NSD:D000BFDC| 06 00 00 00 0x6
NSD:D000BFE0| 07 00 00 00 0x7
NSD:D000BFE4| 08 00 00 00 0x8
NSD:D000BFE8| 09 00 00 00 0x9
NSD:D000BFEC| 10 00 00 00 0x10
NSD:D000BFF0| 11 00 00 00 0x11
NSD:D000BFF4| 00 C0 00 D0 0xD000C000
NSD:D000BFF8| 20 53 70 80 0x80705320 \\vmlinux\Global\__irq_svc
NSD:D000BFFC| 78 09 B0 80 0x80B00978 \\vmlinux\init/main\start_kernel+0x8
NSD:D000C000| 00 00 00 00 0x0
NSD:D000C004| 00 00 00 00 0x0
start_kernel에서 set_task_stack_end_magic를 호출할 시 스택에 레지스터를 어떻게 푸쉬하는지 점검합니다.
[1]: 스택 주소는 0xD000BFA8로 업데이트됩니다.
[2]: R12 즉 현재 스택 주소이서 0x4만큼 뻬고 R11에 저장합니다.
NSR:80119F00|E1A0C00D__set_task_stack_end_magic:_____cpy_____r12,r13
NSR:80119F04|E92DD800 push {r11-r12,r14,pc} //<<--[1]
NSR:80119F08|E24CB004 sub r11,r12,#0x4 ; r11,r12,#4 //<<--[2]
NSR:80119F0C|E52DE004 str r14,[r13,#-0x4]!
스택 덤프
_____address|_data________|value_____________|symbol
NSD:D000BF94| 00 00 00 00 0x0
NSD:D000BF98| 00 00 00 00 0x0
NSD:D000BF9C| 00 00 00 00 0x0
NSD:D000BFA0| 00 00 00 00 0x0
NSD:D000BFA4| 00 00 00 00 0x0
NSD:D000BFA8| FC BF 00 D0 0xD000BFFC // <<-- R11
NSD:D000BFAC| B8 BF 00 D0 0xD000BFB8 // <<-- R12
NSD:D000BFB0| 88 09 B0 80 0x80B00988 \\vmlinux\init/main\start_kernel+0x18 //<<-- LR
NSD:D000BFB4| 08 9F 11 80 0x80119F08 \\vmlinux\fork\set_task_stack_end_magic+0x8 //<<-- PC
NSD:D000BFB8| 00 00 00 00 0x0
NSD:D000BFBC| 00 00 00 00 0x0
NSD:D000BFC0| 00 00 00 00 0x0
NSD:D000BFC4| 00 00 00 00 0x0
NSD:D000BFC8| 00 00 00 00 0x0
NSD:D000BFCC| 00 00 00 00 0x0
NSD:D000BFD0| 00 00 00 00 0x0
NSD:D000BFD4| 04 00 00 00 0x4
NSD:D000BFD8| 05 00 00 00 0x5
NSD:D000BFDC| 06 00 00 00 0x6
NSD:D000BFE0| 07 00 00 00 0x7
NSD:D000BFE4| 08 00 00 00 0x8
NSD:D000BFE8| 09 00 00 00 0x9
NSD:D000BFEC| 10 00 00 00 0x10
NSD:D000BFF0| 11 00 00 00 0x11
NSD:D000BFF4| 00 C0 00 D0 0xD000C000
NSD:D000BFF8| 20 53 70 80 0x80705320 \\vmlinux\Global\__irq_svc
NSD:D000BFFC| 78 09 B0 80 0x80B00978 \\vmlinux\init/main\start_kernel+0x8
NSD:D000C000| 00 00 00 00 0x0
위 정보를 종합하면 함수 호출 시 아래 규칙으로 스택에 푸쉬합니다.
[1]: 스택을 푸쉬할 때의 함수 프로그램 카운터
[2]: 호출한 함수(Linked Register) 주소
[3]: 업데이트하기 직전의 스택 주소
[4]: 프레임 포인터 레지스터: 이 주소에 -4를 빼면 바로 이전에 수행됐던 함수 심볼 정보가 보임
예를 들면 0xD000BFF8 = 0xD000BFFC - 0x4
#스택 덤프
NSD:D000BFA8| FC BF 00 D0 0xD000BFFC // <<-- [4]
NSD:D000BFAC| B8 BF 00 D0 0xD000BFB8 // <<-- [3]
NSD:D000BFB0| 88 09 B0 80 0x80B00988 \\vmlinux\init/main\start_kernel+0x18 //<<-- [2]
NSD:D000BFB4| 08 9F 11 80 0x80119F08 \\vmlinux\fork\set_task_stack_end_magic+0x8 //<<-- [1]
NSD:D000BFB8| 00 00 00 00 0x0 //<<-- 스택 주소
// .. 생략..
NSD:D000BFF4| 00 C0 00 D0 0xD000C000
NSD:D000BFF8| 20 53 70 80 0x80705320 \\vmlinux\Global\__irq_svc
NSD:D000BFFC| 78 09 B0 80 0x80B00978 \\vmlinux\init/main\start_kernel+0x8
NSD:D000C000| 00 00 00 00 0x0
'리눅스 커널의 구조와 원리 > 2. 라즈베리 파이 설정' 카테고리의 다른 글
라즈베리 파이 시작하기_OS설치 (0) | 2023.05.12 |
---|---|
[리눅스][유틸리티] 서버간 파일 복사 - scp (0) | 2023.05.12 |
[라즈베리] 커널 빌드 스크립트 (0) | 2023.05.12 |
[리눅스커널] 로그 레벨을 업데이트하는 커밋(라즈베리 파이3)! (0) | 2023.05.05 |
[라즈베리파이] 64비트 라즈비안 이미지 위치 (0) | 2023.05.05 |