PART II 커널의시작 start_kernel 은어떻게호출될까? 커널의실제시작함수는 start_kernel() 함수다. 이함수는다시 100여개의함수들을호출하면서부팅을진행한다. 하지만 startk_kernel() 함수가호출되기전에커널컴파일을통해얻어진 zimage의압축해

Similar documents
Microsoft PowerPoint - o8.pptx

Microsoft Word - 1. ARM Assembly 실습_xp2.doc

Microsoft PowerPoint - 05-ARM-Instruction-Set.ppt

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

Microsoft Word - FunctionCall

Chapter ...

Microsoft Word ARM_ver2_0a.docx

Microsoft PowerPoint - chap06-2pointer.ppt

PowerPoint 프레젠테이션

Here is a "PLDWorld.com"... // EXCALIBUR... // Additional Resources // µc/os-ii... Page 1 of 23 Additional Resources: µc/os-ii Author: Source: HiTEL D

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

PowerPoint 프레젠테이션

Microsoft PowerPoint - LN_2_Bootloader.ppt [호환 모드]

Computer Architecture

슬라이드 1

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

학습목차 r 개념으로살펴보는 CPU 속의제어장치 r 마이크로연산 r 제어장치의동작 r 마이크로프로그램을이용한제어 컴퓨터구조 제어장치

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A634C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

ARM Reverse Engineering

Microsoft PowerPoint - hy2-12.pptx

PowerPoint 프레젠테이션

정보보안 개론과 실습:네트워크

PowerPoint 프레젠테이션

<4D F736F F F696E74202D2037C0E52DC4B3BDC3BFCDB8DEB8F0B8AE>

학습목차 r 컴퓨터본체에서 CPU 의위치살펴보기 r CPU 의성능 r CPU 의기능 r CPU 의조직 r 레지스터의조직 r 명령어사이클 r 명령어파이프라이닝 컴퓨터구조 2 9. CPU 조직과기능

Computer Architecture

버퍼오버플로우-왕기초편 10. 메모리를 Hex dump 뜨기 앞서우리는버퍼오버플로우로인해리턴어드레스 (return address) 가변조될수있음을알았습니다. 이제곧리턴어드레스를원하는값으로변경하는실습을해볼것인데요, 그전에앞서, 메모리에저장된값들을살펴보는방법에대해배워보겠습

