head.S
*
; 컴파일 시점에 이루어짐
r3 : r2번 레이블의 물리주소 0x8080
r4 : 2번 레이블의 가상주소 0x80008080
r8 : 커널 메모리 시작 offset. 0x80000000
r8 = r8 + r4 (0x8000000 + 0x8000000 = 0x0 -> overflow 발생으로 더한값이 0이 된다.)
#ifndef CONFIG_XIP_KERNEL
adr r3, 2f
ldmia r3, {r4, r8}
sub r4, r3, r4 ; r3-r4 = 0x8080 - 0x80008080 이상태에서 -플래그가 세워지지는 않음(명령어에s가 없으니까ㅋㅋ) 값은 0x8000000
add r8, r8, r4 ; r8을 delta값처럼 쓴다? create page table에서 사용.... (r8의 용도는 무엇인가?!)
#else
ldr r8, =PLAT_PHYS_OFFSET ; PLAT_PHYS_OFFSET이 0으로 설정되어있음
#endif
=> MMU를 설정하기 전이라 가상주소를 사용할 수 없기때문에, 이런 식으로 주소설정을 해준다. (이를 위해 base address를 0으로..?)
https://github.com/raspberrypi/linux/commit/72a20e22f49e2dad3180c23980a9df1c63faab0a
* __create_page_tables: 페이지테이블을 0으로 초기화하는 과정
- page_table 인자(rd, phys)로 넘어온걸 계산하는 매크로
- r4에 페이지테이블의 시작 주소를 구한 후 루틴에 들어간다.
(어떤 루틴인가~~~시작!)
* ###_LPAE ? 우리는 세팅이 안되어있어서 스킵됨
* 인라인 어셈블러
1. https://wiki.kldp.org/KoreanDoc/html/EmbeddedKernel-KLDP/app3.basic.html
* clobber가 메모리 배리어
* =r 포인터
* I는 integer라서 커널소스에서보면, i가 쓰임
2. http://codecat.tistory.com/entry/%EC%9D%B8%EB%9D%BC%EC%9D%B8-%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC
3. http://stackoverflow.com/questions/25294649/how-does-this-inline-assembly-define-a-variable
스크립트로 C언어의 DEFINE을 쫙구현할때 main()에서 인라인어셈블러문법을 사용해서 쫘르륵 설정한다.
참고로 '->' 는 인라인어셈블러문법에서 자동으로 값들을 설정하기위해서 스크립트를 이용하는데 이때 상수로 쓰기위한 문법?
'sed script' => stream editor의 약자로 \n를 사용해서 시작한다.
ex. 리눅스 명령어로 사용할 때, aa.c라는 파일을 cc.c로 바꿀 때,
$ ls | sed 's/aa/cc/g'
참고2. #define문법(C에서는 컴파일타임)을 안쓰고 offsetof을 사용해서 구현한 이유는 뭘까?
define할 값들을 스크립트를 통해서 동적으로 적용하기 위해서는 런타임 시점에 값을 변경해야 할 필요가 있음.
참고1, 참고2 => 일종의 코드생성을 위해 sed를 일반적으로 사용하는데 이를 이용해서 헤더파일을 만들어서 define들을 만들어서 사용할라고~~
* ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] 0 mm_mmuflags
r7 = __lookup_process_type으로 proc_info를 가지고와서 r10에 저장해 놨었음
__lookup_process_type를 쭉 따라들어가면 PROC_INFO라고 define시키는 구문이 있음 (vmlinux의 섹션헤더 부분에 데이터들이 박히게된다.)
-> __lookup_process_type_data -> ###_begin, ###_end 중간에 포인터들로 박힌다.
=> /linux/arch/arm/mm/proc-v7.S를 확인해보면 소스 확인 가능함 ('proc.info.init'으로 검색)
=> .macro __v7_proc
=> ALT_SMP => PMD_TYPE_SECT, ... 비트셋팅!
이렇게하면 비트들이 설정이 된다.
여기까지하면 플래그 값이 0x11c0e
...... 여기서 유니프로세스랑 멀티프로세스일때 어케 되는지(ALT_UP)
- 유니 : 0xc02
- 멀티 : 0xc0e
* adr r0, __turn_mmu_on_loc ; mmu turn on 주소를 r0에 넣기
r0 = __turn_mmu_on_loc의 물리주소 0x8134
r3 = __turn_mmu_on_loc의 가상주소 0x80009134
r5 = __turn_mmu_on의 주소 0x80008240
r6 = __turn_mmu_on_end의 주소 0x80008260
... github 소스랑 주석 참고
* r4에 페이지테이블의 시작 주소를 구했었음.
00100000
(base가 됨)
---------------------------
* XIP : 커널을 압축하지 않고 ROM FLASH에서 바로 실행되는 커널
* ARMSim - The ARM Simulator Dept. of computer science
* arm-bcm###
arm-linux-gnueabihf-objdump (cross compile)
(http://hybridego.net/entry/armlinuxgnueabihfgcc-%EC%99%80-armlinuxgnueabigcc-%EC%B0%A8%EC%9D%B4)
--------------------------
page offset
physical offset
text offset
Entry point address
Coherent, coherence 캐시 일관성 관련
'System > Linux Kernel' 카테고리의 다른 글
kernel/head.S (2) (0) | 2016.03.05 |
---|---|
[Linux Kernel Concept, File System] (1) 유닉스 파일시스템과 Inode구조체 (2) | 2016.02.14 |
[Linux Kernel Concept] GNU / Linux Kernel / Linux Distros (0) | 2016.02.13 |
gzip (0) | 2016.01.23 |
barrier와 volatile (0) | 2016.01.23 |