[PintOS] 1. Introduction
앞으로의 PintOS 과제를 통해서 어떠한 모습의 PintOS를 만들 것인지 아래 그림으로 나타내었다.
현재 상태의 PintOS
최종 상태의 PintOS
Init Process 관련 주요 함수
운영체제 과목을 들었다면 위의 그림에서 무엇이 문제인지 알 수 있을 것이다. 내부 코드로 한 번 살펴보자. 다음은 PintOS 내부에 프로그램을 실행시키는 주요 함수들이다.
static void run_task(char ** argv) {
// ...
process_wait(process_execute(argv));
// ...
}
tid_t process_execute(const char *file_name) {
// ...
tid = thread_create(.., start_process, ..);
// ...
return tid;
}
int process_wait(tid_t child_tip UNUSED) {
return -1;
}
void thread_create(const char *name, int priority, thread_fun *function, void *aux) {
struct thread *;
struct kernel_thread_frame *kf;
// ...
t = palloc_get_page(PAL_ZERO); // allocate page
init_thread(t, name, priority); // initialize thread struct
tid = t->tid = allocate_tid(); // allocate allocate_tid
/* Stack frame for kernel thread */
kf = alloc_frame(t, sizeof *kf); // allocate kernel stack
// ...
thread_unblock(t);
return tid;
}
void thread_exit(void) {
// ...
process_exit();
intr_disable();
list_remove(&thread_current()->allelem);
thread_current()->status = THREAD_DYING;
schedule();
}
응용 프로그램을 실행시키면 run_task(), process_execute(), process_wait()를 순서대로 호출시킨다. 하지만 process_wait()에서 user process의 실행 종료를 기다리지 않고 바로 return -1을 실행하도록 되어있다. 따라서 thread_create()로 스레드를 생성시키고 PintOS가 즉시 종료되어 응용 프로그램을 실행시킬 수 없는 구조다. 이후에 내가 만들고 싶은 PintOS는 응용 프로그램을 실행시키는 user process를 만들고 PintOS가 이 프로세스의 실행 종료까지 기다린 후 정상적으로 종료하는 그림이다.
User Process 관련 주요 함수
/* src/userprog/process.c */
/* Initialize interrupt frame */
static void start_process(void *file_name_) {
char *file_name = file_name_;
struct intr_frame if_; // interrupt frame
bool successs;
// ...
success = load(file_name, &if_.eip, &if_.esp);
if(!success)
thread_exit();
/* Start the user process */
asm volatile("movl %0, %%esp; jmp intr exit" : : "g" (&if) : "memory"); // jump to intr_exit after stack pointer points to if
}
- load()를 통해 file_name에 해당하는 프로그램을 메모리에 탑재
- 성공 시 프로그램 실행
- 실패 시 스레드 종료
/* src/userprog/process.c */
/* Memory allcation & Load program onto memory */
bool load(costt char *file_name, void (**eip)(void), void **esp) {
struct thread *t = thread_current();
struct Elf32_Ehdr ehdr;
struct file *file = NULL;
off_t file_ofs;
bool success = alse;
int i ;
/* Allocate and activate page directory */
t->pagedir = pagedir_create(); // create page directory
if(t->pagedir == NULL) // activate page table
// handling error
process_activate(); // open file
/* Open executable file */
file = filesys_open(file_name);
if(file == NULL) {
// handling error
}
/* Read and verify executable header */
if(file_read(file, &ehdr, sizeof ehdr) != sizeof ehdr
|| memcmp(ehdr.e_ident, "\177ELF\1\1\1", 7)
|| ehdr.e_type != 2
|| ehdr.e_machine != 3
|| ehdr.e_version != 1
|| ehdr.e_phentsize != sizeof(struct Elf32_Phdr)
|| ehdr.e_phnum > 1024) {
// handling error
}
/* Read program headers */
file_ofs = ehdr.e_phoff;
for(i = 0; i < ehdr.e_phnum; i++) {
/* Read and store load info */
struct Elf32_Phdr phdr;
if(file_ofs < 0 || file_ofs > file_length(file))
// handling error
file_seek(file, file_ofs);
if(file_read(file, &phdr, sizeof phdr) != sizeof phdr)
// handling error
// ...
switch(phdr.p_type) {
// ...
/* Load file onto memory via load info */
if(!load_segment(file, file_page, (void*) mem_page, read_bytes, zero_bytes, writable))
// handling error
}
}
/* Initialize stack */
if(!setup_stack(esp))
// handling error
success = true;
return success;
}
- ELF 파일 포맷에 따라 메모리 탑재
- 페이지 테이블 생성
- ELF 파일의 헤더 정보 저장
- 프로그램 배치 정보 저장 & 배치 정보를 이용해 메모리에 파일 탑재
- 스택 생성 및 초기화
Author And Source
이 문제에 관하여([PintOS] 1. Introduction), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@chowisely/PintOS-Introduction저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)