[PintOS] 로딩 (Loading)
1. Loader
- 로딩(Loading) : pintos 첫 실행시 진행되는 부팅의 과정이다.
- 부팅(Booting) : 컴퓨터를 구동하여 기초적인 초기화 작업을 수행하고 운영 체제를 읽어오는 일련의 작업이다.
- 로더(Loader) : 부팅 작업을 진행하는 프로그램. Disk의 첫 번째 섹터에 저장되어 있다.
1) BIOS(ROM에 있음)가 로더(Loader)를 메모리에 로드(Load) 한다.
- BIOS는 컴퓨터가 구동된 후 저장 장치(Disk)의 첫 번째 섹터를 탐색해여 이 장치가 부팅 가능한지 검사한다. (BIOS : Basic Input/Output System 입출력 처리 펌웨어)
- Sector : 저장 장치(Disk)에서 데이터를 저장하는 최소 단위로, 한 섹터의 크기는 512 bytes이다.
- 첫 번째 섹터를 MBR(Master Boot Record)라고 하고, 부팅 가능한 장치임을 나타내기 위해 섹터의 마지막 2 bytes가 0xAA55 (Magic Number)의 값을 가져야 한다.
- 부팅 가능한 장치인 경우 BIOS는 이 첫 번째 섹터를 읽어서 메모리의 0x7c00 위치에 올려놓고 작업을 시작한다.
.org LOADER_SIG - LOADER_BASE
.word 0xaa55
/* 섹터의 마지막 2bytes가 0xAA55이어야 부팅 가능한 장치임을 나타냄.(Magic Number)
* 부팅 가능한 장치임이 판명되면 BIOS는 이 첫 번 째 섹터를 읽어서 메모리의 0x7c00 위치에 올려놓고
* 작업을 시작한다. */
2) 로더(Loader)가 디스크에서 커널(Kernel)을 찾아 메모리의 0x20000 위치에 로드한다.
3) 커널의 entry point로 이동한다. (kernel의 ELF header가 entry point의 위치를 포함)
커널 시작 !!!!
2. Low-Level Kernel Initialization
로더(Loader)는 control을 kernel로 옮긴다.
start() 코드는 CPU를 16 bit real mode에서 32 bit protected mode 로 바꿔주고 main() 함수를 부르는 역할을 한다.
그런데 여기 핀토스에서는 start대신 다른 코드가 쓰인 것 같다. start.S 파일은 있긴 한데..
나중에 다시 확인하기 !
#### Switch to protected mode.
# Note that interrupts are still off.
# Point the GDTR to our GDT. Protected mode requires a GDT.
# We need a data32 prefix to ensure that all 32 bits of the GDT
# descriptor are loaded (default is to load only 24 bits).
data32 lgdt gdtdesc
# Then we turn on the following bits in CR0:
# PE (Protect Enable): this turns on protected mode.
# PG (Paging): turns on paging.
# WP (Write Protect): if unset, ring 0 code ignores
# write-protect bits in page tables (!).
# EM (Emulation): forces floating-point instructions to trap.
# We don't support floating point.
movl %cr0, %eax
orl $CR0_PE, %eax
movl %eax, %cr0
# We're now in protected mode in a 16-bit segment. The CPU still has
# the real-mode code segment cached in %cs's segment descriptor. We
# need to reload %cs, and the easiest way is to use a far jump.
# Because we're not in a 32-bit segment the data32 prefix is needed to
# jump to a 32-bit offset.
data32 ljmp $SEL_KCSEG, $protcseg
# We're now in protected mode in a 32-bit segment.
.code32
Real mode
- 컴퓨터가 가동되고 바로 동작하는 모드로 loader의 코드는 real mode에서 동작한다.
- 프로그램이 동작할 때, physical memory에는 한 번에 한 개의 프로그램만 적재 가능하다. 즉 한 번에 한개의 프로그램만 실행할 수 있다.
- physical memory에 올라간 프로그램이 종료되지 않으면 인터럽트나 시스템 종료를 해야 다른 프로그램의 실행이 가능하다.
- physical memory에 직접 접근이 가능하므로 응용 프로그램에서 시스템 코드로의 접근이 용이하고 이는 보안에 취약하고 시스템 손상을 유발한다.
Protected mode
- 각 프로세스마다 보조기억장치에 각자의 가상 메모리(Virtual memory) 영역을 할당 받는다. (32bit의 경우 각각 4GB)
- 이 영역은 각자가 real mode 인 것처럼 동작하고 페이징 기법을 통해 실제 필요한 부분만 physical memory에 올라와서 실행되기 때문에 real mode의 단점들을 보완한다.
- 여러 프로그램을 동시에 실행 가능하고 real mode에서의 단점들을 커버할 수 있다.
start()의 전체적인 진행
1) PC's memory size를 얻어 init_ram_pages (<threads/loader.h>)에 저장
나중에 내용 추가
2) A20 line을 활성화 (CPU's address line numbered 20)
나중에 내용 추가
3) 메모리 초기화
Page table 란?
- Frame : physical memory를 구성하는 단위 블록. 4KB 크기
- Page : virtual memory를 구성하는 단위 블록. 4KB 크기
- virtual memory에 있는 page들은 실제 실행될 때 physical memory의 frame을 할당받아 physical memory에 위치하게 된다.
- Page table : Page 들을 관리하기 위한 테이블. 프로세스마다 하나씩 존재. Page table entry(PTE)로 구성되며 각 PTE는 하나의 Page의 첫 주소를 가리키는 포인터를 정보로 가진다.
- Page directory : Page Directory Entry(PDE) 들로 구성된 데이터. 각 PDE는 하나의 Page table의 첫 주소를 가리키는 포인터를 정보로 가진다.
Pintos Page table 구조
- 4KB의 Page directory, Page table, Page를 가진다.
- 32bit 아키텍처에서 하나의 주소 값은 4B 를 차지하므로 4KB의 Page directory는 1024 (4KB/4B = 1K = 1024)개의 PDE를 가진다.
- Page table, Page frame도 동일
- 이를 통해 pintos 32bit의 Linear address로 표현할 수 있는 Virtual Memory의 크기는 1024(PDE) * 1024(PTE) * 4KB(Page) = 2^20 * 4KB = 1MB * 4KB = 4GB 이다.
이해를 돕기 위해 두 가지 그림을 첨부하였다.
Page Table Mapping
- 보호모드로 전환된 후에 접근 가능한 Virtual Memory의 크기는 4GB이다. (0x00000000-0xffffffff)
- 이중 0xc0000000 ~ 0xffffffff(3~ 4GC)의 1GB 공간을 커널 영역으로 사용한다. (시작 위치 0xc0000000은 LOADER_PHYS_BASE라는 값으로 <thread/loader.h>에 저장되어 있다.
3. High-Level Kernel Initialization
1) bss_init() : 커널의 "BSS"를 초기화
보통 5개의 세그먼트로 나누어 진다. 낮은 주소부터 Text(code), Data, BSS, Heap, Stack
---- dynamic 영역 -----실행시간에 할당되는 영역
- Stack : 지역 변수와 각종 정보들이 저장되는 영역. 주소의 높은 곳부터 낮은 곳으로 저장된다. (함수 호출 때마다 프레임 할당 영역)
- Heap : 사용자가 직접 할당한 메모리가 저장되는 영역 (malloc, 실행 시간 임의의 지점에서 메모리를 할당/수거)
---- static 영역 ---- 컴파일 시간에 할당되는 영역
- BSS : (미래에 초기화 시킬 예정이지만) 초기화되지 않은 전역 변수와 정적(static) 변수가 저정되는 공간. block started symbol segment를 뜻한다. bss 영역은 어느정도의 공간의 크기를 저장할 것이라는 정보를 저장한다. 즉 바로 메모리를 확보하는 것이 아니라 런타임 후에야 메모리영역이 확보된다.
- Data : 초기화된 전역 변수와 정적(static) 변수가 저장되는 공간이다.
- Text(Code) : 프로그램의 기계어 코드가 저장되어 읽기만 가능. 쓰기는 불가능하다. 우리가 작성하는 코드부분 !!!!
2) read_command_line() : kernel command line 을 읽어와서 arguments 로 나눈다.
3) parse_options() : command line 에서 options 을 읽어온다.
4) thread_init() : 쓰레드 시스템을 초기화한다.
5) console_init() : 콘솔 초기화 -> 콘솔 초기화 이후에는 printf() 를 사용 가능하다.
6) 커널의 메모리 시스템 초기화
- palloc_init() : page allocator 설정
- malloc_init() : 사용자 메모리 할당(malloc 함수) 이 가능하게 설정
- paging_init() : loader.S 에서 구성했던 페이지 테이블을 다시 구성한다.
7) tss_init() : tss(task state segment) 를 설정한다. 이는 커널이 task 를 관리할 때 필요한 정보가 들어있는 segment이다.
8) gdt_init() : gdt(global description table) 을 초기화한다. 마찬가지로 커널이 task 를 관리할 때 필요한 정보가 들어있다.
9) 인터럽트 초기화
- intr_init() : IDT(Interrupt Descriptor Table) 를 초기화한다. 이 table 은 인터럽트를 handling 하는 handler 함수들이 연결되는 table이다.
- timer_init(), kbd_init() : 타이머, 키보드 인터럽트 초기화
- input_init() : input 모듈 초기화
- exception_init(), syscall_init() : 예외처리 인터럽트, system call 인터럽트 초기화
10) thread_start() : 우선 가장 실행 우선순위가 낮은 idle 이라는 thread 를 생성하여 동작시키고 인터럽트를 활성화시킨다.
11) serial_init_queue() : serial 로부터 인터럽트를 받아 커널을 제어할 수 있도록 한다.
12) timer_calibrate() : 정확한 시간 측정을 위해 timer 를 보정한다.
13) ide_init() : IDE disk 를 초기화한다.
14) filesys_init() : 파일시스템을 초기화한다.
참조
poArlim 티스토리 : https://poalim.tistory.com/23?category=758538
Pintos Documentation : web.stanford.edu/class/cs140/projects/pintos/pintos.pdf
Luavis'Dev Story - A20 gate : b.luavis.kr/os/a20
Science Direct - Page Directory Table : www.sciencedirect.com/topics/computer-science/page-directory-table
'정글 2기 > OS 운영체제' 카테고리의 다른 글
[pintos] Project 1_priority scheduling (0) | 2021.10.04 |
---|---|
[pintos] Project 1_alarm (0) | 2021.10.04 |
[PintOS] 디버깅 도구(Debugging Tool)_printf, ASSERT, __attributes__, backtraces (0) | 2021.10.03 |
[OS운영체제] 권영진 교수님 OS 강의 (카이스트 전산학부) (2) | 2021.10.01 |
[OS운영체제] Network Programming_TCP/IP echo server, echo client (0) | 2021.09.26 |
댓글