62
The place for generating the top 1% software experts Linux Booting 과과 과과 백 백 백 [email protected]

Linux Booting 과정 이해

Embed Size (px)

DESCRIPTION

Linux Booting 과정 이해. 백 창 우 [email protected]. 강의 목표. kernel source 의 분석 기법을 이해한다 . ctags, cscope, source navigation 등의 사용법을 익힌다 . Linux 의 부팅 과정을 이해한다 . kernel 의 초기화 code 를 이해한다 . init process 의 역할에 대해서 이해한다 . 부팅 스크립트를 이해한다 . 실제 kernel 초기화 코드를 분석해 본다. Booting 의 의미. booting 의 정의 - PowerPoint PPT Presentation

Citation preview

Page 1: Linux Booting  과정 이해

The place for generating the top 1% software experts

Linux Booting 과정 이해

백 창 우[email protected]

Page 2: Linux Booting  과정 이해

The place for generating the top 1% software experts

강의 목표☞ kernel source 의 분석 기법을 이해한다 .☞ ctags, cscope, source navigation 등의 사용법을 익힌다 . ☞ Linux 의 부팅 과정을 이해한다 .☞ kernel 의 초기화 code 를 이해한다 .☞ init process 의 역할에 대해서 이해한다 .☞ 부팅 스크립트를 이해한다 .☞ 실제 kernel 초기화 코드를 분석해 본다 .

Page 3: Linux Booting  과정 이해

The place for generating the top 1% software experts

Booting 의 의미☞ booting 의 정의

: kernel 이 메모리에 올려지고 하드웨어가 초기화 되어 바로 사용 가능한 상태로 만드는 과정을 부팅이라고 한다 .

☞ booting 의 목적- processor 초기화- memory 점검 및 초기화- 각종 하드웨어 점검 및 초기화- kernel loading- kernel 자료구조 등록 및 초기화- 사용환경 조성

Page 4: Linux Booting  과정 이해

The place for generating the top 1% software experts

부팅 과정 도식도 (1/5)

ROM BIOS HDD 의 MBR

FDD 의 MBRVGA 체크

Memory 체크IDE 장치 체크

각종 장치 정보 수집

VGA 체크Memory 체크IDE 장치 체크

각종 장치 정보 수집

MBR 에 있는 Bootloader 로딩 또는 bootsect.S 로딩

MBR 에 있는 Bootloader 로딩 또는 bootsect.S 로딩

Flash Memory

Power OnPower On

SUN Sparc, …

Intel ix86

StrongARM, XScale, …

Page 5: Linux Booting  과정 이해

The place for generating the top 1% software experts

부팅 과정 도식도 (2/5)

kernel 을 main memory 로 로딩kernel 을 main memory 로 로딩 kernel 압축 해제kernel 압축 해제

Page 6: Linux Booting  과정 이해

The place for generating the top 1% software experts

부팅 과정 도식도 (3/5)

초기화 code 수행

start_kernel() { Architecture 의존적인 설정 trap 에 대한 초기화 Interrupt 에 대한 초기화 Scheduler 에 대한 초기화 softirq 에 대한 초기화 Timer 초기화 Console 초기화 kernel module 사용을 위한 초기화 kernel cache 에 대한 초기 설정 Clock tick 과 BogoMIPS 를 구함 buddy system 사용을 위한 memory 초기화 kernel cache 에 대한 초기화 fork 에 관한 초기화 (max threads) 각종 kernel cache 및 buffer 에 대한 생성 및 초기화 /proc 디렉토리에 대한 초기화 IPC 에 대한 초기화 SMP 에 대한 초기화 init kernel thread 시작 kernel idle}

start_kernel() { Architecture 의존적인 설정 trap 에 대한 초기화 Interrupt 에 대한 초기화 Scheduler 에 대한 초기화 softirq 에 대한 초기화 Timer 초기화 Console 초기화 kernel module 사용을 위한 초기화 kernel cache 에 대한 초기 설정 Clock tick 과 BogoMIPS 를 구함 buddy system 사용을 위한 memory 초기화 kernel cache 에 대한 초기화 fork 에 관한 초기화 (max threads) 각종 kernel cache 및 buffer 에 대한 생성 및 초기화 /proc 디렉토리에 대한 초기화 IPC 에 대한 초기화 SMP 에 대한 초기화 init kernel thread 시작 kernel idle}

각종 interface 장치 초기화network interface 초기화initrd 로딩 및 ‘ /’ mountfree memory 재 계산console open/sbin/init process 수행

각종 interface 장치 초기화network interface 초기화initrd 로딩 및 ‘ /’ mountfree memory 재 계산console open/sbin/init process 수행

init kernel thread

Page 7: Linux Booting  과정 이해

The place for generating the top 1% software experts

부팅 과정 도식도 (4/5)

/sbin/init 수행

signal handler 설정console 설정/etc/inittab 파일 read/etc/rc.d/rc.sysinit script 수행/etc/rc.d/rc script 수행/sbin/mingetty 수행run level 5 이면 /etc/X11/prefdm 수행

signal handler 설정console 설정/etc/inittab 파일 read/etc/rc.d/rc.sysinit script 수행/etc/rc.d/rc script 수행/sbin/mingetty 수행run level 5 이면 /etc/X11/prefdm 수행

host name 설정시간 설정usb 설정file system checkISA 설정sound 설정

host name 설정시간 설정usb 설정file system checkISA 설정sound 설정

run level 에 따른 /etc/rc*.d 디렉토리의script 를 수행

run level 에 따른 /etc/rc*.d 디렉토리의script 를 수행

가상 터미널을 띄우고login 프로그램 실행

가상 터미널을 띄우고login 프로그램 실행

gdm 또는 kdm 또는 xdm 실행 gdm 또는 kdm 또는 xdm 실행

/etc/X11/prefdm

/sbin/mingetty

/etc/rc.d/rc 3

/etc/rc.d/rc.sysinit

Page 8: Linux Booting  과정 이해

The place for generating the top 1% software experts

부팅 과정 도식도 (5/5)

/sbin/login

인증 수행 후 shell 실행인증 수행 후 shell 실행

Shell 실행

Page 9: Linux Booting  과정 이해

The place for generating the top 1% software experts

ROM BIOS (1/2)

BIOS (Basic Input Output) 의 의미: 하드웨어 안에는 그 하드웨어의 input/output 을 제어할 수 있는 프로그램이 내장되는데 그러한 프로그램을 BIOS (Basic Input Output) 라 한다 . 이러한 BIOS 는 통상 내용이 지워지지 않는 ROM chip 에 내장되게 되는데 그래서 ROM BIOS 라 부른다 . I386 PC 에서 ROM BIOS 가 하는 일은 크게 3 부분으로 나눌 수 있고 다음과 같다 .

전원이 들어 오는 순간 모든 부품이 초기화 된다 . 만약 초기화 시키지 않으면 기존의 정보가 남아서 오작동을 일어 킬 수 있다 . 그리고 시스템의 정상 여부를 검색하여 이상 유무를 테스트한다 .CPU, VGA, RAM 등이 주요 검색 대상이 된다 .

전원이 들어 오는 순간 모든 부품이 초기화 된다 . 만약 초기화 시키지 않으면 기존의 정보가 남아서 오작동을 일어 킬 수 있다 . 그리고 시스템의 정상 여부를 검색하여 이상 유무를 테스트한다 .CPU, VGA, RAM 등이 주요 검색 대상이 된다 .

POST (Power On Self Test) 과정

ROM BIOS 내부에 있는 인터럽트 핸들러로 인터럽트 백터 테이블을 구성한다 . 그리고 시스템에 장착되어 있는 장치들의 상태를 알아내 메모리의 하위 번지 (0x0800~0x1000) 에 기록한다 .확장 BIOS 와 SCSI 카드를 검색하여 메모리 하위 번지에 기록한다 .