온라인 IT 교육최강 ( 강의정보처리필기강사조대호 차시명 [CA-06 강 ] 프로세서와명령어차시 6 차시 학습내용 프로세서와명령어 학습목표 컴퓨터의구조와프로세서에대해이해할수있다 컴퓨터의명령어에대해이해할수있다 학습내용 1. 컴퓨터의구성 - 1

Microsoft PowerPoint - hy2-12.pptx

Microsoft PowerPoint - 알고리즘_5주차_1차시.pptx

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

PowerPoint 프레젠테이션

JVM 메모리구조

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

인터럽트 (Interrupt) 범용입출력포트에서입출력의내용을처리하기위해매번입출력을요구하는플래그를검사하는일 (Pollong) 에대하여마이크로컨트롤러에게는상당한시간을소비하게만든다. 인터럽트란 CPU가현재처리하고있는일보다급하게처리해야할사건이발생했을때, 현재수행중인일을중단하고

망고100 보드로 놀아보자 -10

11장 포인터

초보자를 위한 분산 캐시 활용 전략

금오공대 컴퓨터공학전공 강의자료

hlogin2

<4D F736F F F696E74202D203137C0E55FBFACBDC0B9AEC1A6BCD6B7E7BCC72E707074>

임베디드시스템설계강의자료 6 system call 1/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

Mango220 Android How to compile and Transfer image to Target

SRC PLUS 제어기 MANUAL

chap 5: Trees

학습목표 2/33 마이크로프로세서와마이크로컨트롤러의차이를알수있다. 마이크로프로세서에서프로그램이수행되기위한명령어형식과명령어실행절차를알수있다. 프로그램을수행하려면어떤종류의명령어가필요한지알수있다. 현대컴퓨터의기본모델인저장형프로그램컴퓨터의한계점과그한계를완화하려는방법을알수있다.

PowerPoint 프레젠테이션

Reusing Dynamic Linker For Exploitation Author : Date : 2012 / 05 / 13 Contact : Facebook : fb.me/kwonpwn

[8051] 강의자료.PDF

PowerPoint 프레젠테이션

PowerPoint Presentation

<C1A4BAB8C3B3B8AE5FB1E2BBE75FC7CAB1E25F FB1E2BBE7C6D0BDBABFEB2E687770>

Deok9_Exploit Technique

API 매뉴얼

Microsoft PowerPoint - ch10 - 이진트리, AVL 트리, 트리 응용 pm0600

SQL Developer Connect to TimesTen 유니원아이앤씨 DB 기술지원팀 2010 년 07 월 28 일 문서정보 프로젝트명 SQL Developer Connect to TimesTen 서브시스템명 버전 1.0 문서명 작성일 작성자

Adobe Flash 취약점 분석 (CVE )

슬라이드 1

untitled

지난시간에... 우리는 kernel compile을위하여 cross compile 환경을구축했음. UBUNTU 12.04에서 arm-2009q3를사용하여 간단한 c source를빌드함. 한번은 intel CPU를위한 gcc로, 한번은 ARM CPU를위한 gcc로. AR

<4D F736F F F696E74202D206D61696E D F6E D20C7C1B7CEBCBCBCAD20B7CEB5F920C8C420B8DEB8F0B8AE20B9D B20B1B8C1B6C0CCC7D8>

Abstract View of System Components

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

Microsoft Word - ExecutionStack

4. 다음주소지정방식중속도가가장빠른주소방식은? 가. immediate addressing mode 나. direct addressing mode 다. indirect addressing mode 라. index register. 5. 간접주소 (indirect addr

<C1A4BAB8C3B3B8AE5FB1E2BBE75FC7CAB1E25F E687770>

시스코 무선랜 설치운영 매뉴얼(AP1200s_v1.1)

PowerPoint 프레젠테이션

UI TASK & KEY EVENT

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

커알못의 커널 탐방기 이 세상의 모든 커알못을 위해서

설계란 무엇인가?

Code Generation in Rapid

PowerPoint 프레젠테이션

2. GCC Assembler와 AVR Assembler의차이 A. GCC Assembler 를사용하는경우 i. Assembly Language Program은.S Extension 을갖는다. ii. C Language Program은.c Extension 을갖는다.

금오공대 컴퓨터공학전공 강의자료

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

KEY 디바이스 드라이버

<BDC7C7E83120B0E1B0FABAB8B0EDBCAD202832C1D6C2F7292E687770>

DBMS & SQL Server Installation Database Laboratory

PowerPoint 프레젠테이션

Microsoft PowerPoint - ch07 - 포인터 pm0415

API 매뉴얼

11장 포인터

프로그램카운터 (Program Counter) 명령레지스터 (Instruction Register) 누산기 (AC: Accumulator) 상태레지스터 (Status Register) PSWR(Program Status Word Register) 메모리주소레지스터 (M

Microsoft PowerPoint - chap01-C언어개요.pptx

Microsoft PowerPoint - 02_Linux_Fedora_Core_8_Vmware_Installation [호환 모드]

슬라이드 1

게시판 스팸 실시간 차단 시스템

<C6F7C6AEB6F5B1B3C0E72E687770>

임베디드시스템설계강의자료 4 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

PowerPoint 프레젠테이션

임베디드 시스템 구조

Computer Architecture

Microsoft PowerPoint - LN_1_ARM_CPU_0.ppt [호환 모드]

adfasdfasfdasfasfadf

Microsoft PowerPoint - additional01.ppt [호환 모드]

<4D F736F F D20B1B9B0A1BAB020BEC6C0CCC7C720C2F7B4DC20B0A1C0CCB5E5>

제목을 입력하세요

Microsoft Word - NAT_1_.doc

Transcription:

PART II 커널의시작 start_kernel 은어떻게호출될까? 커널의실제시작함수는 start_kernel() 함수다. 이함수는다시 100여개의함수들을호출하면서부팅을진행한다. 하지만 startk_kernel() 함수가호출되기전에커널컴파일을통해얻어진 zimage의압축해제, 페이지디렉터리구성과같은기초적인작업이먼저수행되어야한다. 바로이 번파트에서 start_kernel() 함수가불리기전까지일련의과정을알아볼것이다. 이번파트에서다루는모든코드는 ARM 어셈블리로작성되어있다. 부트로더로부터 PC(Program Counter) 가 start 레이블로이동되면서기초작업이수행된다. start_kenel 이호출되는단계는크게 3 단계로구분할수있는데, 1 단계는커널이미지인 zimage 압축 을해제하기위한준비단계로프로세서버전에맞는프로세서타입테이블로부터캐시켜기, 끄기, 플러시등을수행하고, MMU 를위한 16KB 페이지디렉터리를구성한다. 2 단계는 zimage 의압축을 해제한다. 마지막 3 단계에서는프로세서및머신정보와부트로더로부터넘겨온 atag 정보의유효성 등을검사한후 MMU 를활성화하는단계를거쳐커널의시작인 start_kernel() 함수를호출하게된다. 그림 PART II-1 은이번파트에서알아볼커널의주요내부흐름 (flow) 을보여준다.

5 Chapter 커널압축해제준비하기 이번장은압축된커널이미지 (zimage) 를해제하기위해필요한단계들에대해서알아볼것이다. 압축해제준비단계로는인터럽트비활성화, 동적메모리할당, BSS 영역초기화, 페이지디렉터리초기화, 캐시켜기등을수행한다. 압축을해제하기위한준비중가장중점을두는부분은 zimage의압축이해제되는위치를기준으로하위 16KB에페이지디렉터리를위한공간을구성하고, CP15의 c2 레지스터에페이지디렉터리의위치를저장하는것이다. ARM에서페이지디렉터리는 4GB의메모리를 1MB 섹션으로관리한다. 따라서 4GB를관리하기위해서는 1MB 단위의 4,096개엔트리가필요하고각엔트리는 32비트워드로관리되기때문에총 16KB(4Byte 3 4,096엔트리 5 16KB) 가필요하게된다. 또한페이지디렉터리의위치에해당하는엔트리에 cacheable과 bufferable을설정하여페이지디렉터리가캐싱되어빠르게접근될수있도록한다. 그림 5-1은이번장에서알아볼커널코드의내부흐름을도식화한것이다. 그림 5-1 start 레이블에서압축해제준비까지흐름도

5.1 부트로더에이어첫스타트끊기 - start 레이블 57 5.1 부트로더에이어첫스타트끊기 - start 레이블 부트로더에의해서하드웨어및소프트웨어에대한기본적인초기화가이루어진이후에가장먼저실행되는것은 arch/arm/boot/compressed/head.s에있는 start 레이블에있는코드들이다. 12) start 레이블에서는부트로더로부터아키텍처 ID와 atags(7.4절참고 ) 정보를전달받는다. 또한인터럽트비활성화및레지스터를초기화하고 not_relocated 레이블로점프한다. 코드 5-1을자세히살펴보자. 코드 5-1 arch/arm/boot/compressed/head.s 의 start 레이블 start:.type start,#function 1: mov r7, r1 @ 아키텍처 ID 저장 ➊ mov r8, r2 @ atags 포인터저장 #ifndef ARM_ARCH_2 ➋ mrs r2, cpsr @ CPSR 가져오기 orr r2, r2, #0xc0 @ 6, 7번비트에 IRQ, FIQ 끄도록설정 msr cpsr_c, r2 @ CPSR에반영해서인터럽트끄기 #else teqp pc, #0x0c000003 @ 인터럽트끄기 ➌ #endif.text ➍ adr r0, LC0 ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} subs r0, r0, r1 beq not_relocated start 레이블의코드섹션 ➊ 에서는부트로더로부터전달된아키텍처 ID 와 atags 정보를레 지스터 r7, r8 에각각저장한다. 12) 부트로더는다음과같이 5 가지기능을제공해야한다. 1) RAM 초기화, 2) 시리얼포트초기화, 3) 머신타입찾기, 4) 커널 tagged list 구성, 5) 커널이미지로제어이관

58 Chapter 5 커널압축해제준비하기 코드섹션 ➋에서는인터럽트를비활성화한다. IRQ와 FIQ를모두비활성화시키며, 인터럽트를비활성화시키는방법은 ARM 프로세서의버전에따라서구현이다르다. ARM_ ARCH_2 는 ARM2, ARM3 프로세서에대해서 GCC에의해서선언되는매크로다. ARM 버전 2, 3의코어에대해서는코드섹션 ➌과같이인터럽트비활성화를한다. 코드섹션 ➍는텍스트섹션의시작이며, 레지스터 r1 r6, ip, sp를아래와같이설정해준다. LC0 -> r1 bss_start -> r2 _end -> r3 zreladdr -> r4 _start -> r5 _got_start -> r6 _got_end -> ip user_stack+4096 -> sp 표 5-1 에있는 ip, sp 는 GCC 에서사용되는 ARM 레지스터들의명명법 (mnemonic) 이다. GCC 에사용되는 ARM 레지스터이름과쓰임은표 5-1 을참조하기바란다. 그다음에 not_relocated 레이블로점프한다. 표 5-1 GCC 에의해사용되는 ARM 레지스터이름과쓰임 레지스터이름레지스터명명법쓰임 r0 a1 함수에전달되는첫인자 결과값레지스터 스크래치레지스터 r1 a2 함수에전달되는두번째인자 스크래치레지스터 r2 a3 함수에전달되는세번째인자 스크래치레지스터 r3 a4 함수에전달되는네번째인자 스크래치레지스터 r4 v1 레지스터변수 r5 v2 레지스터변수 r6 v3 레지스터변수 r7 v4 레지스터변수 r8 v5 레지스터변수 r9 v6 rfp 레지스터변수 - 실제프레임포인터 r10 sl 스택리미트 (stack limit)

5.2 BSS 영역초기화하기 - not_relocated 레이블 59 표 5-1 ( 계속 ) 레지스터이름 레지스터명명법 쓰임 r11 fp 프레임포인터 (frame pointer) r12 ip 스크래치레지스터 (scratch register) r13 sp 스택포인터 (stack pointer) r14 lr 링크레지스터 (link register) r15 pc 프로그램카운터 (program counter) 5.2 BSS 영역초기화하기 - not_relocated 레이블 압축된커널인 zimage의압축을해제하기위한준비단계로 BSS 영역을초기화해주고캐시활성화및동적메모리영역을설정한다. 이러한설정은커널압축해제시꼭필요한요구사항이다. 코드 5-2로원리를살펴보자. 코드 5-2 arch/arm/boot/compressed/head.s 의 not_relocated 레이블 not_relocated: mov r0, #0 1: ➊ str r0, [r2], #4 @ bss 영역초기화 str r0, [r2], #4 str r0, [r2], #4 str r0, [r2], #4 cmp r2, r3 @ r2, r3를비교 blo 1b @ r2가 r3보다작다면뒤쪽레이블 1로점프 bl cache_on ➋ mov r1, sp @ malloc 영역은스택바로위에위치 add r2, sp, #0x10000 @ 64k max, r2 = sp+ 0x10000 bhs wont_overwrite @ r4가 higher or same이라면점프 ➌ 코드섹션 ➊은 BSS 영역을 0으로초기화하며, BSS 영역은초기화되지않은전역데이터를위한공간이다. BSS 영역은 bss_start와 _end 사이의영역이며, 링커스크립트파일에의해서그값이결정된다. 코드섹션 ➋를통해서 cache_on을호출하여캐시를활성화하고, 압축된커널을풀기위한동적메모리공간의시작주소 (user_stack + 4KB) 와끝주소 (user_stack + 4KB + 64KB)

60 Chapter 5 커널압축해제준비하기 를레지스터 r1, r2에구한다. 즉, 동적메모리공간은 64KB다. 이것으로커널압축해제를위한모든준비가마무리되었다. cache_on 레이블에해당하는코드분석은다음절 (5.3절) 에서자세히알아볼것이다. 코드섹션 ➌의 wont_overwrite 레이블로점프하여본격적인커널압축해제를실행하게된다. wont_overwrite에대해서는 6.1절에서알아볼예정이다. 알아봅시다! vmlinux.lds 링커스크립트파일 링커스크립트파일은링커에의해참조되며, Makefile에의해생성된오브젝트파일들을어떤식으로링크하여커널이미지를생성할지에대한정보를가지고있다. 링커는항상링커스크립트를사용한다. 만약에링커스크립트를직접제공하지않으면기본스크립트를이용한다. 기본스크립트는 ld -verbose를통해확인할수있다. code@kernel:~$ ld -verbose GNU ld (GNU Binutils for Debian) 2.20.1.20100303 Supported emulations: armelf_linux_eabi armelfb_linux_eabi elf_x86_64 elf_i386 i386linux elf_l1om using internal linker script: ================================================== /* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT( elf32-littlearm, elf32-bigarm, elf32-littlearm ) OUTPUT_ARCH(arm) ENTRY(_start) SEARCH_DIR( /usr/arm-linux-gnueabi/lib ); SECTIONS { /* Read-only sections, merged into text segment: */ PROVIDE ( executable_start = SEGMENT_START( text-segment, 0x00008000));. = SEGMENT_START( text-segment, 0x00008000) + SIZEOF_HEADERS;.interp : { *(.interp) }.text : { *(.text.unlikely.text.*_unlikely) *(.text.stub.text.*.gnu.linkonce.t.*) /*.gnu.warning sections are handled specially by elf32.em. */

5.2 BSS 영역초기화하기 - not_relocated 레이블 61 *(.gnu.warning) *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) } =0.bss : { *(.dynbss) *(.bss.bss.*.gnu.linkonce.b.*) *(COMMON) /* Align here to ensure that the.bss section occupies space up to _end. Align after.bss to ensure correct alignment even if the.bss section disappears because there are no input sections. FIXME: Why do we need it- When there is no.bss section, we don t pad the.data section. */. = ALIGN(.!= 0-32 / 8 : 1); } _bss_end =. ; bss_end =. ;. = ALIGN(32 / 8);. = ALIGN(32 / 8); end =. ; _end =.; PROVIDE (end =.);. = DATA_SEGMENT_END (.); } ================================================== code@kernel:~$ -T 옵션을통해서자신만의링커스크립트를링커에게제공할수있다. 아래코드는간단한링커스크립 트파일이다. OUTPUT_FORMAT( elf32-littlearm, /* 실행할바이너리를 elf */ elf32-littlearm, /* 포멧으로생성한다. */ elf32-littlearm ) OUTPUT_ARCH(arm) /* 아키텍처를 ARM 으로명시한다. */ ENTRY(_start) /* 시작함수를 _start 로설정한다. */ SECTIONS {. = 0x00000000; /* 이미지시작주소 - mmu 사용을하지않을경우 0xA000000 과같이물리메모리의주소가들어갈수도있다.*/. = ALIGN(4);

62 Chapter 5 커널압축해제준비하기 }.text : { *(.text) }. = ALIGN(4);.rodata : { *(.rodata) } /* 각오브젝트 (.o) 파일의 text 섹션 ( 코드영역 ) 들이링커에의해서하나의 text 섹션으로재배치된다. */ /* 각오브젝트 (.o) 파일의 rodata 섹션 ( 읽기전용데이터영역 ) 들이링커에의해서하나의 rodata 섹션으로재배치된다. */. = ALIGN(4); /* 각오브젝트 (.o) 파일의 data 섹션 ( 데이터.data : { *(.data) } 영역 ) 들이링커에의해서하나의 data 섹션으로재배치된다. */. = ALIGN(4); /* 각오브젝트 (.o) 파일의 got 섹션 (global got : { *(.got) } offset table) 들이링커에의해서하나의 got 섹션으로재배치된다.*/. = ALIGN(4); /* 각오브젝트 (.o) 파일의 bss 섹션 ( 초기화.bss : { *(.bss) } 되지않은데이터영역 ) 들이링커에의해서 하나의 bss 섹션으로재배치된다. */ 5.3 캐시활성화하기 - cache_on 레이블 BSS 영역초기화와동적메모리영역설정등을해주었다면커널압축해제를위한마지막준비단계로서캐시켜기 (cache on) 를수행한다. 리눅스에서캐시켜기는 ARM 아키텍처버전마다서로다르게구현된다. cache_on 레이블에서는현재시스템의 ARM 아키텍처버전에맞는캐시켜기서브루틴을찾아호출한다. 또한 setup_mmu라는서브루틴을호출하여페이지디렉터리를초기화해준다. 코드 5-3을통해자세히살펴보자. 코드 5-3 arch/arm/boot/compressed/head.s 의 cache_on 레이블 cache_on: mov r3, #8 @ cache_on 함수 ➊ b call_cache_fn call_cache_fn: adr r12, proc_types @ r12 = proc_types에대한 @ 테이블의시작주소 ➋ #ifdef CONFIG_CPU_CP15 mrc p15, 0, r6, c0, c0 @ get processor ID #else ldr r6, =CONFIG_PROCESSOR_ID @ r6에프로세서아이디를얻어옴 #endif 1: ldr r1, [r12, #0] @ core ID ➌ ldr r2, [r12, #4] @ Mask

