Kernel 2.6 makefile 분석 LKSAS 3기 송형주.

Slides:



Advertisements
Similar presentations
Wireless & Mobile Communication system LAB TinyOS 의 메시지 형식 및 자바 응용 프로그램들 조선대학교 정보통신공학과 변재영 본 자료는 한백전자 교육자료를 이용하여 제작되었음을 밝힙니다.
Advertisements

Format String Attack! 포맷 스트링 공격 경일대학교 사이버보안학과 학년 남주호.
기초C언어 제1주 실습 강의 소개, C언어 개요, Cygwin/Eclipse 사용 컴퓨터시뮬레이션학과 2016년 봄학기
GTK 프로그래밍 ( 1 ) SNSLAB 발표 : 문동규.
컴퓨터프로그래밍 1주차실습자료 Visual Studio 2005 사용법 익히기.
Image & Video processing
1. 신뢰할 수 있는 싸이트 등록 인터넷 익스플로러 실행 후 실행
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
Cross Compiler를이용한 커널 컴파일 및 포팅
커널 컴파일 및 개발 환경 구축 IT EXPERT 리눅스 커널 프로그래밍 Author : Byungki Kim
컴퓨터 프로그래밍 기초 [Final] 기말고사
리눅스 기본 명령어 및 Vi 명령어 정리 2015/1, 컴퓨터의 개념 및 실습.
데이터 파일 C 데이터 파일과 스트림(Stream) 텍스트 파일 처리
나민영 서경대학교 컴퓨터공학과 CGVR Lab 같이만들어보자 5주차 OpenCV 설정 및 기초.
QT 프로그래밍 발표: 김래영.
임베디드 리눅스 설치 및 동작 Lecture #5.
어셈블리 문법 보강 4월 10일.
임베디드 시스템 개론 크로스 플랫폼 설치 2일차 강의 자료 Embedded System Lab.
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
Homework #6 (1/3) 다음을 수행한 후, 화면(혹은 파일)을 출력하여 제출한다.
제 3장. C보다 나은 C++ II.
07. 디바이스 드라이버의 초기화와 종료 김진홍
CHAPTER 02 OpenCV 개요 PART 01 영상 처리 개요 및 OpenCV 소개.
Root Filesystem Porting
C / C++ Programming in multi platform
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
Root Filesystem Porting
부트로더와 Self Programming
WinCE Device Driver 실습 #3
WinCE Device Driver 실습 #2
Lecture 4 Debugging Technique & LKM
Cross Compiler 설치.
Cross Compiler를이용한 커널 컴파일 및 포팅
AVR – ATmega103(ATMEL) Compilers & ISP
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
리눅스 시스템 & 커널 기초 P.46 – P.53 이름: nsh009 학번: 112 1/20.
솔라리스10 3장. 솔라리스 패키지 관리.
이름 : 황 상 두 전화번호 : 이메일 : PinTool 이름 : 황 상 두 전화번호 : 이메일 :
27장. 모듈화 프로그래밍.
Homework #6 (1/3) 다음을 수행한 후, 화면(혹은 파일)을 출력하여 제출한다.
Device Driver 임베디드 시스템 I.
영상처리 실습 인공지능연구실.
cafe.naver.com/embeddedcrazyboys
ADC 디바이스 사용법.
Homework #6 (1/3) 다음을 수행한 후, 화면(혹은 파일)을 출력하여 제출한다.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
1. 스크립트 작성 마법사 2. NSIS 스크립트 컴파일
컴퓨터 계측 및 실습 디지털 출력 영남대학교 기계공학부.
네트워크 환경 구축과 이미지 전송 호스트/타겟 통신 직렬 통신을 이용한 이미지 전송 수퍼 데몬 BOOTP 환경 구축
Canary value 스택 가드(Stack Guard).
Kernel, Ramdisk, JFFS2 Porting
PHP 웹 프로그래밍 (PHP Web Programming) 미리 정의된 함수 문양세 강원대학교 IT대학 컴퓨터과학전공.
제 6 강 Getting started.
OpenCV 설정 2.21 만든이 딩딩.
Homework #5 (1/3) 다음을 수행한 후, 결과 파일들을 출력하여 제출한다.
01. 분산 파일 시스템의 개요 네트워크에 분산된 파일을 사용자가 쉽게 접근하고 관리할 수 있게 해준다.
셀프 프로그래밍으로 쓰기 셀프 프로그래밍이란? 프린트포트의 ISP 모듈을 사용하지 않음 부트로더에 의한 펌웨어 다운로드
기초C언어 제2주 실습 프로그래밍의 개념, 프로그램 작성 과정 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원
시스템 인터페이스 Lab1 X-window 및 명령어 사용.
Homework #3 (1/3) 다음을 수행한 후, 결과 파일들을 출력하여 제출한다.
과제 4: Thread (5월 9일까지) 4장 연습문제 풀이
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
1. 지역변수와 전역변수 2. auto, register 3. static,extern 4. 도움말 사용법
Homework #7 (1/3) 1. 다음 순서에 따라 수행하고, 그 과정의 화면을 캡쳐한다.
Docker Study 6~7.
1장. C Language Synopsis.
시스템 해킹과 보안 permission과 SetUID.
1. 실습 시간에 수행한 avd 생성 및 실행, adb shell 접속 및 명령어 수행 결과를 제출한다.
Presentation transcript:

