[PintOS] 1. Introduction

20143 단어 pintospintos

앞으로의 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 파일의 헤더 정보 저장
    - 프로그램 배치 정보 저장 & 배치 정보를 이용해 메모리에 파일 탑재
    - 스택 생성 및 초기화

좋은 웹페이지 즐겨찾기