5.3 캐시활성화하기 - cache_on 레이블 63 eor r1, r1, r6 @ (real ^ match)-> exclusive or 연산함 @ 두비트가같으면 0, 두비트가다르면 1 tst r1, r2 @ & mask -> 마스크를적용 @ tst는선택된 bit들이 all zero인지검사할때사용 addeq pc, r12, r3 @ cache 함수호출 -> 결과값이 0이면 @ r12+r3 값을 pc에넣어점프. add r12, r12, #4*5 @ 일치하지않으면 r12에 20을더함 @ ( 다음엔트리를가리키게한다.) b 1b @ 뒤에있는레이블 1로점프 코드섹션 ➊에서는레지스터 r3에상수 8을저장하고 call_cache_fn 레이블로점프한다. ARM 프로세서버전마다다른캐시켜기 (cache on), 캐시플러시 (cache flush), 캐시끄기 (cache off) 기능을 proc_types 테이블로관리한다. 즉, proc_types 테이블의각엔트리는특정 ARM 프로세서버전에알맞은캐시켜기, 캐시플러시, 캐시끄기서브루틴에대한정보를갖고있다. 상수 8은 proc_types 테이블의각엔트리에존재하는캐시켜기서브루틴의시작주소를가리키는오프셋으로사용된다. proc_types 테이블의구성은 알아봅시다! proc_ types 테이블 을참조하길바란다. 알아봅시다! proc_types 테이블 proc_types 테이블은 ARM 프로세서버전마다하나의엔트리로표현되며, 엔트리는아래그림 5-2 와같 이구성된다. CPU ID match CPU ID mask cache on subroutine Entry 1 cache off subroutine cache flush subroutine 그림 5-2 proc_types 테이블코드 5-3의코드섹션 ➌에서 ((real_id ^ match) & mask) == 0일경우엔트리가일치한다. 그리고라이트쓰루 (writethrough, 바로쓰기 ) 정책을사용하는캐시는캐시켜기 / 끄기 (cache on/off) 에대한함수가존재하지만, 라이트백 (writeback, 나중쓰기 ) 정책을사용하는캐시의경우는메모리와의동기화를위해서캐시플러시 (cache flush) 함수가추가적으로필요하다.

