본문 바로가기
정글 2기/OS 운영체제

[PintOS] 로딩 (Loading)

by Dean30 2021. 10. 4.
728x90

[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

728x90

댓글