630 likes | 999 Views
Linux Booting 과정 이해. 백 창 우 bckddn@daum.net. 강의 목표. kernel source 의 분석 기법을 이해한다 . ctags, cscope, source navigation 등의 사용법을 익힌다 . Linux 의 부팅 과정을 이해한다 . kernel 의 초기화 code 를 이해한다 . init process 의 역할에 대해서 이해한다 . 부팅 스크립트를 이해한다 . 실제 kernel 초기화 코드를 분석해 본다. Booting 의 의미. booting 의 정의
E N D
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
HDD의 MBR ROM BIOS Power On FDD의 MBR VGA 체크 Memory 체크 IDE 장치 체크 각종 장치 정보 수집 Flash Memory MBR에 있는 Boot loader 로딩 또는 bootsect.S 로딩 부팅 과정 도식도 (1/5) SUN Sparc, … Intel ix86 StrongARM, XScale, … The place for generating the top 1% software experts
kernel을 main memory로 로딩 kernel 압축 해제 부팅 과정 도식도 (2/5) The place for generating the top 1% software experts
초기화 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 } init kernel thread 각종 interface 장치 초기화 network interface 초기화 initrd 로딩 및 ‘/’ mount free memory 재 계산 console open /sbin/init process 수행 부팅 과정 도식도 (3/5) The place for generating the top 1% software experts
/etc/rc.d/rc.sysinit /sbin/init 수행 host name 설정 시간 설정 usb 설정 file system check ISA 설정 sound 설정 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수행 /etc/rc.d/rc 3 run level에 따른 /etc/rc*.d 디렉토리의 script를 수행 /etc/X11/prefdm gdm 또는 kdm 또는 xdm 실행 /sbin/mingetty 가상 터미널을 띄우고 login 프로그램 실행 부팅 과정 도식도 (4/5) The place for generating the top 1% software experts
/sbin/login 인증 수행 후 shell 실행 Shell 실행 부팅 과정 도식도 (5/5) The place for generating the top 1% software experts
POST (Power On Self Test) 과정 전원이 들어 오는 순간 모든 부품이 초기화 된다. 만약 초기화 시키지 않으면 기존의 정보가 남아서 오작동을 일어 킬 수 있다. 그리고 시스템의 정상 여부를 검색하여 이상 유무를 테스트한다. CPU, VGA, RAM등이 주요 검색 대상이 된다. 시스템 초기화 ROM BIOS 내부에 있는 인터럽트 핸들러로 인터럽트 백터 테이블을 구성한다. 그리고 시스템에 장착되어 있는 장치들의 상태를 알아내 메모리의 하위 번지(0x0800~0x1000)에 기록한다. 확장 BIOS와 SCSI 카드를 검색하여 메모리 하위 번지에 기록한다. Disk Boot Boot strap 루틴이 CMOS에 저장되어 있는 boot device 순서를 참조하여 boot driver의 boot sector 로 부터 boot strap code를 RAM으로 loader하고 제어를 넘긴다. ROM BIOS (1/2) BIOS (Basic Input Output)의 의미 : 하드웨어 안에는 그 하드웨어의 input/output을 제어할 수 있는 프로그램이 내장되는데 그러한 프로그램을 BIOS (Basic Input Output)라 한다. 이러한 BIOS는 통상 내용이 지워지지 않는 ROM chip에 내장되게 되는데 그래서 ROM BIOS라 부른다. I386 PC에서 ROM BIOS가 하는 일은 크게 3부분으로 나눌 수 있고 다음과 같다. 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 트랙0, 섹터1 플래터의 구조 MBR의 이해 (1/2) 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 이미지 (dd if=/dev/had of=MBR.img bs=1c count=512) time out 시간 LILO 문자열 jmp 0x7C second boot loader의 위치 map 파일 image 디스크립트1 위치 Boot Loader code 파티션 1 파티션 2 파티션 3 파티션 4 Magic number fs type MBR의 이해 (2/2) 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
BIOS의 시스템 초기화가 끝날 무렵 MBR에 있는 LILO의 first.S를 메모리의 0x7C00 (0x7C0:0x0000)으로 옮기고 제어를 0x7C00으로 넘긴다. 이후 모든 설명은 LILO를 기준으로 설명하고자 한다. 0x7C00 first.S LILO first.S loading The place for generating the top 1% software experts
first.S 0x9A000 first.S 0x9A200 Stack 0x9B000 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’을 출력한다. 0x7C00 The place for generating the top 1% software experts
1. 하드 디스크상의 second.S를 메모리 0x9B000 번지로 로딩한다. 하드 디스크상의 위치는 lilo명령어를 내릴 때 first.S에 저장된 값이고 second.S는 /boot/boot.b를 의미한다. 2. ‘I’를 화면에 출력하고 제어를 second.S로 옮긴다. 0x7C00 first.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S second.S load The place for generating the top 1% software experts
1. 터미널 부팅을 사용하는가 체크하고 사용한다면 시리얼 포트를 설정한다. 2. 키보드 버퍼를 비운다. 3. 화면에 ‘L’을 출력한다. 0x7C00 first.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 23kjds sadjlkasd sadjlkas ksjd=-= second.S의 초기화 작업 The place for generating the top 1% software experts
0x7C00 first.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 0x9D200 Image descriptor table 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이 정확이 로드 되었는지 점검한다. 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 파일 내부에 존재하고 있다. 0x7C00 first.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 0x9D200 Image descriptor table 0x9D800 keyboard translation table 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를 출력하고 사용자 입력을 기다린다. 0x7C00 first.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 0x9D200 Image descriptor table 0x9D600 Default command line, etc 0x9D800 keyboard translation table The place for generating the top 1% software experts
1. 화면에 “Loading”을 출력한다. 2. 사용자의 입력으로 부팅할 boot image가 선택되면 image descriptor tables에서 부팅할 image descriptor를 선택하여 initrd의 사용 여부를 검사하고 initrd를 사용한다면 initrd를 로딩한다. initrd의 로딩을 위해 먼저 메모리 량과 initrd의 사이즈를 검사한다. initrd 로딩시 한 sector를 읽을 때마다 화면에 ‘.’을 출력 0x7C00 first.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S Image descriptor 자료구조 0x9D200 Image descriptor table typedef 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; 0x9D600 Default command line, etc 0x9D800 keyboard translation table RAM disk 및 initrd load The place for generating the top 1% software experts
Boot map load 1. /boot/map 파일 내에 있는 boot map을 읽어 메모리의 0x9D000에 로드 한다. 이러한 boot map에는 bootsect.S의 하드디스크상 위치 정보와 setup.S의 하드디스크상 위치 정보가 담겨있다. 0x7C00 first.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 0x9D000 Map load area 0x9D200 Image descriptor table 0x9D600 Default command line, etc 0x9D800 keyboard translation table 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한다. 0x7C00 first.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 0x9D000 Map load area 0x9D200 Image descriptor table 0x9D600 Default command line, etc 0x9D800 keyboard translation table 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을 작성한다. 0x7C00 first.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 0x9D000 Map load area 0x9D200 Image descriptor table 0x9D600 Default command line, etc 0x9D800 keyboard translation table The place for generating the top 1% software experts
Parameter line 작성 (2/2) 다음은 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 번지에 쓴다. 0x7C00 first.S 0x90000 boot sector 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 0x9D000 Map load area 0x9D200 Image descriptor table 0x9D600 Default command line, etc 0x9D800 keyboard translation table The place for generating the top 1% software experts
setup.S load 1. setup.S를 하드 디스크에서 읽어 메모리 0x90200에 로드한다. 0x7C00 first.S 0x90000 boot sector 0x90200 setup.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 0x9D000 Map load area 0x9D200 Image descriptor table 0x9D600 Default command line, etc 0x9D800 keyboard translation table 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로 옮긴다. 0x7C00 first.S 0x90000 boot sector 0x90200 setup.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 0x9D000 Map load area 0x9D200 Image descriptor table 0x9D600 Default command line, etc 0x9D800 keyboard translation table The place for generating the top 1% software experts
kernel load (2/2) 0x7BE kernel (not big kernel)을 로드한 최종 모습 Partition table 0x7FE 0x7C00 first.S BIOS에서 메모리에 저장한 정보 0x10000 kernel 0x90000 boot sector 0x90200 setup.S 0x9A000 first.S 0x9A200 Stack 0x9B000 second.S 0x9D000 Map load area 0x9D200 Image descriptor table 0x9D600 Default command line, etc 0x9D800 keyboard translation table The place for generating the top 1% software experts
setup.S (1/4) arch/i386/boot/setup.S : start_of_setup 세컨드리 하드디스크를 읽는다. 만약 SAFE_RESET_DISK_CONTROLLER이 define되었다면 프라이머리를 읽는다. start_of_setup: setup.S의 마지막 부분에 할당되어 있는 setup_sig1과 setup_sig2 변수의 값을 읽어 setup.S가 정상적으로 로딩되었는가 확인한다. (setup_sig1 = 0xAA55, setup_sig2 = 0x5A5A) good_sig1: -> good_sig: kernel이 제대로 로딩되었는지 확인한다. (big kernel은 loadflags 변수에 1이 들어 있고 type_of_loader 변수에 kernel을 로딩한 boot loader ids 값이 들어 있음.) loader_ok: extended memory size를 구함 먼저 BIOS function인 0xe820을 사용할 수 있는지 체크하고 사용 가능하면 0xe820을 호출, 최대 32번 반복 호출하여 e820map struct에 저장 (eax = 0xe820; int 0x15) 다음으로 BIOS function 0xe810을 호출하고 마지막으로 BIOS function 0x88을 호출하여 extended memory size를 결정 The place for generating the top 1% software experts
setup.S(2/4) mem88: 키보드 설정 delay time = 250ms, rate time = 30.0 arch/i386/boot/video.S : video: vga 메모리 사이즈와 칼라 모드 설정 vga의 모드 체크 커스 위치, 현재의 디스플레이 페이지, 비디오 모드와 넓이, 폰트 사이즈 등을 설정 arch/i386/boot/setup.S : mem88: hd0의 파라메타를 0x90080으로 16byte 만큼 복사 hd1의 파라메타를 0x90090으로 16byte 만큼 복사 hd1이 있는지 체크 is_disk1: PS/2 데스크 탑에 관한 정보를 읽어와 MCA(Micro Channel Architecture) bus를 확인한다. (일반적인 PC는 IBM PS/2 데스크 탑이 아니기 때문에 no_mca로 점프) The place for generating the top 1% software experts
setup.S(3/4) no_mca: PS/2 마우스가 있다면 0x901FF에 0xAA를 저장 no_psmouse: APM의 작동 유무 확인 (APM BIOS라면 관련 설정을 함) rmodeswtch_normal: -> default_switch: NMI (Non-Maskable Interrupt)를 포함하여 모든 interrupt를 disable 한다. rmodeswtch_end: code32 변수에 kernel의 시작 주소를 설정한다. (big kernel 이면 code32 = 0x100000 아니면 code32 = 0x1000) big kernel이 아니라면 0x10000에 있는 kernel을 0x1000으로 옮긴다. (압축 해제를 위한 공간 확보가 목적) The place for generating the top 1% software experts
setup.S(4/4) a20_none: A20 line이 사용 가능한가 테스트 한다. a20_kbc: empty_8042 루틴을 호출하여 키보드 버퍼를 비운다. A20 line을 enable시킨다. (movb $0xDF, %al; outb %al, $0x60) a20_done: 초기 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) The place for generating the top 1% software experts
arch/i386/boot/setup.S GDT (Global Descriptor Table) 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 0x0000 0x0000 0x0000 0x0000 0x0000 0x00CF 0x0000 0x00CF 0x9A00 0x0000 0x0000 0x0000 0x9200 0xFFFF 0xFFFF 0x0000 head.S (1/4) • 보호모드로 전환된 상태에서 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 dummy(0) unused(1) code (2) data (3) The place for generating the top 1% software experts
zImage vmlinux 0x1000 0x100000 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)로 넘긴다. normal kernel The place for generating the top 1% software experts
head.S (3/4) big kernel Uncompressing low buffer bzImage 0x2000 0x100000 0x90000 move_routine_start move_routine_start를 복사 후 제어가 넘어감 vmlinux bzImage 0x90000 0x1000 0x2000 0x100000 move_routine_start에 의해 복사된 후 제어가 kernel로 넘아감 vmlinux vmlinux 0x1000 0x2000 0x100000 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로 제어를 옮긴다. The place for generating the top 1% software experts
start_kernel (1/10) lock_kernel() SMP일 경우 spin lock을 건다. single CPU는 해당되지 않고 SMP CPU는 동시에 여러 processor가 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 The place for generating the top 1% software experts
start_kernel (2/10) setup_arch() 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 설정을 한다. The place for generating the top 1% software experts
start_kernel (3/10) parse_options() command line을 parsing한다. 환경변수는 envp_init에 kernel option은 argv_init에 저장 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 초기화 The place for generating the top 1% software experts
start_kernel / trap_init() (1/4) IDT (Interrupt Descriptor Table)내 예외처리 handler The place for generating the top 1% software experts
start_kernel / trap_init() (2/4) IDT (Interrupt Descriptor Table)내 예외처리 handler 예외 발생시 호출되는 함수는 arch/i386/kernel/entry.S에서 찾을 수 있다. 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 오류에 의해 발생 The place for generating the top 1% software experts
start_kernel / trap_init() (3/4) IDT (Interrupt Descriptor Table)내 예외처리 handler 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) 보호모드에서 심각한 에러가 감지되면 발생 The place for generating the top 1% software experts
start_kernel / trap_init() (4/4) IDT (Interrupt Descriptor Table)내 예외처리 handler 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 요구 시 발생 The place for generating the top 1% software experts
start_kernel (4/10) init_IRQ() idt에 interrupt handler를 등록한다. IDT index 32번부터 시작하여 차례로 등록하고 등록된 IRQ는 시스템마다 다르나 보편적으로 i386계열의 경우 32(IRQ 0)번은 timer, 33(IRQ 1)번 keyboard 순으로 등록된다. sched_init() 1. init_task의 processor를 설정한다. 2. pidhash table을 초기화 한다. 3. 프로그램 가능한 타이머 벡트를 작성한다. 4. 하반부 핸들러 루틴들을 셋팅한다. softirq_init() softirq를 설정한다. The place for generating the top 1% software experts
start_kernel (5/10) time_init() • 1. 타임 퀀텀을 구함. • 2. CPU clock을 구함. console_init() 1. tty_ldisc_N_TTY 자료구조를 정의하고 각 flag를 셋팅한다. 2. console_driver 자료 구조를 설정하고 device driver로 등록한다. 3. columns과 row를 참조하여 사용할 buffer size를 결정한다. 4. cursor 크기 및 깜빡임에 대한 설정을 한다. init_modules() kernel symbol table의 크기를 결정하여 kernel_module 구조체에 저장한다. profiling을 사용한다면 profile buffer를 활당한다. The place for generating the top 1% software experts
start_kernel (6/10) kmem_cache_init() • slab 활당자를 위한 cache_cache 구조체의 값들을 셋팅한다. calibrate_delay() 보다 높은 정밀도의 delay를 위해 clock tick을 구하고 BogoMIPS를 구한다. mem_init() • 1. empty_zero_page의 하드웨어 정보를 0으로 초기화 시킨다. • 2. buddy system을 만들고, free page 수를 구하고, 사용하는 page 수 등을 출력한다. The place for generating the top 1% software experts
2^0 2^1 2^2 2^3 2^4 2^5 2^6 2^7 2^8 2^9 start_kernel / mem_init() buddy System 2^n 만큼 block size가 늘어남 The place for generating the top 1% software experts
start_kernel (7/10) kmem_cache_sizes_init() • kernel cache 사이즈를 결정하고, slab table을 생성. pgtable_cache_init() PAE를 쓸 경우 “pae_pgd” object를 만들어 줌. fork_init() 시스템에서 생성할 수 있는 최대 thread 수를 구함 proc_caches_init() task_struct 에서 사용하는 자료구조들의 object를 만들어줌 files_cache, fs_cache, vm_area_struct, mm_struct The place for generating the top 1% software experts
start_kernel (8/10) vfs_caches_init() 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 생성 buffer_init() buffer cache hash table을 초기화한다. page_cache_init() page cache hash table을 초기화한다. The place for generating the top 1% software experts