64 Chapter 5 커널압축해제준비하기 코드섹션 ➋에서는앞서설명한 proc_types 테이블의시작주소를레지스터 r12에저장한다. CONFIG_CPU_CP15는코프로세서 (coprocessor1 CP15) 13) 의존재여부에대한커널설정매크로다. 만약 CP15가존재하는 ARM 아키텍처의경우는 CPU ID를 CP15를통해서얻어온다. 코드섹션 ➌에서는현재 ARM 아키텍처에알맞은 cache_on 서브루틴을 proc_types 테이블에서찾은후점프한다. 앞서 proc_types 테이블을통해서 ARM 프로세서버전에맞는캐시켜기구현서브루틴으로이동해왔다. ARM 버전별로캐시켜기구현방법은서로다르지만, 결국하는일은모두같다. 코드 5-4는 ARM v6의예제다. ARM v6은 ARM v4와같은방법으로캐시켜기를수행하므로 armv4_mmu_cache_on 서브루틴을수행한다. 코드 5-4 arch/arm/boot/compressed/head.s 의 amrv4_mmu_cache_on 레이블 armv4_mmu_cache_on: mov r12, lr ➊ bl setup_mmu mov r0, #0 mcr p15, 0, r0, c7, c10, 4 mcr p15, 0, r0, c8, c7, 0 mrc p15, 0, r0, c1, c0, 0 ➋ orr r0, r0, #0x5000 rr r0, r0, #0x0030 ➌ bl common_mmu_cache_on ➍ mov r0, #0 mcr p15, 0, r0, c8, c7, 0 ➎ mov pc, r12 먼저코드섹션 ➊에서레지스터 lr에담긴복귀주소를 r12에저장한후에 setup_mmu 서브루틴을호출한다. 이는 setup_mmu 서브루틴수행을마치고반환된후나머지코드를마저수행하기위해서다. 코드섹션 ➋에서는 CP15를이용해서쓰기버퍼의내용을모두메모리에업데이트하고, 13) 코프로세서는추가된명령어집합 (instruction set) 과설정레지스터 (configuration register) 를통해서 ARM 코어의추가기능을지원한다. 특히 CP15 는 ARM 프로세서가 Cache, TCM, Identification Register, Write Buffer, Memory Management 를제어할수있게해준다.

