Linux Booting 과정 이해

Preview:

DESCRIPTION

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

Citation preview

The place for generating the top 1% software experts

Linux Booting 과정 이해

백 창 우bckddn@daum.net

The place for generating the top 1% software experts

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

The place for generating the top 1% software experts

Booting 의 의미☞ booting 의 정의

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

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

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, …

The place for generating the top 1% software experts

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

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

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

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

The place for generating the top 1% software experts

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

/sbin/login

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

Shell 실행

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

The place for generating the top 1% software experts

ROM BIOS (2/2)

BIOS 의 구조 CMOS 의 구조

POST 과정

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 를 의미한다 .

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

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 로 많이 사용되고 있다 .

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

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

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

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=-=

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

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

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

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 자료구조

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

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

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

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 이다 .

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

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

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

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 에서 메모리에 저장한 정보

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:

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:

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:

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:

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)

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

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 로 넘아감

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 로 제어를 옮긴다 .

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 (bhcompile@daffy.perf.redhat.com) (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 (bhcompile@daffy.perf.redhat.com) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #1 Tue Jul 15 17:03:30 EDT 2003

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()

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 초기화

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

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 에서 찾을 수 있다 .

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

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

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()

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 를 활당한다 .

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 구조체의 값들을 셋팅한다 .

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 가 늘어남

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()

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()

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” 를 출력

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()

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()

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 한다 .

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 하여 만들어 진다 .

The place for generating the top 1% software experts

init process (2/8)

pstree

ps -aux

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 이하는 일을 분석하는 것과 같다 .

새로운 파티션 등록

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

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

The place for generating the top 1% software experts

init process (6/8)

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

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

initdefault 디폴트 런 레벨을 지정

off아무 일도 하지 않음

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

boot 부팅시 실행

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

inittab action list

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 )

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

사용자입력

인증 성공

Recommended