ROM BIOS 내부에 있는 인터럽트 핸들러로 인터럽트 백터 테이블을 구성한다 . 그리고 시스템에 장착되어 있는 장치들의 상태를 알아내 메모리의 하위 번지 (0x0800~0x1000) 에 기록한다 .확장 BIOS 와 SCSI 카드를 검색하여 메모리 하위 번지에 기록한다 .

시스템 초기화

Boot strap 루틴이 CMOS 에 저장되어 있는 boot device 순서를 참조하여 boot driver 의 boot sector로 부터 boot strap code 를 RAM 으로 loader 하고 제어를 넘긴다 .

Boot strap 루틴이 CMOS 에 저장되어 있는 boot device 순서를 참조하여 boot driver 의 boot sector로 부터 boot strap code 를 RAM 으로 loader 하고 제어를 넘긴다 .

Disk Boot

Page 10: Linux Booting  과정 이해

The place for generating the top 1% software experts

ROM BIOS (2/2)

BIOS 의 구조 CMOS 의 구조

POST 과정

Page 11: Linux Booting  과정 이해

The place for generating the top 1% software experts

MBR 의 이해 (1/2)

플래터의 구조MBR트랙 0, 섹터 1

MBR 의 이해: MBR 이란 하드디스크로 부팅하기 위한 boot loader 와 파티션 분할 정보 , 부팅에 사용되는 실제 파티션 (ACTIVE PARTITION) 에 대한 정보가 저장된 곳으로 하드디스크의 제일 바깥쪽에 위치한 공간으로 ( 절대섹터 0(Cylinder 0, Head 0, Sector 1), 크기 :1sector(512byte)) 하드 디스크로 들어오는 관문이 되는 곳이다 . MBR 은 boot sector 에 포함되나 모든 boot sector 가 MBR 은 아니다 . boot sector 는 각 파티션의 첫 번째 sector 를 의미한다 .

Page 12: Linux Booting  과정 이해

The place for generating the top 1% software experts

MBR 의 이해 (2/2)

MBR 이미지 (dd if=/dev/had of=MBR.img bs=1c count=512)

Boot Loader code

Magic number

LILO 문자열 time out 시간

map 파일 image

디스크립트 1 위치

jmp 0x7C

파티션 1

파티션 2

파티션 3

파티션 4

second boot loader 의

위치

fs type

Page 13: Linux Booting  과정 이해

The place for generating the top 1% software experts

Boot Loader 의 역할과 종류☞ Boot Loader 의 역할kernel 을 memory 에 적재하고 제어를 kernel 로 옮긴다 . 또한 OS 를 선택적 부팅 가능하게 하는것도 있으며 serial 을 통한 kernel 다운로드를 제공하기도 한다 . embedded system 을 위한 boot loader 는 BIOS 에서 해주는 하드웨어 초기화 작업을 하기도 한다 .

☞ Boot Loader 의 종류- LILO

: 전통적인 linux boot loader 이다 . 일반적인 boot loader 가 그렇듯 assembly 로 짜여져 있고 크게 MBR 에 들어가는 first.S 와 /boot/boot.b 로 만들어지는 second.S 두 부분으로 이루어져 있다 .

- GRUB: 최근에 주목 받고 있는 boot loader 로서 기능과 유연성 면에서 LILO 보다 앞선다 . GNU 에서 만들었으며 뛰어난 shell interface 를 제공한다 .

- Blob

: ARM SA-11x0 architecture 에서 사용하는 대표적인 boot loader 로서 GNU GPL 이여서 사용에 제한이 없고 serial 을 통한 다운로드를 지원한다 .

- bootsector.S: kernel 에서 제공되는 boot loader 로서 압축된 kernel 의 제일 앞 512byte 공간을 차지하고 있으며 floppy 등으로 부팅할 때 사용되어지고 다른 boot loader 로 부팅할 때는 건너 띄는 부분이다 .

- 기타: 그 외 redboot, angel, bootldr 등이 임베디드 시스템용 boot loader 로 많이 사용되고 있다 .

Page 14: Linux Booting  과정 이해

The place for generating the top 1% software experts

LILO first.S loading

first.SBIOS 의 시스템 초기화가 끝날 무렵 MBR 에 있는 LILO 의 first.S 를 메모리의 0x7C00 (0x7C0:0x0000) 으로 옮기고제어를 0x7C00 으로 넘긴다 . 이후 모든 설명은 LILO 를 기준으로 설명하고자 한다 .

BIOS 의 시스템 초기화가 끝날 무렵 MBR 에 있는 LILO 의 first.S 를 메모리의 0x7C00 (0x7C0:0x0000) 으로 옮기고제어를 0x7C00 으로 넘긴다 . 이후 모든 설명은 LILO 를 기준으로 설명하고자 한다 .

0x7C00

Page 15: Linux Booting  과정 이해

The place for generating the top 1% software experts

first.S 의 자기 복제

지금부터 설명할 LILO 의 버전은 21.X.X 이하를 기준으로설명하고자 한다 . 현재 LILO 의 최신 버전은 지금을 설명과는다른 모습을 띠고 있으나 부팅 과정을 이해 하는데는 상관이없을 것으로 보인다 .

1. 0x7C00 으로 제어를 옮긴 first.S 는 내부의 start 라벨로 jump 한 후 0x7C00 에 있는 자기 자신을 0x9A000 으로 복사하고 제어를 0x9A000 이후로 옮긴다 .

2. 0x9A200 ~ 0x9B000까지를 stack 으로 설정한다 . mov ss, #0x9000 mov sp, #0xB000

3. 화면에 ‘ L’ 을 출력한다 .

지금부터 설명할 LILO 의 버전은 21.X.X 이하를 기준으로설명하고자 한다 . 현재 LILO 의 최신 버전은 지금을 설명과는다른 모습을 띠고 있으나 부팅 과정을 이해 하는데는 상관이없을 것으로 보인다 .

1. 0x7C00 으로 제어를 옮긴 first.S 는 내부의 start 라벨로 jump 한 후 0x7C00 에 있는 자기 자신을 0x9A000 으로 복사하고 제어를 0x9A000 이후로 옮긴다 .

2. 0x9A200 ~ 0x9B000까지를 stack 으로 설정한다 . mov ss, #0x9000 mov sp, #0xB000

3. 화면에 ‘ L’ 을 출력한다 .

0x7C00first.S

first.S

0x9A000

Stack0x9A200

0x9B000

Page 16: Linux Booting  과정 이해

The place for generating the top 1% software experts

second.S load

1. 하드 디스크상의 second.S 를 메모리 0x9B000 번지로 로딩한다 .

하드 디스크상의 위치는 lilo명령어를 내릴 때 first.S 에 저장된 값이고 second.S 는 /boot/boot.b 를 의미한다 .

2. ‘I’ 를 화면에 출력하고 제어를 second.S 로 옮긴다 .

1. 하드 디스크상의 second.S 를 메모리 0x9B000 번지로 로딩한다 .

하드 디스크상의 위치는 lilo명령어를 내릴 때 first.S 에 저장된 값이고 second.S 는 /boot/boot.b 를 의미한다 .

2. ‘I’ 를 화면에 출력하고 제어를 second.S 로 옮긴다 .

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Page 17: Linux Booting  과정 이해

The place for generating the top 1% software experts

second.S 의 초기화 작업

1. 터미널 부팅을 사용하는가 체크하고 사용한다면 시리얼 포트를 설정한다 .

2. 키보드 버퍼를 비운다 .

3. 화면에 ‘ L’ 을 출력한다 .

1. 터미널 부팅을 사용하는가 체크하고 사용한다면 시리얼 포트를 설정한다 .

2. 키보드 버퍼를 비운다 .

3. 화면에 ‘ L’ 을 출력한다 .

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

23kjdssadjlkasdsadjlkasksjd=-=

Page 18: Linux Booting  과정 이해

The place for generating the top 1% software experts

Image descriptor table load

1. second.S 는 내부 boot parameter(“LILO”, version) 의 값을 비교하여 second.S 가 제대로 load 되었는가 체크한다 .

2. 부트 이미지들의 정보가 들어있는 Image descriptor table 을 메모리의 0x9D200 에 로드한다 .