5.4 페이지디렉터리엔트리초기화하기 - setup_mmu 레이블 65 I-Cache( 명령어캐시 ), D-Cache( 데이터캐시 ), TLB에대해서도플러시해준다. 코드섹션 ➌에서는 CP15의제어레지스터 (control register) 의내용을읽어와서 I-Cache 활성화비트, 라운드로빈캐시교체정책활성화비트를설정한다. 보다자세한내용은 알아봅시다! CP15 제어레지스터 를참조하길바란다. 변경된설정에대한적용은 common_mmu_cache_on 서브루틴에서수행된다. 알아봅시다! CP15 제어레지스터 ARM 은 CP15 의제어레지스터를통해서 MMU 와캐시의활성화, 캐시교체정책설정등을수행한다. CP15 의제어레지스터는그림 5-3 과같다. 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 4 3 2 1 0 SBZ F A T R SBZ E E V E X P U F I SBZ I T S B Z D T L 4 R R V I Z F R S B SBO W C A M 그림 5-3 CP15 제어레지스터 0x5000 은 12 번째비트 (I bit) 와 14 번째비트 (RR bit) 를설정함으로써 I-Cache 활성화와라운드로빈캐시교 체정책을설정한다. 코드섹션 ➍의 common_mmu_cache_on 서브루틴에서는앞서코드섹션 ➌에서변경된도메인 (domain) 설정과 I-Cache 활성화및라운드로빈캐시교체정책을적용한다. 또한페이지디렉터리 (page directory) 의시작주소값을 CP15의전용레지스터 (Translation Table Base Register) 14) 에저장한다마지막으로코드섹션 ➎를통해서 I-Cache, D-Cache, TLB를플러시하고코드 5-2의 bl cache_on 다음명령어로반환한다. 5.4 페이지디렉터리엔트리초기화하기 - setup_mmu 레이블 setup_mmu 레이블은 cache_on 레이블내에서호출되며, 커널압축해제에필요한페이지디렉터리엔트리 (page directory entry) 를초기화해준다. 특히메모리의 256MB 영역에대해서는 cacheable, bufferable로설정을해준다. 이것은커널의압축해제시캐시와쓰 14) TTBR 는 L1( 레벨 1) 테이블의물리주소를저장하는 CP15 내의특수레지스터다. TTBR 은 OS 를통해사용되며, L1 테이블에빠른접근을하기위한목적을갖는다.

