오후 12:36 2006-04-26
arm boot
조경민 bro@shinbiro.com
http://neri.cafe24.com
============================================================
;=====================================================
; boot test
; by bro, bro@shinbiro.com 오전 10:23 2006-04-26
;
; armasm main.s -o main.o
; armlink main.o --ro-base 0x0 -o main.axf
;=====================================================
AREA boot, CODE, READONLY
ENTRY
vector ; 인터럽트 벡터 테이블
b reset ; 주소 0번지에 reset 인터럽트가 오면 바로 reset레이블로 점프
b error ; undefined_instruction
b error ; software_interrupt
b error ; prefetch_abort
b error ; data_abort
b error ; not_used
b error ; IRQ
b error ; FIQ
error
b error
reset
; 현재 모드에서 IRQ|FIQ를 끈다.
mrs r0, CPSR ; 현재 상태 얻어옴
bic r0, r0, #0x1f ; 모드 클리어
orr r0, r0, #(0x13 | 0xc0) ; 0x13(0001 0011) | 0xC0 (1101 0000) = 0xD3(1101 0011)
msr CPSR_cxsf, r0 ; 현재 상태 저장
; 괜히 r0를 1로 만든다.
mov r0, #1
; 소프트 인터럽트를 발생시켜본다. (x86 vc의 __asm int 30과 동일)
; swi 30
; 스택 초기화 0x9000
mov sp, #0x9000
; 함수 호출
bl sub
; 종료
b end
sub
stmfd sp!, {r0-r12,lr}
mov r0, #3
ldmfd sp!, {r0-r12,pc}
end
END
-----------------------------------------------------------------------------
본 소스는 부팅부터 시작함을 의미하기 때문에 0x0 번지부터 시작하도록
링킹을 해야 한다.
또한 -G 옵션을 주면 AXD Debugger로 디버깅시 main.s 소스 레벨 디버깅이 가능하다.
armasm main.s -G -o main.o
armlink main.o --ro-base 0x0 -o main.axf
시작하자 마자 여러 주변 장치에서 발생되는 IRQ(인터럽트)가 발생될 수 있다.
일단 이것부터 꺼놓고 시작해야 한다.
mrs r0, CPSR
bic r0, r0, #0x1f
orr r0, r0, #(0x13 | 0xc0) ; 0x13(0001 0011) | 0xC0 (1101 0000) = 0xD3(1101 0011)
msr CPSR_cxsf, r0
mrs r0, CPSR을 통해서 CPSR 의 값을 읽는다. CPSR은 아래와 같다.
CPSR(Current Program State Register)
31 28 27 8 7 6 5 4 0
+---------------------------------------------+
|N Z C V I F T mode|
+---------------------------------------------+
N: Negative로 ALU 수행 결과가 음수인 경우 1로 변함
Z: Zero로 ALU 결과가 0이면 1로 변함
C: Carry로 ALU 결과 또는 shift 수행 결과에 의해 carry 출력이 발생하면 1로 변함
V: oVerflow로 산술 연산 결과 값이 너무 커 sign bit를 연산 결과가 침범하면 1로 변함
I: IRQ를 금지하면 1로 설정됨
F: FIQ를 금지하면 1로 설정됨
T: Thumb 모드이면 1로 설정됨
mode[4:0] 5비트는 ARM의 user, fiq, svc, abort, irq, undefined 모드로 6가지 중 하나
10011는 svc 모드를 의미
다음 bic r0, r0, #0x1f를 통해서 r0 = r0 & ~(0x1f)를 한다. 즉 [4:0] 모드비트들을 0으로 클리어하고
ex) CPSR의 최상위 4비트를 0으로 셋
mrs R0, CPSR
bic R0, R0, #0xF0000000 ; 0 의 갯수가 항상 6개 이상이어야 한다... 0xf1100000 은 안됨
orr r0, r0, #(0x13 | 0xc0) 즉 orr r0, r0, #0xD3를 통해서 [4:0] 1 0011로 svc모드로
[7:5]비트는 110로 IRQ는 1, FIQ는 1, Thumb은 0, 즉 IFt이다.
그런후, msr CPSR_cxsf, r0 로 CPSR에 svc모드면서 IFt를 적용하게 된다.
스택 레지스터 sp (r13)을 사용하기 전에는 사용할 공간을 잘 머리속에 메모리 맵을
구상하면서 정해야한다. 현재는 0x9000번지를 stack top으로 정하였으며 스택은
stmfd (full decending)이므로 하위 주소로 자란다.
서브 함수
서브 함수는 bl로 호출하게 된다. 서브함수 시작시
sub함수
stmfd sp!, {r0-r12,lr}
:
ldmfd sp!, {r0-r12,pc}
를 두면 r0부터 r12까지의 레지스터를 스택에 관리하고 리턴 lr도 저장한 후,
ldmfd 에서 lr값을 pc에 넣어 복귀할 수 있도록 한다.
arm boot
조경민 bro@shinbiro.com
http://neri.cafe24.com
============================================================
;=====================================================
; boot test
; by bro, bro@shinbiro.com 오전 10:23 2006-04-26
;
; armasm main.s -o main.o
; armlink main.o --ro-base 0x0 -o main.axf
;=====================================================
AREA boot, CODE, READONLY
ENTRY
vector ; 인터럽트 벡터 테이블
b reset ; 주소 0번지에 reset 인터럽트가 오면 바로 reset레이블로 점프
b error ; undefined_instruction
b error ; software_interrupt
b error ; prefetch_abort
b error ; data_abort
b error ; not_used
b error ; IRQ
b error ; FIQ
error
b error
reset
; 현재 모드에서 IRQ|FIQ를 끈다.
mrs r0, CPSR ; 현재 상태 얻어옴
bic r0, r0, #0x1f ; 모드 클리어
orr r0, r0, #(0x13 | 0xc0) ; 0x13(0001 0011) | 0xC0 (1101 0000) = 0xD3(1101 0011)
msr CPSR_cxsf, r0 ; 현재 상태 저장
; 괜히 r0를 1로 만든다.
mov r0, #1
; 소프트 인터럽트를 발생시켜본다. (x86 vc의 __asm int 30과 동일)
; swi 30
; 스택 초기화 0x9000
mov sp, #0x9000
; 함수 호출
bl sub
; 종료
b end
sub
stmfd sp!, {r0-r12,lr}
mov r0, #3
ldmfd sp!, {r0-r12,pc}
end
END
-----------------------------------------------------------------------------
본 소스는 부팅부터 시작함을 의미하기 때문에 0x0 번지부터 시작하도록
링킹을 해야 한다.
또한 -G 옵션을 주면 AXD Debugger로 디버깅시 main.s 소스 레벨 디버깅이 가능하다.
armasm main.s -G -o main.o
armlink main.o --ro-base 0x0 -o main.axf
시작하자 마자 여러 주변 장치에서 발생되는 IRQ(인터럽트)가 발생될 수 있다.
일단 이것부터 꺼놓고 시작해야 한다.
mrs r0, CPSR
bic r0, r0, #0x1f
orr r0, r0, #(0x13 | 0xc0) ; 0x13(0001 0011) | 0xC0 (1101 0000) = 0xD3(1101 0011)
msr CPSR_cxsf, r0
mrs r0, CPSR을 통해서 CPSR 의 값을 읽는다. CPSR은 아래와 같다.
CPSR(Current Program State Register)
31 28 27 8 7 6 5 4 0
+---------------------------------------------+
|N Z C V I F T mode|
+---------------------------------------------+
N: Negative로 ALU 수행 결과가 음수인 경우 1로 변함
Z: Zero로 ALU 결과가 0이면 1로 변함
C: Carry로 ALU 결과 또는 shift 수행 결과에 의해 carry 출력이 발생하면 1로 변함
V: oVerflow로 산술 연산 결과 값이 너무 커 sign bit를 연산 결과가 침범하면 1로 변함
I: IRQ를 금지하면 1로 설정됨
F: FIQ를 금지하면 1로 설정됨
T: Thumb 모드이면 1로 설정됨
mode[4:0] 5비트는 ARM의 user, fiq, svc, abort, irq, undefined 모드로 6가지 중 하나
10011는 svc 모드를 의미
다음 bic r0, r0, #0x1f를 통해서 r0 = r0 & ~(0x1f)를 한다. 즉 [4:0] 모드비트들을 0으로 클리어하고
ex) CPSR의 최상위 4비트를 0으로 셋
mrs R0, CPSR
bic R0, R0, #0xF0000000 ; 0 의 갯수가 항상 6개 이상이어야 한다... 0xf1100000 은 안됨
orr r0, r0, #(0x13 | 0xc0) 즉 orr r0, r0, #0xD3를 통해서 [4:0] 1 0011로 svc모드로
[7:5]비트는 110로 IRQ는 1, FIQ는 1, Thumb은 0, 즉 IFt이다.
그런후, msr CPSR_cxsf, r0 로 CPSR에 svc모드면서 IFt를 적용하게 된다.
스택 레지스터 sp (r13)을 사용하기 전에는 사용할 공간을 잘 머리속에 메모리 맵을
구상하면서 정해야한다. 현재는 0x9000번지를 stack top으로 정하였으며 스택은
stmfd (full decending)이므로 하위 주소로 자란다.
서브 함수
서브 함수는 bl로 호출하게 된다. 서브함수 시작시
sub함수
stmfd sp!, {r0-r12,lr}
:
ldmfd sp!, {r0-r12,pc}
를 두면 r0부터 r12까지의 레지스터를 스택에 관리하고 리턴 lr도 저장한 후,
ldmfd 에서 lr값을 pc에 넣어 복귀할 수 있도록 한다.
'KB > embbeded sw' 카테고리의 다른 글
arm-4: 커널 영역 올리기 (0) | 2006.04.27 |
---|---|
arm-3 : c코드로 점프~ (0) | 2006.04.26 |
arm-1: ADS로 ARM 공부 add (0) | 2006.04.25 |
arm-0: Armulator 사용하기 (0) | 2006.04.25 |
MPSoC 관련 (0) | 2006.04.11 |