Image descriptor table 은 /boot/map 파일 내부에 존재 한다 .

3. checksum 값으로 Image descriptor table 이 정확이 로드 되었는지 점검한다 .

1. second.S 는 내부 boot parameter(“LILO”, version) 의 값을 비교하여 second.S 가 제대로 load 되었는가 체크한다 .

2. 부트 이미지들의 정보가 들어있는 Image descriptor table 을 메모리의 0x9D200 에 로드한다 .

Image descriptor table 은 /boot/map 파일 내부에 존재 한다 .

3. checksum 값으로 Image descriptor table 이 정확이 로드 되었는지 점검한다 .

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Image descriptor table0x9D200

Page 19: Linux Booting  과정 이해

The place for generating the top 1% software experts

Keyboard translation table load

1. keyboard translation table 을 메모리 0x9D800 에 로드 한다 .

keyboard translation table 은 keyboard 에서 넘어오는 scan code 를 ASCII 코드로 변환 시켜 주는 역할을 수행한다 .

keyboard translation table 역시 /boot/map 파일 내부에 존재하고 있다 .

1. keyboard translation table 을 메모리 0x9D800 에 로드 한다 .

keyboard translation table 은 keyboard 에서 넘어오는 scan code 를 ASCII 코드로 변환 시켜 주는 역할을 수행한다 .

keyboard translation table 역시 /boot/map 파일 내부에 존재하고 있다 .

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Image descriptor table0x9D200

keyboard translation table0x9D800

Page 20: Linux Booting  과정 이해

The place for generating the top 1% software experts

Default command line load

1. Default command line 을 메모리 0x9D600 위치에 로드 한다 .

Default command line 역시 /boot/map 파일 내에 존재한다 .

2. ‘O’ 를 화면에 출력한다 .

3. “boot :” prompt 를 출력하고 사용자 입력을 기다린다 .

1. Default command line 을 메모리 0x9D600 위치에 로드 한다 .

Default command line 역시 /boot/map 파일 내에 존재한다 .

2. ‘O’ 를 화면에 출력한다 .

3. “boot :” prompt 를 출력하고 사용자 입력을 기다린다 .

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Image descriptor table0x9D200

Default command line, etckeyboard translation table0x9D800

0x9D600

Page 21: Linux Booting  과정 이해

The place for generating the top 1% software experts

RAM disk 및 initrd load

1. 화면에 “ Loading”을 출력한다 .

2. 사용자의 입력으로 부팅할 boot image 가 선택되면 image descriptor tables 에서 부팅할 image descriptor 를 선택하여 initrd 의 사용 여부를 검사하고 initrd 를 사용한다면 initrd 를 로딩한다 .

initrd 의 로딩을 위해 먼저 메모리 량과 initrd 의 사이즈를 검사한다 .

initrd 로딩시 한 sector 를 읽을 때마다 화면에 ‘ .’ 을 출력

1. 화면에 “ Loading”을 출력한다 .

2. 사용자의 입력으로 부팅할 boot image 가 선택되면 image descriptor tables 에서 부팅할 image descriptor 를 선택하여 initrd 의 사용 여부를 검사하고 initrd 를 사용한다면 initrd 를 로딩한다 .

initrd 의 로딩을 위해 먼저 메모리 량과 initrd 의 사이즈를 검사한다 .

initrd 로딩시 한 sector 를 읽을 때마다 화면에 ‘ .’ 을 출력

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Image descriptor table0x9D200

Default command line, etckeyboard translation table0x9D800