66 Chapter 5 커널압축해제준비하기 기버퍼사용을통해서압축해제의성능을높이기위함이다. setup_mmu 수행이후페 이지디렉터리의모습은그림 5-4 와같다. RAM Entry P-Address Value in Virtual zimage 4095 1536 0x50007FFC 0x50005800 0xFFF00C12 0x60000C12 0x50C00000 unzip 1535 0x500057FC 0x5FF00C1E 256 Cacheable/ Bufferable 1230 0x50005400 0x50000C1E zimage 1279 0x500053FC 0x4FF00C12 0x50008000 16KB 0x50004000 Page Directory (4096 Entries) 2 1 0 0x50004008 0x50004004 0x50004000 0x00200C12 0x00100C12 0x00000C12 그림 5-4 setup_mmu 수행후페이지테이블 코드 5-5 를통해서커널이어떻게페이지디렉터리를초기화하는지알아보도록하자. 코드 5-5 arch/arm/boot/compressed/head.s 의 setup_mmu 레이블 setup_mmu: sub r3, r4, #16384 bic r3, r3, #0xff bic r3, r3, #0x3f00 mov r0, r3 @ 포인터정렬 @ r3 = 0x50004000 -> page directory 시작주소 ➊ mov r9, r0, lsr #18 @ 18비트만큼 right shift, ➋ mov r9, r9, lsl #18 @ 다시 18비트만큼 left shift ->r9 = start of RAM add r10, r9, #0x10000000 @ r10 = end of RAM mov r1, #0x12 orr r1, r1, #3 << 10 @ r1과 0xC00을 or 연산 -> r1 = 0xC12 @ 3 * 2^10 -> 3k -> 0xC00 /* r2 와 r4 는같음 (zreladdr) */ add r2, r3, #16384 1: cmp r1, r9

