대망의 PintOS가 시작되었다.
순차적으로 부팅에 필요한 초기화 함수가 진행된다.
BSS를 지우고 머신의 RAM size를 가져온다
a. BSS 지우기 ( BSS는 0으로 초기화되어야 하는 세그먼트. 실제로 디스크에 저장되거나 커널에 의해 0이되지 않음. 직접 0으로 만들어야함) (BSS의 시작은 _start_bss. 끝은 _end_bss로 기록됨)
명령줄을 인수로 구분하고 옵션을 구문 분석한다.
lock을 사용할 수 있도록 스레드로 초기화. 그런 다음 콘솔 잠금 사용.
a. thread_init()
b. console_init()
메모리 시스템 초기화
a. 페이지 테이블을 커널 가상 매핑으로 채운 후 새 페이지 디렉토리를 사용하도록 CPU를 설정한다. (base_pml4는 생성된 pml4를 가리킴)
실제 주소 [0 ~ mem_end]를 [LOADER_KERN_BASE ~ LOADER_KERN_BASE + mem_end]에 매핑
인터럽트 핸들러 초기화
쓰레드 스케줄러와 인터럽트 활성화 시작
a. thread_start() 함수를 통해 인터럽트를 활성화하여 쓰레드 선점 스케줄링(preemptive thread scheduling)을 시작하고 유휴 쓰레드를 만든다.
파일 시스템 초기화
커널의 명령줄에서 지정된 actions 실행함
a. run_actions 함수를 통해 응용 프로그램을 실행한다던가 thread를 테스트한다던가 하는 각 task 별로 평가가 진행된다.
끝낸다.
a. PintOS가 실행되는 가상머신인 Bochs 또는 QEMU에서 실행 중인 시스템의 전원을 끈다.
유휴 쓰레드(idle thread) : 실행할 준비가 된 다른 쓰레드가 없을 때 실행된다.
유휴 쓰레드는 처음에 idle_thread를 초기화할 때 한 번 thread_start() 함수에 의해 ready list에 배치된다. ready list가 비어있는 상황을 하나하나 처리하는 대신 idle_thread를 넣어둔다. 일부 악명 높은 예외를 제외하고 idle_thread가 다른 쓰레드를 실행할 수 있도록 할 때까지 시스템을 저전력 상태로 둔다.
/* 가장 낮은 우선순위로 idle 쓰레드를 생성 */
thread_create ("idle", PRI_MIN, idle, &idle_started);
/* 커널 스레드의 기본으로 사용되는 함수 */
static void
kernel_thread (thread_func *function, void *aux) {
ASSERT (function != NULL);
intr_enable (); /* 스케줄러가 인터럽트를 끈 상태에서 실행. */
function (aux); /* 스레드 함수 실행. */
thread_exit (); /* 함수가 반환되면 thread kill */
}
/* 유휴 스레드.
실행할 준비가 된 다른 스레드가 없을 때 실행.
유휴 스레드는 처음에 thread_start()에 의해 준비 목록에 표시.
처음에 한 번 예약되며, 이 시점에서 idle_thread를 초기화하고
thread_start()가 계속될 수 있도록 전달된 세마포를 "업"한 후 즉시 차단.
그 후 유휴 스레드는 준비 목록에 나타나지 않음.
준비 목록이 비어 있는 경우 next_thread_to_run()에서 특별한 경우로 반환 */
static void
idle (void *idle_started_ UNUSED) {
struct semaphore *idle_started = idle_started_;
idle_thread = thread_current ();
sema_up (idle_started);
for (;;) {
/* Let someone else run. */
intr_disable ();
thread_block ();
asm volatile ("sti; hlt" : : : "memory");
}
}
디버깅 모드에서 개발자가 오류가 생기면 치명적일 것이라는 곳에 심어놓은 에러 검출용 코드이다.
#define ASSERT(CONDITION)
if ((CONDITION)) { } else {
PANIC ("assertion `%s' failed.", #CONDITION);
}
/* Halts the OS, printing the source file name, line number, and
* function name, plus a user-specific message. */
#define PANIC(...) debug_panic (__FILE__, __LINE__, __func__, __VA_ARGS__)
ASSERT (intr_get_level () == INTR_OFF);
해당 CONDITION이 아니면 OS를 중지하고 원본 파일 이름, 줄 번호 및 기능 이름과 사용자별 메시지를 출력한다.
참고.
인터럽트 핸들러
선점 스케줄링
Idle Thread
시스템 유휴 프로세스
ktx 타고 대전으로 돌아오는 한 시간 안에 복습 차원의 데일리 블로깅을 끝내자 했는데 쉽지 않다. 정리를 잘하는 사람들은 많은 시간을 투자하는 걸까. 참 대단하고 감사하다. 🫶🏻
비 오는 문지 캠퍼스는 처음인데 운치 있다. 네이버 지도를 믿고 안 가던 길로 가다가 허탕치고 돌아돌아 오게 된 정문 길이었는데 오히려 좋았다. 서울에 있다 와서 그런지 길이 넓고 조용하니 조경이 정리돼있는 게 해외에 온 거 같아 좋았다.
머리를 싹둑 잘랐다. 동갑내기 미용사도 어색할거다 괜찮냐 물어보는데 너무 개운하다. 긴머리의 효율을 못느껴 진즉에 자를 걸이라는 생각밖에 안 들었다.
좋은 글이네요! 잘 보고 가요!