kernel 2.6 makefile 분석 LKSAS 3기 송형주

Kernel Makefile 제대로 분석하려면? GNU make, gcc, ld manual Kbuild System (Documents/kubild/makefiles.txt) 쉘 스크립트 Linux Binary Utilities (binutils) ELF file format 임베디드 시스템 엔지니어를 위한 리눅스 커널 분석 (http://kldp.org/KoreanDoc/html/EmbeddedKernel-KLDP/) 백창우, ‘유닉스,리눅스 프로그래밍 필수 유틸리티’ make, binutil 등 설명이 잘되어 있음. ^^

Linux Kernel Source Tree

kbuild overview vmlinux와 modules 생성 $(TOP)/Makefile – 최상위 Makefile .config – 커널 설정 파일 make [config | menuconfig | xconfig] 를 통해 생성. arch/$(ARCH)/Makefile - 아키텍처별 makefile scripts/Makefile.* - 모든 kbuild Makefile에 사용되는 규칙이 들어있는 파일 kbuild Makefiles – 약 500개 정도가 있다.

Kbuild의 실행 절차 커널 설정 (make config|menuconfig|xconfig) 커널 버전을 include/linux/version.h 에 저장 include/asm-$(ARCH)에 대한 심볼릭 링크 만듬 arch/$(ARCH)/Makefile 에서 정의된, 그외의 타겟 빌딩을 위한 모든 종속 리스트를 준비 init-*, core-*, driver-*, net-* 등의 타겟 등을 만듬 모든 오브젝트들이 링크되고, 소스 트리의 루트 디렉토리에 vmlinux를 만듬. 최종 부트이미지(bzImage)를 만들기 위한 아키텍처에 따른 부분이 실행됨 (Documentation/kbuild/makefile.txt 참조)

Built-in object goals (obj-y) specifying object files for vmlinux “$(LD) –r” : to merge $(obj-y) files into one built-in.o file ex. $(TOP)/kernel/Makefile

Loadable module goals – (obj-m) object files which are built as loadable kernel modules. ex. $(TOP)/kernel/Makefile ex. $(TOP)/.config 참고!! 커널에 포함되지 않은 external module을 컴파일 하기위해서는 Documentation/kbuild/modules.txt를 참조 디바이스 드라이버 개발

Building non-kbuild targets (extra-y) obj-y에 지정된 타겟이 아닌, 현재 디렉토리에서 만들어지는 추가 타겟을 지정 즉, obj-y로 지정되지 않았기 때문에, built-in.o 로 같이 linking되지 않음. (내 생각) : 커널 빌드 시, 아키텍처 종속적인 부분의 처리를 위해서 사용하는 듯?? ex. $(TOP)/arch/x86_64/kernel/Makefile

Environment Variables value Description V 빌드시에, 현재 컴파일되는 파일명만을 보여줌. (default) 1 빌드시에 실행되는 모든 명령 및 메시지를 보여줌. O dir 컴파일 되는 모든 output file들을 dir에 저장되게 지정 C 빌드과정에서 sparse tool이 컴파일된 파일을 체크하게끔 한다. sparse은 커널 소스 파일의 프로그래밍 에러를 찾는 툴이다. 2 sparse tool은 컴파일에 관계없이 모든 파일을 체크하게끔 한다. Example : make V=1 ARCH=x86_64

$(top)/Makefile 커널 빌드시, 명령 및 메시지 출력 옵션 커널 빌드시, 소스 코드 체크 옵션 빌드된 파일의 출력 디렉토리 지정

How to build vmlinux ?? -Makefile : 아키텍처 독립적인 부분 - arch/x86_64/Makefile : 아키텍처 종속적인 부분

Building vmlinux vmlinux는 $(vmlinux-init)와 $(vmlinux-main)에서 정의된 오브젝트로 만들어진다. 각 오브젝트의 linking 순서가 중요. 링커스크립트 지정 ld -m elf_x86_64 -o vmlinux -T arch/x86_64/kernel/vmlinux.lds arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o init/built-in.o --start-group usr/built-in.o arch/x86_64/kernel/built-in.o arch/x86_64/mm/built-in.o arch/x86_64/crypto/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o block/built-in.o lib/lib.a arch/x86_64/lib/lib.a lib/built-in.o arch/x86_64/lib/built-in.o drivers/built-in.o sound/built-in.o arch/x86_64/pci/built-in.o net/built-in.o --end-group .tmp_kallsyms2.o ld [옵션] 오브젝트파일 .. -m : 어떤 포맷으로 출력물을 만들 것인가?? -T: 링커 스크립트 지정 --start-group ~ --end-group : ~에 지정된 오브젝트들 서로간에 변수나 함수 참조를 가능하게 함. -o : 출력 파일명 지정 $(vmlinux-init) $(head-y) $(init-y) $(vmlinux-main) vmlinux $(core-y) $(libs-y) $(drivers-y) $(net-y) kallsyms.o

Building bzImage (1/3) 1. arch/x86_64/boot/compressed/vmlinux.bin vmlinux에서 .note 섹션, .comment 섹션 및 모든 심볼들과 재배치 정보들을 제거한 후, 인스트럭션 데이터만을 뽑아, arch/x86_64/boot/compressed/vmlinux.bin 라는 바이너리 파일을 만든다. objcopy -O binary -R .note -R .comment -S vmlinux arch/x86_64/boot/compressed/vmlinux.bin objcopy [옵션] 입력파일 [출력파일] -0 오브젝트형식: 어떤 오브젝트 형식으로 출력 파일을 만들 것인지 지정 (예: elf32-i386, binary) -R 섹션 : 출력 파일에서 해당 섹션을 지운다. -S : 입력 파일의 재배치 정보와 심볼 정보를 출력 파일에 복사하지 않는다. 2. arch/x86_64/boot/compressed/vmlinux.bin.gz 1단계에서 만든, vmlinux.bin을 가장 압축률이 좋은 방법으로 압축해서(-9), vmlinux.bin.gz을 만듬 gzip -f -9 < arch/x86_64/boot/compressed/vmlinux.bin > arch/x86_64/boot/compressed/vmlinux.bin.gz

Building bzImage (2/3) 3. arch/x86_64/boot/compressed/piggy.o 링커 스크립트(vmlinux.scr)를 이용해서 vmlinux.bin.gz을 ELF 오브젝트 파일인 piggy.o로 링킹 ld -m elf_i386 -r --format binary --oformat elf32-i386 -T arch/x86_64/boot/compressed/vmlinux.scr arch/x86_64/boot/compressed/vmlinux.bin.gz -o arch/x86_64/boot/compressed/piggy.o 4. arch/x86_64/boot/compressed/vmlinux head.o + misc.o + piggy.o 를 링킹해서, vmlinux를 만듬, 이 때 .text 섹션은 0x100000 위치부터, 엔트리포인트는 startup_32로 지정한다. ld -m elf_i386 -Ttext 0x100000 -e startup_32 -m elf_i386 arch/x86_64/boot/compressed/head.o arch/x86_64/boot/compressed/misc.o arch/x86_64/boot/compressed/piggy.o -o arch/x86_64/boot/compressed/vmlinux ld [옵션] 오브젝트파일 .. -m emulation : 링커에게 해당 타겟 emulation에 맞는 정보를 제공 (예. 링커 스크립트 등) -r : 재할당 가능한 출력 파일을 생성. 즉, ld의 입력 오브젝트로 쓰일 수 있는 출력 파일을 생성. (실제로 piggy.o는 ld로 다시 링킹됨) --format input-format : 입력 오브젝트 파일의 형식 지정 --oformat output-format : 출력 오브젝트 파일의 형식 지정. -o : 출력 파일명 지정 -Ttext org : text 섹션의 시작주소를 org로 지정 -e entry : 엔트리 포인트를 지정한다.

Building bzImage (3/3) 5. arch/x86_64/boot/vmlinux.bin 4단계에서 만든 vmlinux에서 .note 섹션, .comment 섹션 및 모든 심볼들과 재배치 정보들을 제거한 후, 인스트럭션 데이터만을 뽑아, arch/x86_64/boot/vmlinux.bin 라는 바이너리 파일을 만든다. objcopy -O binary -R .note -R .comment -S arch/x86_64/boot/compressed/vmlinux arch/x86_64/boot/vmlinux.bin 6. arch/x86_64/boot/bzImage bootsect + setup + vmlinux.bin 를 합쳐서, bzImage 파일을 만든다. arch/x86_64/boot/tools/build -b arch/x86_64/boot/bootsect arch/x86_64/boot/setup arch/x86_64/boot/vmlinux.bin CURRENT > arch/x86_64/boot/bzImage

결론 - Kernel Build Process

참고 : kernel Makefile 계층도

참고 : kernel 2.6 vmlinux.lds 링커 스크립터 분석 송형주

vmlinux.lds 첫 부분. 12 OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") 13 OUTPUT_ARCH(i386:x86-64) /* 프로그램의 엔트리포인트를 지정 */ 14 ENTRY(phys_startup_64) 15 jiffies_64 = jiffies; 16 _proxy_pda = 0; 실행 가능한 ELF 오브젝트 파일은 프로그램 헤더를 사용해서, 시스템 로더에서 읽히고, 메모리로 적재되는 방법을 설명 보통 디폴트 프로그램 헤더가 사용되지만, PHDRS 명령을 사용해 직접 정의 가능 PHDRS 명령 문법 name : 링커 스크립트의 SECTION 명령에서의 참조 type PT_LOAD ( 이 프로그램 헤더가 파일로부터 로드되는 세그먼트를 기술함 PT_NOTE ( 참고 정보를 갖는 세그먼트) FLAGS(flags) : 명시적으로 세그먼트 플래그를 지정 (flags 값은 정수여야함, R:4, W:2, E:1) PHDRS { name type [ FILEHDR ] [ PHDRS ] [ AT ( address ) ] [ FLAGS ( flags ) ] ; } 17 PHDRS { 18 text PT_LOAD FLAGS(5); /* R_E */ 19 data PT_LOAD FLAGS(7); /* RWE */ 20 user PT_LOAD FLAGS(7); /* RWE */ 21 data.init PT_LOAD FLAGS(7); /* RWE */ 22 note PT_NOTE FLAGS(4); /* R__ */ 23 }

Text Section 분석 .text 섹션 정의 24 SECTIONS 25 { 26 . = __START_KERNEL; - 엔트리 포인트 정의 - 심볼에 값 할당 - 출력 섹션의 위치와 어떤 입력 섹션이 그 안으로 들어갈지 결정 여기서 ‘.’ 은 특수한 링커 변수 dot 로 현재 출력 위치를 지정함. 24 SECTIONS 25 { 26 . = __START_KERNEL; 27 phys_startup_64 = startup_64 - LOAD_OFFSET; 28 _text = .; /* Text and read-only data */ 29 .text : AT(ADDR(.text) - LOAD_OFFSET) { 30 /* First the code that has to be first for bootstrapping */ 31 *(.bootstrap.text) 32 /* Then all the functions that are "hot" in profiles, to group them 33 onto the same hugetlb entry */ 34 #include "functionlist" 35 /* Then the rest */ 36 *(.text) 37 SCHED_TEXT 38 LOCK_TEXT 39 KPROBES_TEXT 40 *(.fixup) 41 *(.gnu.warning) 42 } :text = 0x9090 43 /* out-of-line lock text */ 44 .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) } 45 46 _etext = .; /* End of text section */ __START_KERNEL = 0x100100 + 0xFFFFFFFF80000000 (LOAD_OFFSET) 링커에서 정의한 변수 외부 소스 파일에서 extern을 선언해 접근 가능 ADDR(section) - 해당 secion의 VMA를 리턴 .text 섹션 정의 섹션을 프로그램 헤더에 의해 기술된 세그먼트에 할당하고, 정의되지 않은 영역은 0x9090의 패턴으로 채움.

Output Section address AT[lma] :phdr =fillexp { output-section-command … } [:phdr][=fillexp] address output section의 VMA(virtual memory address) 정의 AT[lma] output setction의 LMA(Load Memory address) 정의 :phdr Program Header에서 정의한 세그먼트에 해당 섹션을 위치 시킴 =fillexp 섹션 중에 정의되지 않은 영역을 해당값으로 채움

Data Section, BSS Section BSS 영역은 compressed/head.S 에서 0으로 초기화 된다. .bss Section

참고 - .init.text Section Ex. arch/x86_64/kernel/head64.c 에서 static void __init copy_bootdata(char *real_mode_data) { .. } 여기서 함수 앞에 쓰인 __init은 include/linux/init.h에 다음과 같이 정의되어 있다. #define __init __attribute__ ((__section__ (".init.text"))) 이 섹션들은 init 커널스레드의 free_initmem() 함수에서 삭제된다.

ELF Format Object files participate in program linking (building a program) and program execution (running a program).

Program Loading

(예제) readelf -l vmlinux 메모리에 올릴 수 있는 프로그램 세그먼트 보조정보 세그먼트 Section to Segment mapping: Segment Sections... 00 .text __ex_table .rodata .pci_fixup __ksymtab __ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __param __bug_table 01 .data .data.cacheline_aligned .data.read_mostly 02 .vsyscall_0 .xtime_lock .vxtime .vgetcpu_mode .sys_tz .sysctl_vsyscall .xtime .jiffies .vsyscall_1 .vsyscall_2 .vsyscall_3 03 .data.init_task .data.page_aligned .smp_locks .init.text .init.data .init.setup .initcall.init .con_initcall.init . security_initcall.init .altinstructions .altinstr_replacement .exit.text .init.ramfs .data.percpu .data_nosave .bss 04

참고 : vmlinux.scr SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; } 압축된 vmlinux.bin.gz는 .data 섹션에 포함되므로, *(.data)로 표시된 곳에 들어가게 된다. 그 전후에 LONG(input-data-end - input-data)로 압축된 커널의 크기를 저장한다. 위의 input_data 변수는 커널 압축을 푸는, arch/x86_64/boot/compressed/misc.c에서 이용됨.

참고 : 커널 빌드시, Log 남기기 make V=1 ARCH=x86_64 2>&1 | tee log-bzImage.txt