5.4 페이지디렉터리엔트리초기화하기 - setup_mmu 레이블 67 orrhs r1, r1, #0x0c @ r1 의값이램영역일경우 set cacheable, bufferable, cmp r1, r10 bichs r1, r1, #0x0c @ r1 의값이램영역이아닐경우 clear cacheable, bufferable str r1, [r0], #4 @ 1:1 mapping add r1, r1, #1048576 teq r0, r2 bne 1b @ 두값이같은지비교 @ 같지않다면뒤쪽에있는레이블 1로점프 mov pc, lr ENDPROC( setup_mmu) @ lr 은 arm4_mmu_cache_on 레이블에서 @ bl setup_mmu 다음주소 코드섹션 ➊에서는페이지디렉터리의시작주소를레지스터 r0에저장한다. 이시작주소는 ZRELADDR(zImage의물리주소 ) - 16KB를통해서구해지며, 커널이미지바로앞에위치하게된다. 또한 16KB의크기를갖는다. ZRELADDR의값은각아키텍처마다달라지며, arch/arm/$(mach)/makefile.boot에서찾아볼수있다. 페이지디렉터리에대해서는 알아봅시다! MMU 페이지테이블 을참조하길바란다. 코드섹션 ➋를통해서페이지디렉터리는메모리를 1MB 단위의섹션 (section) 으로관리한다. 페이지디렉터리내의 4,096개엔트리에대해서접근권한 (access permission) 을읽기 / 쓰기가능으로해준다. 또한 4,096개의엔트리중 256개 (256MB 영역 ) 에대해서는 cacheable, bufferable 설정을해준다. 알아봅시다! MMU 페이지테이블 MMU는가상주소를물리주소로변환 (virtual to physical translation), 메모리접근제어 (memory access permission control), 메모리내의각페이지에대한캐시및쓰기버퍼설정등을한다. 만약 MMU가비활성화되어있으면가상메모리와물리메모리는 1:1 매핑이된다. ARM MMU 하드웨어는 L1과 L2의 2단계구조인멀티레벨페이지테이블 (multilevel page table) 구조를갖는다. L1 페이지테이블은마스터페이지테이블 (master page table) 이라고하고, 각엔트리에는 L2 페이지테이블의시작주소를가지며, 1MB 크기의페이지변환을한다. 이것때문에섹션페이지테이블 (section page table) 이라고부르기도한다. 마스터 L1 페이지테이블은 4GB 를 1MB의섹션으로나눔에따라 4,096의페이지엔트리를갖는다.

