Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

Pure Software Engineer :)

booting ARM Linux 본문

Software Engineering/Linux

booting ARM Linux

HelloJaewon 2015. 7. 19. 19:15

Raspberry pi2를 target으로 리눅스 커널 부팅과정을 스터디 중.

이 글은  커널 소스의 Documentation/arm/Booting 문서를 참고하여 작성한  글이다.


부트로더는 다음의 5가지 일을 한다.

1. RAM 초기화

2. 시리얼 포트 초기화

3. Detect the machine type

4. kernel tagged list 설정

5. kernel image 호출


3. Detect the machine type

arch/arm/tools/mach-types에 각 machine별 정보를 파일로 제공한다.


# Database of machine macros and numbers  

...

# machine_is_xxx    CONFIG_xxxx     MACH_TYPE_xxx       number

...

prima2_evb      MACH_PRIMA2_EVB     PRIMA2_EVB      3103 

paz00           MACH_PAZ00      PAZ00           3128 

acmenetusfoxg20     MACH_ACMENETUSFOXG20    ACMENETUSFOXG20     3129 

bcm2708         MACH_BCM2708        BCM2708         3138 

bcm2709         MACH_BCM2709        BCM2709         3139 

ag5evm          MACH_AG5EVM     AG5EVM          3189 

ics_if_voip     MACH_ICS_IF_VOIP    ICS_IF_VOIP     3206 

wlf_cragg_6410      MACH_WLF_CRAGG_6410 WLF_CRAGG_6410      3207 

...


raspberry pi2는 bcm2709 chip을 사용하므로 bootloader는 저 값으로 kernel image 호출할 때 사용할 것이다.


4. kernel tagged list 설정

부트로더는 tagged list 또는 dtb image중 한가지를 kernel에 전달해야 한다.

이 정보들을 담고 있는 물리주소를 kernel image를 실행할때 r2 register로 넘겨준다.


4.1 tagged list

tagged list는 비어있을 수도 있지만 system memory의 크기와 root file system의 위치를 전달 해야 한다.

tagged list는 메모리상에 존재해야 하며, 이 메모리 위치는 kernel decompressor 또는 initrd의 bootp process가 메모리를 겹쳐사용하지 않도록 해야한다.

RAM의 맨 앞 16KB에 위치하도록 권장한다.


4.2 device tree

부트로더는 tagged list 대신 device tree image (dtb)를 통해 커널에 시스템 정보를 전달할 수 있다.

이는 메모리에 64bit로 align되어야 하며 Documentation/devicetree/booting-without-of.txt에 포맷 문서가 있다.

커널은 부팅과정에서 부트로더가 dtb를 전달했는지 확인하기 위해 메모리의 0xd00dfeed 주소를 확인한다.

실제로 head.S에는 다음과 같은 코드가 있다.

0xd00dfeed 주소를 사용한 것은 마침 영어에서 dtb가 feed(먹이로 들어왔는지) 확인하는 의미인듯 하다^^;


#ifdef CONFIG_ARM_APPENDED_DTB

/*

 * if there are device trees (dtb) appended to zImage, advance r10 so that the

 * dtb data will get relocated along with the kernel if necessary.

 */

        ldr lr, [r6, #0]

#ifndef __ARMEB__

        ldr r1, =0xedfe0dd0     @ sig is 0xd00dfeed big endian

#else

        ldr r1, =0xd00dfeed

#endif

        cmp lr, r1

        bne dtb_check_done      @ not found

...


dtb도 tagged list와 마찬가지로 커널이 메모리를 겹쳐서 사용하지 않을 위치에 있어야 하며, RAM 시작 주소의 128MB 바로 위가 안전하다.


5. load ramdisk (optional)

initramfs를 사용한다면 이것 역시 메모리를 겹쳐 쓰지 않도록 유의해야 하며, dtb 바로 다음이 안전하다.


6. kernel image (zImage) 호출

kernel image를 호출하는것은 2가지 방법이 있다.

첫째, kernel image가 flash 메모리에 저장되어 있고 부트로더가 flash 메모리에 있는 커널 이미지를 바로 호출하는 경우

둘째, kernel image를 RAM에 올려 실행하는 경우. 이 경우 kernel은 RAM의 처음 128MB안에 위치해 있어야 하며, kernel image를 압축해제 하기 이전에 메모리 재배치를 피하기 위해 (?) 32MB 보다 위에 위치해 있을것을 권장한다. (이것은 부팅 속도를 빠르게 하기 위해서 필요함)


(압축되지 않은) raw kernel을 사용할때는 제약사항이 좀 더 까다롭다.

- 메모리의 TEXT_OFFSET - PAGE_OFFSET 에 위치해 있어야 한다.(?)

- 모든 DMA 가능한 장치들을 검사해서 메모리가 문제 없음을 확인해야 한다.

- CPU 레지스터를 설정해야 한다.

  - r0 : 0

  - r1 : machine type number

  - r2 : tagged listㄷ 또는 device tree block (dtb)의 물리주소

- CPU mode

  - IRQ, FIQ disable 설정

  - ARM virtualization extensions을 지원하지 않는 경우 SVC_MODE로 설정 (angel bootloader인 경우는 예외)

  - ARM virtualization extensions을 지원하는 경우 kernel이 hardware suuport를 사용하도록 HYP_MODE로 진입할 수 있다. 만약 HYP_MODE로 부팅하지 않는다면 반드시 SVC_MODE로 설정해야 한다.

- Caches, MMUs

  - MMU 설정 off

  - Instruction cache는 on/off 둘다 가능

  - Data cache는 반드시 off

- 부트로더는 kernel image의 첫 번째 명령어 위치로 점프 함으로써 이후 커널 코드가 실행된다.

- ARM instruction set을 지원하는 CPU의 경우, Thumb2 커널 이미지라 할지라도 맨 처음에는 ARM state에서 시작한다.

- Cortex-M과 같은 Thumb instruction set만 지원하는 CPU의 경우, Thumb state로 시작해야 한다.



'Software Engineering > Linux' 카테고리의 다른 글

[우분투] samba 설치  (0) 2015.08.17
Ubuntu 12.04에 최신 ruby 설치  (0) 2015.04.27
Awesome! bash command  (0) 2015.04.26
Awesome strace  (0) 2015.04.19
MR4C build  (0) 2015.03.02