0x9D600typedef struct { char name[MAX_IMAGE_NAME+1]; char password[MAX_PW+1]; unsigned short rd_size[2]; // ram disk size SECTOR_ADDR initrd, start; // image 시작 sector unsigned short start_page; unsigned short flags, vga_mode;} IMAGE_DESCR;

Image descriptor 자료구조

Page 22: Linux Booting  과정 이해

The place for generating the top 1% software experts

Boot map load

1. /boot/map 파일 내에 있는 boot map 을 읽어 메모리의 0x9D000 에 로드 한다 .

이러한 boot map 에는 bootsect.S 의 하드디스크상 위치 정보와 setup.S 의 하드디스크상 위치 정보가 담겨있다 .

1. /boot/map 파일 내에 있는 boot map 을 읽어 메모리의 0x9D000 에 로드 한다 .

이러한 boot map 에는 bootsect.S 의 하드디스크상 위치 정보와 setup.S 의 하드디스크상 위치 정보가 담겨있다 .

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Map load areaImage descriptor table

0x9D200

Default command line, etckeyboard translation table0x9D800

0x9D600

0x9D000

Page 23: Linux Booting  과정 이해

The place for generating the top 1% software experts

Default command line load and save

1. default command line sector( 파일 ) 를 재 로딩하여 매직 넘버를 확인한다 . 그리고 /boot/map 파일의 boot map 상에 fallback sector 가 있다면 default command line( 메모리 ) 을 fallback sector 의 내용으로 덮어 쓴다 .

fallback sector 는 boot map 상의 첫 번째 sector 로서 현재 지정된 kernel image 로 부팅이 실패 되었을 시 다른 kernel 로 부팅 가능하게 다른 kernel 을 지정하는 부분이다 .

2. 기존의 default command line sector( 파일 ) 에 fallback sector 의 내용을 write 한다 .

1. default command line sector( 파일 ) 를 재 로딩하여 매직 넘버를 확인한다 . 그리고 /boot/map 파일의 boot map 상에 fallback sector 가 있다면 default command line( 메모리 ) 을 fallback sector 의 내용으로 덮어 쓴다 .

fallback sector 는 boot map 상의 첫 번째 sector 로서 현재 지정된 kernel image 로 부팅이 실패 되었을 시 다른 kernel 로 부팅 가능하게 다른 kernel 을 지정하는 부분이다 .

2. 기존의 default command line sector( 파일 ) 에 fallback sector 의 내용을 write 한다 .

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Map load areaImage descriptor table

0x9D200

Default command line, etckeyboard translation table0x9D800

0x9D600

0x9D000

Page 24: Linux Booting  과정 이해

The place for generating the top 1% software experts

Parameter line 작성 (1/2)

1. Default command line 에 option sector 를 로드 한다 . option sector 는 /boot/map 파일 내에 존재한다 . option sector 에는 다음과 같은 내용이 들어 있다 . ro BOOT_FILE=/boot/vmlinuz-2.4.20-8 root=LABEL=/

2. “boot :” prompt 로 부터 받은 내용과 option sector 의 내용을 조합하여 Parameter line 을 작성한다 .

1. Default command line 에 option sector 를 로드 한다 . option sector 는 /boot/map 파일 내에 존재한다 . option sector 에는 다음과 같은 내용이 들어 있다 . ro BOOT_FILE=/boot/vmlinuz-2.4.20-8 root=LABEL=/

2. “boot :” prompt 로 부터 받은 내용과 option sector 의 내용을 조합하여 Parameter line 을 작성한다 .

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Map load areaImage descriptor table

0x9D200

Default command line, etckeyboard translation table0x9D800

0x9D600

0x9D000

Page 25: Linux Booting  과정 이해

The place for generating the top 1% software experts

Parameter line 작성 (2/2)

다음은 parameter line 을 작성하는 예를 그림으로 나타내었다 . command line 는 “boot :” prompt 로 부터 받은 정보이고 option sector 가 map 파일로 부터 읽어온 option string 이다 .

다음은 parameter line 을 작성하는 예를 그림으로 나타내었다 . command line 는 “boot :” prompt 로 부터 받은 정보이고 option sector 가 map 파일로 부터 읽어온 option string 이다 .

Page 26: Linux Booting  과정 이해

The place for generating the top 1% software experts

Boot sector load

1. Boot map 으로 부터 boot sector 의 하드 디스크상의 주소를 알아내어 메모리 0x90000 위치에 로드 한다 .

2. command line magic number 위치 (0x90020) 에 magic number 를 기입한다 .

3. 0x90022 위치에 parameter line 의 offset 을 기입한다 .

4. option sector 에 VGA 에 대한 설정이 있는가 확인하고 있다면 메모리 0x506 번지에 쓴다 .

1. Boot map 으로 부터 boot sector 의 하드 디스크상의 주소를 알아내어 메모리 0x90000 위치에 로드 한다 .

2. command line magic number 위치 (0x90020) 에 magic number 를 기입한다 .

3. 0x90022 위치에 parameter line 의 offset 을 기입한다 .

4. option sector 에 VGA 에 대한 설정이 있는가 확인하고 있다면 메모리 0x506 번지에 쓴다 .

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Map load areaImage descriptor table

0x9D200

Default command line, etckeyboard translation table0x9D800

0x9D600

0x9D000

0x90000boot sector

Page 27: Linux Booting  과정 이해

The place for generating the top 1% software experts

setup.S load

1. setup.S 를 하드 디스크에서 읽어 메모리 0x90200 에 로드한다 .

1. setup.S 를 하드 디스크에서 읽어 메모리 0x90200 에 로드한다 . 0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Map load areaImage descriptor table

0x9D200

Default command line, etckeyboard translation table0x9D800

0x9D600

0x9D000

setup.S

0x90000boot sector0x90200

Page 28: Linux Booting  과정 이해

The place for generating the top 1% software experts

kernel load (1/2)

1. modern kernel(big kernel) 인지 flag 값을 비교하여 확인한다 .

A2. load low(zImage)라면 메모리 0x10000 위치에 kernel 을 로드 한다 .

B2. load high(bzImage)라면 heap 의 사용 가능여부를 따져 보고 사용가능 하다면 loadflags 위치에 LFLAG_USE_HEAP 을 설정한다 .

3. RAM disk 를 사용한다면 setup.S 의 ramdisk_image 와 ramdisk_size 에 initrd 의 시작 주소와 initrd 의 크기를 각각 넣는다 .

B4. 압축된 modern kernel(big kernel) 을 메모리 0x100000 위치에 로드 한다 .

5. 제어를 setup.S 로 옮긴다 .

1. modern kernel(big kernel) 인지 flag 값을 비교하여 확인한다 .

A2. load low(zImage)라면 메모리 0x10000 위치에 kernel 을 로드 한다 .

B2. load high(bzImage)라면 heap 의 사용 가능여부를 따져 보고 사용가능 하다면 loadflags 위치에 LFLAG_USE_HEAP 을 설정한다 .

3. RAM disk 를 사용한다면 setup.S 의 ramdisk_image 와 ramdisk_size 에 initrd 의 시작 주소와 initrd 의 크기를 각각 넣는다 .

B4. 압축된 modern kernel(big kernel) 을 메모리 0x100000 위치에 로드 한다 .

5. 제어를 setup.S 로 옮긴다 .

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Map load areaImage descriptor table

0x9D200

Default command line, etckeyboard translation table0x9D800

0x9D600

0x9D000

setup.S

0x90000boot sector0x90200

Page 29: Linux Booting  과정 이해

The place for generating the top 1% software experts

kernel load (2/2)

0x7C00 first.S

first.S0x9A000

Stack0x9A200

0x9B000second.S

Map load areaImage descriptor table

0x9D200

Default command line, etckeyboard translation table0x9D800

0x9D600

0x9D000

setup.S

0x90000boot sector0x90200

kernel

kernel (not big kernel) 을 로드한 최종 모습

0x10000

Partition table0x7BE

0x7FE

BIOS 에서 메모리에 저장한 정보

Page 30: Linux Booting  과정 이해

The place for generating the top 1% software experts

setup.S (1/4)

세컨드리 하드디스크를 읽는다 .

만약 SAFE_RESET_DISK_CONTROLLER 이 define 되었다면 프라이머리를 읽는다 .

세컨드리 하드디스크를 읽는다 .

만약 SAFE_RESET_DISK_CONTROLLER 이 define 되었다면 프라이머리를 읽는다 .

kernel 이 제대로 로딩되었는지 확인한다 .

(big kernel 은 loadflags 변수에 1 이 들어 있고 type_of_loader 변수에 kernel 을 로딩한 boot loader ids 값이 들어 있음 .)

kernel 이 제대로 로딩되었는지 확인한다 .

(big kernel 은 loadflags 변수에 1 이 들어 있고 type_of_loader 변수에 kernel 을 로딩한 boot loader ids 값이 들어 있음 .)

extended memory size 를 구함

먼저 BIOS function 인 0xe820 을 사용할 수 있는지 체크하고 사용 가능하면 0xe820 을 호출 , 최대 32 번 반복 호출하여 e820map struct 에 저장

(eax = 0xe820; int 0x15)

다음으로 BIOS function 0xe810 을 호출하고 마지막으로 BIOS function 0x88 을 호출하여 extended memory size 를 결정

extended memory size 를 구함

먼저 BIOS function 인 0xe820 을 사용할 수 있는지 체크하고 사용 가능하면 0xe820 을 호출 , 최대 32 번 반복 호출하여 e820map struct 에 저장

(eax = 0xe820; int 0x15)

다음으로 BIOS function 0xe810 을 호출하고 마지막으로 BIOS function 0x88 을 호출하여 extended memory size 를 결정

setup.S 의 마지막 부분에 할당되어 있는 setup_sig1 과 setup_sig2 변수의 값을 읽어 setup.S 가 정상적으로 로딩되었는가 확인한다 . (setup_sig1 = 0xAA55, setup_sig2 = 0x5A5A)

setup.S 의 마지막 부분에 할당되어 있는 setup_sig1 과 setup_sig2 변수의 값을 읽어 setup.S 가 정상적으로 로딩되었는가 확인한다 . (setup_sig1 = 0xAA55, setup_sig2 = 0x5A5A)

arch/i386/boot/setup.S : start_of_setup

start_of_setup:

good_sig1: -> good_sig:

loader_ok:

Page 31: Linux Booting  과정 이해

The place for generating the top 1% software experts

setup.S (2/4)

키보드 설정

delay time = 250ms, rate time = 30.0

키보드 설정

delay time = 250ms, rate time = 30.0

hd0 의 파라메타를 0x90080 으로 16byte 만큼 복사

hd1 의 파라메타를 0x90090 으로 16byte 만큼 복사

hd1 이 있는지 체크

hd0 의 파라메타를 0x90080 으로 16byte 만큼 복사

hd1 의 파라메타를 0x90090 으로 16byte 만큼 복사

hd1 이 있는지 체크

vga 메모리 사이즈와 칼라 모드 설정

vga 의 모드 체크

커스 위치 , 현재의 디스플레이 페이지 , 비디오 모드와 넓이 , 폰트 사이즈 등을 설정

vga 메모리 사이즈와 칼라 모드 설정

vga 의 모드 체크

커스 위치 , 현재의 디스플레이 페이지 , 비디오 모드와 넓이 , 폰트 사이즈 등을 설정

mem88:

arch/i386/boot/video.S : video:

arch/i386/boot/setup.S : mem88:

PS/2 데스크 탑에 관한 정보를 읽어와 MCA(Micro Channel Architecture) bus 를 확인한다 .

( 일반적인 PC 는 IBM PS/2 데스크 탑이 아니기 때문에 no_mca 로 점프 )

PS/2 데스크 탑에 관한 정보를 읽어와 MCA(Micro Channel Architecture) bus 를 확인한다 .

( 일반적인 PC 는 IBM PS/2 데스크 탑이 아니기 때문에 no_mca 로 점프 )

is_disk1:

Page 32: Linux Booting  과정 이해

The place for generating the top 1% software experts

setup.S (3/4)

PS/2 마우스가 있다면 0x901FF 에 0xAA 를 저장PS/2 마우스가 있다면 0x901FF 에 0xAA 를 저장

NMI (Non-Maskable Interrupt) 를 포함하여 모든 interrupt 를 disable 한다 .NMI (Non-Maskable Interrupt) 를 포함하여 모든 interrupt 를 disable 한다 .

APM 의 작동 유무 확인

(APM BIOS 라면 관련 설정을 함 )

APM 의 작동 유무 확인

(APM BIOS 라면 관련 설정을 함 )

no_mca:

no_psmouse:

rmodeswtch_normal: -> default_switch:

code32 변수에 kernel 의 시작 주소를 설정한다 .

(big kernel 이면 code32 = 0x100000 아니면 code32 = 0x1000)

big kernel 이 아니라면 0x10000 에 있는 kernel 을 0x1000 으로 옮긴다 . ( 압축 해제를 위한 공간 확보가 목적 )

code32 변수에 kernel 의 시작 주소를 설정한다 .

(big kernel 이면 code32 = 0x100000 아니면 code32 = 0x1000)

big kernel 이 아니라면 0x10000 에 있는 kernel 을 0x1000 으로 옮긴다 . ( 압축 해제를 위한 공간 확보가 목적 )

rmodeswtch_end:

Page 33: Linux Booting  과정 이해

The place for generating the top 1% software experts

setup.S (4/4)

A20 line 이 사용 가능한가 테스트 한다 . A20 line 이 사용 가능한가 테스트 한다 .

초기 idt 와 gdt 를 설정한다 .

(lidt idt_48; …; lgdt gdt_48;)

coprecess 를 초기화 한다 .

(xorw %ax, %ax; outb %al, $0xf0; outb %al, $0xf1)

IRQ를 재 프로그래밍 해준다 .

protected mode 로 전환 한다 .

kernel 에 제어를 넘긴다 . (arch/i386/boot/compressed/head.S : startup_32)

초기 idt 와 gdt 를 설정한다 .

(lidt idt_48; …; lgdt gdt_48;)

coprecess 를 초기화 한다 .

(xorw %ax, %ax; outb %al, $0xf0; outb %al, $0xf1)

IRQ를 재 프로그래밍 해준다 .

protected mode 로 전환 한다 .

kernel 에 제어를 넘긴다 . (arch/i386/boot/compressed/head.S : startup_32)

empty_8042 루틴을 호출하여 키보드 버퍼를 비운다 .

A20 line 을 enable 시킨다 .

(movb $0xDF, %al; outb %al, $0x60)

empty_8042 루틴을 호출하여 키보드 버퍼를 비운다 .

A20 line 을 enable 시킨다 .

(movb $0xDF, %al; outb %al, $0x60)

a20_none:

a20_kbc:

a20_done:

Page 34: Linux Booting  과정 이해

The place for generating the top 1% software experts

head.S (1/4)

1. 보호모드로 전환된 상태에서 data segment 지정을 위한 각 segment select 에 값을 지정한다 . %es = %fs = %gs = %ds = __KERNEL_DS ( = 0x18) (0x18 은 이진수로 00011000 이고 3bit 우로 shift 하면 0x03 이 된다 . 이 0x03 이 GDT 의 index 가 된다 .)

2. stack 을 설정하고 A20라인이 활성화 되었는지 확인한다 . %ss = KERNEL_DS, %esp = stack_start

1. 보호모드로 전환된 상태에서 data segment 지정을 위한 각 segment select 에 값을 지정한다 . %es = %fs = %gs = %ds = __KERNEL_DS ( = 0x18) (0x18 은 이진수로 00011000 이고 3bit 우로 shift 하면 0x03 이 된다 . 이 0x03 이 GDT 의 index 가 된다 .)

2. stack 을 설정하고 A20라인이 활성화 되었는지 확인한다 . %ss = KERNEL_DS, %esp = stack_start

gdt: .word 0, 0, 0, 0 # dummy .word 0, 0, 0, 0 # unused# kernel code segment .word 0xFFFF # 0x100000*0x1000 = 4Gb .word 0 # base address = 0 .word 0x9A00 # code read/exec .word 0x00CF # granularity = 4096, 386# kernel data segment .word 0xFFFF # 0x100000*0x1000 = 4Gb .word 0 # base address = 0 .word 0x9200 # data read/write .word 0x00CF # granularity = 4096, 386

gdt: .word 0, 0, 0, 0 # dummy .word 0, 0, 0, 0 # unused# kernel code segment .word 0xFFFF # 0x100000*0x1000 = 4Gb .word 0 # base address = 0 .word 0x9A00 # code read/exec .word 0x00CF # granularity = 4096, 386# kernel data segment .word 0xFFFF # 0x100000*0x1000 = 4Gb .word 0 # base address = 0 .word 0x9200 # data read/write .word 0x00CF # granularity = 4096, 386

arch/i386/boot/setup.S

0x0000 0x0000

0x0000 0x0000

0x0000 0x0000

0x0000 0x0000

0x00CF 0x9A00

0x0000 0xFFFF

0x00CF 0x9200

0x0000 0xFFFF

GDT (Global Descriptor Table)

dummy(0)

unused(1)

code (2)

data (3)

Page 35: Linux Booting  과정 이해

The place for generating the top 1% software experts

head.S (2/4)

3. eflags register 를 0 으로 초기화한 후 kernel 내의 BSS 영역을 0 으로 초기화 한다 . (BSS 영역은 _end 심볼의 주소 값에서 _edata 심볼의 주소 값을 뺀 크기이다 . )

4. kernel 압축을 0x100000 위치에 푼다 . “Uncompressing Linux...” 를 출력 후 압축을 풀고 다 푼 후 “ Ok, booting the kernel.”을 출력 normal kernel 이면 0x1000 위치의 압축된 kernel 을 0x100000 위치로 그냥 풀고 big kernel 이면 0x100000 위치의 압축된 kernel 을 임시 buffer 에 풀고 임시 버퍼에 풀린 kernel 을 0x100000 위치에 이동시키기 위한 move_routine_start 루틴을 0x1000 에 이동시키고 제어를 넘긴다 . 제어를 넘겨 받은 move_routine_start 루틴은 0x2000 위치에 압축이 풀린 kernel 을 0x100000 으로 복사하고 제어를 arch/i386/kernel/head.S(0x100000) 로 넘긴다 .

3. eflags register 를 0 으로 초기화한 후 kernel 내의 BSS 영역을 0 으로 초기화 한다 . (BSS 영역은 _end 심볼의 주소 값에서 _edata 심볼의 주소 값을 뺀 크기이다 . )

4. kernel 압축을 0x100000 위치에 푼다 . “Uncompressing Linux...” 를 출력 후 압축을 풀고 다 푼 후 “ Ok, booting the kernel.”을 출력 normal kernel 이면 0x1000 위치의 압축된 kernel 을 0x100000 위치로 그냥 풀고 big kernel 이면 0x100000 위치의 압축된 kernel 을 임시 buffer 에 풀고 임시 버퍼에 풀린 kernel 을 0x100000 위치에 이동시키기 위한 move_routine_start 루틴을 0x1000 에 이동시키고 제어를 넘긴다 . 제어를 넘겨 받은 move_routine_start 루틴은 0x2000 위치에 압축이 풀린 kernel 을 0x100000 으로 복사하고 제어를 arch/i386/kernel/head.S(0x100000) 로 넘긴다 .

normal kernel

zImage

0x1000

vmlinux

0x100000

Page 36: Linux Booting  과정 이해

The place for generating the top 1% software experts

head.S (3/4)

big kernel

bzImage

0x1000000x2000

low buffer

0x1000

vmlinux

0x1000000x2000

vmlinux

Uncompressing

0x90000

0x1000

bzImage

0x100000

move_routine_start

0x2000

vmlinux

move_routine_start 를 복사 후 제어가 넘어감

0x90000

move_routine_start 에 의해 복사된 후 제어가 kernel 로 넘아감

Page 37: Linux Booting  과정 이해

The place for generating the top 1% software experts

head.S (4/4)

5. 제어가 0x100000 위치에 있는 arch/i386/kernel/head.S 에 넘어오면 cs 와 ss 를 제외한 각 segment selector 의 값을 GDT 의 kernel data segment 를 지칭하게 한다 . ds = es = fs = gs = 0x18

6. page table 을 초기화 하고 paging 을 활성화 시킨다 . cr3 = pgd address, cr0 = PG bit “1”

7. stack 을 설정한다 . lss stack_start,%esp

8. BSS 영역을 모두 0 으로 초기화 한다 .

9. default interrupt handler 를 등록한다 .

10. boot parameter 와 command line 을 empty_zero_page(0x104000) 로 옮긴다 .

11. CPU 에 관한 정보를 찾아 설정한다 .

12. start_kernel 로 제어를 옮긴다 .

5. 제어가 0x100000 위치에 있는 arch/i386/kernel/head.S 에 넘어오면 cs 와 ss 를 제외한 각 segment selector 의 값을 GDT 의 kernel data segment 를 지칭하게 한다 . ds = es = fs = gs = 0x18

6. page table 을 초기화 하고 paging 을 활성화 시킨다 . cr3 = pgd address, cr0 = PG bit “1”

7. stack 을 설정한다 . lss stack_start,%esp

8. BSS 영역을 모두 0 으로 초기화 한다 .

9. default interrupt handler 를 등록한다 .

10. boot parameter 와 command line 을 empty_zero_page(0x104000) 로 옮긴다 .

11. CPU 에 관한 정보를 찾아 설정한다 .

12. start_kernel 로 제어를 옮긴다 .

Page 38: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel (1/10)

SMP 일 경우 spin lock 을 건다 . single CPU 는 해당되지 않고 SMP CPU 는 동시에 여러 processor 가 kernel 에 진입하는 것을 방지하기 위함

SMP 일 경우 spin lock 을 건다 . single CPU 는 해당되지 않고 SMP CPU 는 동시에 여러 processor 가 kernel 에 진입하는 것을 방지하기 위함

lock_kernel()

배너를 출력한다 . (init/version.c)Linux version 2.4.20-19.9 ([email protected]) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #1 Tue Jul 15 17:03:30 EDT 2003

배너를 출력한다 . (init/version.c)Linux version 2.4.20-19.9 ([email protected]) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #1 Tue Jul 15 17:03:30 EDT 2003

Page 39: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel (2/10)

1. root device 를 설정하고 BIOS 에서 설정한 정보를 복사한 empty_zero_page 에 있는 정보를 이용하여 drive 와 screen, apm 을 설정한다 .

2. PS/2 mouse 정보를 aux_device_present 에 설정한다 .

3. RAM Disk 를 사용하면 RAM Disk 에 대한 설정을 한다 .

4. memory map 을 구하고 memory map 을 화면에 출력한다 .

5. init_task 에서 사용할 init_mm 을 설정한다 .

6. command line 에 따른 memory map 을 설정한다 .

7. max_low_pfn 에 시스템에서 사용할 수 있는 최대 page 수를 구해준다 .

8. 하이퍼 스레딩 사용 유무를 체크하고 사용하지 않으면 관련 설정을 한다 .

9. PGD, PMD, PT 를 생성 또는 설정하고 memory zone 을 설정하고 free page list 와 free page bitmap 를 설정한다 .

10. memory zone 에 따른 resource 에 관한 정보를 등록한다 .

11. DMI 가 있는지 검색하고 있다면 DMI 설정을 한다 .

1. root device 를 설정하고 BIOS 에서 설정한 정보를 복사한 empty_zero_page 에 있는 정보를 이용하여 drive 와 screen, apm 을 설정한다 .

2. PS/2 mouse 정보를 aux_device_present 에 설정한다 .

3. RAM Disk 를 사용하면 RAM Disk 에 대한 설정을 한다 .

4. memory map 을 구하고 memory map 을 화면에 출력한다 .

5. init_task 에서 사용할 init_mm 을 설정한다 .

6. command line 에 따른 memory map 을 설정한다 .

7. max_low_pfn 에 시스템에서 사용할 수 있는 최대 page 수를 구해준다 .

8. 하이퍼 스레딩 사용 유무를 체크하고 사용하지 않으면 관련 설정을 한다 .

9. PGD, PMD, PT 를 생성 또는 설정하고 memory zone 을 설정하고 free page list 와 free page bitmap 를 설정한다 .

10. memory zone 에 따른 resource 에 관한 정보를 등록한다 .

11. DMI 가 있는지 검색하고 있다면 DMI 설정을 한다 .

setup_arch()

Page 40: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel (3/10)

command line 을 parsing 한다 . 환경변수는 envp_init 에 kernel option 은 argv_init 에 저장

command line 을 parsing 한다 . 환경변수는 envp_init 에 kernel option 은 argv_init 에 저장

parse_options()

trap_init()

1. idt (Interrupt Descriptor Table) 에 예외 처리 핸들러를 등록한다 .

2. CPU 의 register 들을 설정한다 . gdtr = gdt_descr, idtr = idt_descr nested task flag bit clear debug register 들의 값을 0 으로 초기화 FPU 초기화

1. idt (Interrupt Descriptor Table) 에 예외 처리 핸들러를 등록한다 .

2. CPU 의 register 들을 설정한다 . gdtr = gdt_descr, idtr = idt_descr nested task flag bit clear debug register 들의 값을 0 으로 초기화 FPU 초기화

Page 41: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel / trap_init() (1/4)

0 divide_error 11 segment_not_present

1 debug 12 stack_segment

2 nmi 13 general_protection

3 int3 14 page_fault

4 overflow 15 spurious_interrupt_bug

5 bounds 16 coprocessor_error

6 invalid_op 17 alignment_check

7 device_not_available 18 machine_check

8 double_fault 19 simd_coprocessor_error

9 coprocessor_segment_overrun 128 system_call

10 invalid_TSS

IDT (Interrupt Descriptor Table) 내 예외처리 handler

Page 42: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel / trap_init() (2/4)

int 0 (divide_error) DIV 명령어에 의한 나누기 에러 발생시 호출

int 1 (debug) single step 또는 debugging exception

int 2 (nmi) Non-Maskable 인터럽트 발생시

int 3 byte breakpoint 명령어 (0xCC) 에 의해 발생

int 4 (overflow) OF flag 가 설정되었을 때 발생

int 5 (bounds) bound 명령어 실행시 경계 초과에 의해 발생

int 6 (invalid_op) instruction 오류에 의해 발생

IDT (Interrupt Descriptor Table) 내 예외처리 handler

예외 발생시 호출되는 함수는 arch/i386/kernel/entry.S 에서 찾을 수 있다 .

예외 발생시 호출되는 함수는 arch/i386/kernel/entry.S 에서 찾을 수 있다 .

Page 43: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel / trap_init() (3/4)

int 7 (device_not_available) coprocessor 부재

int 8 (double_fault) double fault 에서 발생

int 9 (coprocessor_segment_overrun) 보호모드에서 coprocessor 명령어가 coprocessor 에 전달될 때 , page 또는 segment 침해에 발생

int 10 (invalid_TSS) task 전환 시 새로운 TSS 가 타당하지 않을 때 발생

int 11 (segment_not_present) 보호 모드에서 로딩된 segment 가 시스템에 존재하지 않을 때 발생

int 12 (stack_segment) 보호모드에서 stack segment 변경 시 limit violation 에 의해 발생

int 13 (general_protection) 보호모드에서 심각한 에러가 감지되면 발생

IDT (Interrupt Descriptor Table) 내 예외처리 handler

Page 44: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel / trap_init() (4/4)

int 14 (page_fault) paging system 에서 page access error 시 발생

int 15 (spurious_interrupt_bug) P6 Local APIC Spurious Interrupt Bug 발생시 발생 (linux 에서는 하는 일 없음 )

int 16 (coprocessor_error) coprocessor error 에 의해 발생

int 17 (alignment_check) AC flag 를 설정하였을 시 메모리 정렬 에러에 의해 발생 int 18 (machine_check) 시스템에 설치된 메모리 크기를 반환한다 . (linux 에서는 하는 일 없음 )

int 19 (simd_coprocessor_error) SIMD FPU 예외시 발생

int 128 (system_call) system call 요구 시 발생

IDT (Interrupt Descriptor Table) 내 예외처리 handler

Page 45: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel (4/10)

idt 에 interrupt handler 를 등록한다 . IDT index 32 번부터 시작하여 차례로 등록하고 등록된 IRQ는 시스템마다 다르나 보편적으로 i386계열의 경우 32(IRQ 0) 번은 timer, 33(IRQ 1) 번 keyboard 순으로 등록된다 .

idt 에 interrupt handler 를 등록한다 . IDT index 32 번부터 시작하여 차례로 등록하고 등록된 IRQ는 시스템마다 다르나 보편적으로 i386계열의 경우 32(IRQ 0) 번은 timer, 33(IRQ 1) 번 keyboard 순으로 등록된다 .

init_IRQ()

sched_init()

1. init_task 의 processor 를 설정한다 .

2. pidhash table 을 초기화 한다 .

3. 프로그램 가능한 타이머 벡트를 작성한다 .

4. 하반부 핸들러 루틴들을 셋팅한다 .

1. init_task 의 processor 를 설정한다 .

2. pidhash table 을 초기화 한다 .

3. 프로그램 가능한 타이머 벡트를 작성한다 .

4. 하반부 핸들러 루틴들을 셋팅한다 .

softirq 를 설정한다 .softirq 를 설정한다 .

softirq_init()

Page 46: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel (5/10)

time_init()

console_init()

1. tty_ldisc_N_TTY 자료구조를 정의하고 각 flag 를 셋팅한다 .

2. console_driver 자료 구조를 설정하고 device driver 로 등록한다 .

3. columns 과 row 를 참조하여 사용할 buffer size 를 결정한다 .

4. cursor 크기 및 깜빡임에 대한 설정을 한다 .

1. tty_ldisc_N_TTY 자료구조를 정의하고 각 flag 를 셋팅한다 .

2. console_driver 자료 구조를 설정하고 device driver 로 등록한다 .

3. columns 과 row 를 참조하여 사용할 buffer size 를 결정한다 .

4. cursor 크기 및 깜빡임에 대한 설정을 한다 .

kernel symbol table 의 크기를 결정하여 kernel_module 구조체에 저장한다 .kernel symbol table 의 크기를 결정하여 kernel_module 구조체에 저장한다 .

init_modules()

1. 타임 퀀텀을 구함 .

2. CPU clock 을 구함 .

1. 타임 퀀텀을 구함 .

2. CPU clock 을 구함 .

profiling 을 사용한다면 profile buffer 를 활당한다 .profiling 을 사용한다면 profile buffer 를 활당한다 .

Page 47: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel (6/10)

kmem_cache_init()

calibrate_delay()

보다 높은 정밀도의 delay 를 위해 clock tick 을 구하고 BogoMIPS 를 구한다 .보다 높은 정밀도의 delay 를 위해 clock tick 을 구하고 BogoMIPS 를 구한다 .

1. empty_zero_page 의 하드웨어 정보를 0 으로 초기화 시킨다 .

2. buddy system 을 만들고 , free page 수를 구하고 , 사용하는 page 수 등을 출력한다 .

1. empty_zero_page 의 하드웨어 정보를 0 으로 초기화 시킨다 .

2. buddy system 을 만들고 , free page 수를 구하고 , 사용하는 page 수 등을 출력한다 .

mem_init()

slab 활당자를 위한 cache_cache 구조체의 값들을 셋팅한다 .slab 활당자를 위한 cache_cache 구조체의 값들을 셋팅한다 .

Page 48: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel / mem_init()

buddy System

2^0

2^1

2^2

2^3

2^4

2^5

2^6

2^7

2^8

2^9

2^n 만큼 block size 가 늘어남

Page 49: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel (7/10)

kmem_cache_sizes_init()

pgtable_cache_init()

PAE 를 쓸 경우 “ pae_pgd” object 를 만들어 줌 .PAE 를 쓸 경우 “ pae_pgd” object 를 만들어 줌 .

시스템에서 생성할 수 있는 최대 thread 수를 구함시스템에서 생성할 수 있는 최대 thread 수를 구함

fork_init()

kernel cache 사이즈를 결정하고 , slab table 을 생성 .kernel cache 사이즈를 결정하고 , slab table 을 생성 .

task_struct 에서 사용하는 자료구조들의 object 를 만들어줌files_cache, fs_cache, vm_area_struct, mm_struct

task_struct 에서 사용하는 자료구조들의 object 를 만들어줌files_cache, fs_cache, vm_area_struct, mm_struct

proc_caches_init()

Page 50: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel (8/10)

vfs 에서 사용 할 cache 의 object 를 생성 ,dentry_cache object 생성 , dentry 헤쉬 테이블의 크기를 계산해서 생성후 초기화inode_cache object 생성 , inode 헤쉬 테이블의 크기를 계산해서 생성후 초기화메모리의 사이즈로 최대로 허용하는 file 의 갯수를 결정 (총 메모리 양의 10%)rootfs 를 마운트 하기 위해서 mnt, super_block, inode("/"), dentry("/"), dcache 를 생성 , 셋팅bdev 를 마운트 하기 위해서 mnt, super_block, inode("/"), dentry("/"), dcache 를 생성 , 셋팅cdev 헤쉬 테이블을 초기화 하고 cdev_cache object 를 생성iobuf_cache object 생성

vfs 에서 사용 할 cache 의 object 를 생성 ,dentry_cache object 생성 , dentry 헤쉬 테이블의 크기를 계산해서 생성후 초기화inode_cache object 생성 , inode 헤쉬 테이블의 크기를 계산해서 생성후 초기화메모리의 사이즈로 최대로 허용하는 file 의 갯수를 결정 (총 메모리 양의 10%)rootfs 를 마운트 하기 위해서 mnt, super_block, inode("/"), dentry("/"), dcache 를 생성 , 셋팅bdev 를 마운트 하기 위해서 mnt, super_block, inode("/"), dentry("/"), dcache 를 생성 , 셋팅cdev 헤쉬 테이블을 초기화 하고 cdev_cache object 를 생성iobuf_cache object 생성

vfs_caches_init()

buffer cache hash table 을 초기화한다 .buffer cache hash table 을 초기화한다 .

buffer_init()

page cache hash table 을 초기화한다 .page cache hash table 을 초기화한다 .

page_cache_init()

Page 51: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel (9/10)

sigqueue object 를 생성한다 .sigqueue object 를 생성한다 .

signal_init()

/proc 디렉토리에 파일과 디렉토리 및 sub 디렉토리 엔트리를 생성하고 셋팅/proc 디렉토리에 파일과 디렉토리 및 sub 디렉토리 엔트리를 생성하고 셋팅

proc_root_init()

128개의 세마포어 identifiers 테이블을 초기화 , /proc/sysvipc/sem 생성16 개의 메시지 큐 identifiers 테이블을 초기화 , /proc/sysvipc/msg 생성1개의 공유 메모리 identifiers 테이블을 초기화 , /proc/sysvipc/shm 생성

128개의 세마포어 identifiers 테이블을 초기화 , /proc/sysvipc/sem 생성16 개의 메시지 큐 identifiers 테이블을 초기화 , /proc/sysvipc/msg 생성1개의 공유 메모리 identifiers 테이블을 초기화 , /proc/sysvipc/shm 생성

ipc_init()

현재까지 bug 가 발생했는지 체크현재까지 bug 가 발생했는지 체크

check_bugs()

화면에 “ POSIX conformance testing by UNIFIX” 를 출력 화면에 “ POSIX conformance testing by UNIFIX” 를 출력

Page 52: Linux Booting  과정 이해

The place for generating the top 1% software experts

start_kernel (10/10)

SMP 시스템이라면 관련 설정을 수행한다 .SMP 시스템이라면 관련 설정을 수행한다 .

smp_init()

init kernel thread 를 수행하고 kernel 을 unlock 하고 idle mode 로 전환한다 .init kernel thread 를 수행하고 kernel 을 unlock 하고 idle mode 로 전환한다 .

rest_init()

Page 53: Linux Booting  과정 이해

The place for generating the top 1% software experts

init kernel thread (1/2)

SMP 시스템이라면 spin lock 을 건다 .SMP 시스템이라면 spin lock 을 건다 .

lock_kernel()

1. mtrr 을 초기화하고 CPU 에 따른 설정을 한다 . 2. 각종 interface 에 대한 초기화를 수행한다 . PCI, SBUS, MCA, ECARD, NUBUS, ISA(PnP)

3. networking 을 위한 object (“sock”) 를 만들고 netlink 를 위한 자료구조와 device file 을 생성

4. “keventd” kernel thread 실행

5. kernel 에 static 으로 설정된 device driver 들의 초기화 수행

6. IrDA 초기화

7. PCMCIA 초기화

1. mtrr 을 초기화하고 CPU 에 따른 설정을 한다 . 2. 각종 interface 에 대한 초기화를 수행한다 . PCI, SBUS, MCA, ECARD, NUBUS, ISA(PnP)

3. networking 을 위한 object (“sock”) 를 만들고 netlink 를 위한 자료구조와 device file 을 생성

4. “keventd” kernel thread 실행

5. kernel 에 static 으로 설정된 device driver 들의 초기화 수행

6. IrDA 초기화

7. PCMCIA 초기화

do_basic_setup()

Page 54: Linux Booting  과정 이해

The place for generating the top 1% software experts

init kernel thread (2/2)

1. /dev, /root, /dev/console 등이 없다면 새로이 생성

2. devfs 를 사용한다면 devfs 를 /dev 에 mount

3. initrd 를 사용한다면 mount

4. root device mount

1. /dev, /root, /dev/console 등이 없다면 새로이 생성

2. devfs 를 사용한다면 devfs 를 /dev 에 mount

3. initrd 를 사용한다면 mount

4. root device mount

prepare_namespace()

필요 없는 page 를 반환한다 . 필요 없는 page 를 반환한다 .

free_initmem()

1. console 을 open 한다 .

2. dup() 시스템 콜로 표준 출력 (1), 표준 에러 (2) 를 앞서 open 한 console 로 설정한다 .

3. /sbin/init 을 exec 한다 .

1. console 을 open 한다 .

2. dup() 시스템 콜로 표준 출력 (1), 표준 에러 (2) 를 앞서 open 한 console 로 설정한다 .

3. /sbin/init 을 exec 한다 .

Page 55: Linux Booting  과정 이해

The place for generating the top 1% software experts

init process (1/8)

init process 란 ?init process 란 모든 process 의 조상이며 스케줄링 되는 최초의 process 이다 . 모든 process 는 init 을 뿌리로 fork 하여 만들어지기 때문에 모든 process 의 최상위 조상에는 항상 init 이 존재한다 .init process 는 pid 1 을 가지며 부모 process 를 잃어 zombie process 로 남게 된 process 의 부모가되는 역할을 수행하기도 하며 부팅 시 /etc/inittab 파일에 기술된 대로 부팅 스크립트 (rc.sysinit)또는 가상 터미널 (/sbin/mingetty) 을 띄우는 역할을 수행한다 . init process 는 부팅 과정 중 pid 0 인 swapper 에서 fork 되고 /sbin/init 을 exec 하여 만들어 진다 .

Page 56: Linux Booting  과정 이해

The place for generating the top 1% software experts

init process (2/8)

pstree

ps -aux

Page 57: Linux Booting  과정 이해

The place for generating the top 1% software experts

init process (3/8)

# 6 - reboot (Do NOT set initdefault to this)# id:3:initdefault:

# System initialization.si::sysinit:/etc/rc.d/rc.sysinit

l0:0:wait:/etc/rc.d/rc 0l1:1:wait:/etc/rc.d/rc 1l2:2:wait:/etc/rc.d/rc 2l3:3:wait:/etc/rc.d/rc 3l4:4:wait:/etc/rc.d/rc 4l5:5:wait:/etc/rc.d/rc 5l6:6:wait:/etc/rc.d/rc 6

# Trap CTRL-ALT-DELETEca::ctrlaltdel:/sbin/shutdown -t3 -r now

pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"

pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"

/etc/inittab

/sbin/init 은 /etc/inittab 에 기술된 대로스크립트를 실행하고 프로그램을 실행한다 .그래서 /etc/inittab 를 분석하는 일은 init 이하는 일을 분석하는 것과 같다 .

새로운 파티션 등록

Page 58: Linux Booting  과정 이해

The place for generating the top 1% software experts

init process (4/8)

# Run gettys in standard runlevels1:2345:respawn:/sbin/mingetty tty12:2345:respawn:/sbin/mingetty tty23:2345:respawn:/sbin/mingetty tty34:2345:respawn:/sbin/mingetty tty45:2345:respawn:/sbin/mingetty tty56:2345:respawn:/sbin/mingetty tty6

# Run xdm in runlevel 5x:5:respawn:/etc/X11/prefdm -nodaemon

/etc/inittab

Page 59: Linux Booting  과정 이해

The place for generating the top 1% software experts

init process (5/8)

/etc/inittab 파일의 모든 라인은 다음과 같은 일관된 구조를 가지고 있다 .

id 는 init process 가 /etc/inittab 파일을 parsing 할 때 해당 라인을 다른 라인과 유일하게구별해주는 key 이다 .run-levels 는 해당 라인을 적용하기 위한 run level 목록을 의미하고 action 은 해당 명령어에적용에 대한 구체적인 행동을 지정하는 것이라 볼 수 있다 .command 는 실제 실행시키는 명령어이다 .

id : run-levels : action : commandid : run-levels : action : command

Page 60: Linux Booting  과정 이해

The place for generating the top 1% software experts

init process (6/8)

wait 명령어를 실행하고 명령어가 종료하기까지 기다림

respawn 명령어를 실행하고 해당 명령어의 프로세스가 죽으면 다시 실행

initdefault 디폴트 런 레벨을 지정

off아무 일도 하지 않음

once이미 실행되고 있는 프로세스라면 실행하지 말고 , 실행되고 있지 않으면 단지 한번만 실행

boot 부팅시 실행

bootwait 부팅시 실행 , 종료할 때까지 기다림

inittab action list

Page 61: Linux Booting  과정 이해

The place for generating the top 1% software experts

init process (7/8)

sysinit부팅시에 실행 , boot 나 bootwait 엔트리 들이 실행되기 전에 실행

powerwaitinit 프로세스가 SIGPWR 시그널을 받으면 실행되는 명령 , 명령어가 종료 될 때까지 대기

powerfail init 프로세스가 SIGPWR 시그널을 받으면 실행되는 명령 , 명령어가 종료 될 때까지 대기하지 않음

powerokwaitinit 프로세스가 SIGPWR 시그널을 받았을 때 /etc/powerstatus 파일에 OK 라는 단어가 있을 때만 실행

ctrlaltdel init 가 SIGINT 시그널을 받게 되면 실행할 명령어 (CTRL-ALT-DEL )

Page 62: Linux Booting  과정 이해

The place for generating the top 1% software experts

init process (8/8)

init

기본적인 path 설정/etc/sysconfig/network 실행 키맵의 로딩시스템 폰트의 로딩스왑 영역의 활성화디스크 검사 (fsck)/proc 파일시스템의 마운트루트 파일시스템을 rw 모드로remount

/etc/HOSTNAME 파일의 설정/etc/mtab 파일에 루트와 /proc 파일시스템의 엔트리 추가커널 모듈들 로드하기시스템 시간 설정

/etc/rc.d/rc.sysinit

/etc/rc.d/rc3.d 에 있는스크립트 수행 (S = start, K = stop)

/etc/rc.d/rc 3

화면에 “ login:” 출력 후 대기

/sbin/mingetty tty0 ~ 6

“Password:” 출력 후 인증 수행

/bin/login

shell 수행

/bin/bash

사용자입력

인증 성공