68 Chapter 5 커널압축해제준비하기 앞서소개된코드 5-5 상에서는마스터 L1 페이지테이블이크기가 1MB 인가상페이지의시작주소를갖 는섹션페이지테이블의역할을한다. 리눅스에서사용하는섹션테이블 (section table) 의각섹션엔트리 (section entry) 는그림 5-5 와같다. Section Entry [31] [20] [19] [12] [11][10][9] [8] [5] [4][3][2][1][0] Base Address SBZ AP 0 Domain 1 C B 1 0 그림 5-5 MMU 섹션테이블엔트리 알아봅시다! 캐시및쓰기버퍼 프로세서에서쓰기를수행하는속도와메모리에서쓰기를처리하는속도는매우큰차이를나타낸다. 프로세서에서의쓰기명령이완료될때까지프로세서는기다려야한다. 메모리쓰기는프로세서입장에서매우많은클럭 (clock) 을소모해야하는일이기때문에쓰기버퍼를통해서이러한지연이발생하는것을어느정도대비한다. 쓰기버퍼 (write buffer) 란매우작고빠른 FIFO 메모리버퍼이며, 메인메모리에쓰여져야하는데이터를일시적으로저장함으로써프로세서가메모리에쓰기동작시필요한클럭소모를줄여준다. 마찬가지로프로세서에서읽기를수행하는속도와메모리에서읽기를처리하는속도는매우큰차이를나타낸다. 프로세서에서의읽기명령이완료될때까지프로세서는기다려야한다. 캐시 (cache) 는매우빠른속도의저장장치이며, 임시적으로프로세서가메모리로부터읽어온코드혹은데이터를저장한다. 이를통해서프로세서가최근에한번읽었던데이터에접근할때메모리접근에필요한클록소모를줄여준다. 앞서소개한코드 5-5에서 256개의엔트리에대해서 cacheable, bufferable 설정을하는것을보았다. 이를통해서 256개의섹션내의데이터들의읽기 / 쓰기수행시캐시와쓰기버퍼가사용된다. 섹션엔트리내에설정되는값은그림 5-6과같다. Section Entry [31] [20] Base Address 0xC12 0xC1E [19] [12] [11][10] [9] [8] [5] [4] [3] [2] [1] [0] SBZ AP 0 Domain 1 C B 1 0 1 1 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 1 1 1 1 0 fixed Cacheable Bufferable Section Entry 그림 5-6 MMU 섹션엔트리에설정되는값들

5.5 I-Cache 활성화및캐시정책적용하기 - common_mmu_cache_on 레이블 69 5.5 I-Cache 활성화및캐시정책적용하기 - common_mmu_cache_on 레이블 common_mmu_cache_on 은 cache_on 레이블내에서호출되며, ARM 버전 7 이전의 프로세서에대해서만수행된다. I-Cache 활성화및캐시교체정책을 CP15 에적용하고, TTBR 을초기화한다. 코드 5-6 을통해커널이어떻게 I-Cache 를활성화하고캐시정책 을적용하는지알아보도록하자. 코드 5-6 arch/arm/boot/compressed/head.s 의 common_mmu_cache_on 레이블 common_mmu_cache_on: mcr p15, 0, r3, c2, c0, 0 @ 페이지테이블주소를저장 ➊ 1: mcr p15, 0, r0, c1, c0, 0 @ r0을컨트롤레지스터에넣기 ➋ mrc p15, 0, r0, c1, c0, 0 sub pc, lr, r0, lsr #32 우선코드섹션 ➊에서는레지스터 r3에저장되어있는페이지디렉터리의주소값을 CP15 에있는 TTBR에저장한다. 코드섹션 ➋에서는 armv4_mmu_cache_on 레이블에서설정해준라운드로빈캐시교체정책, I-Cache 활성화설정을 CP15의제어레지스터 (control register) 에적용한다.