Notice
Recent Posts
Recent Comments
Link
«   2025/10   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

JunHyeok

[PintOS - Userprog] Exec 본문

PintOS

[PintOS - Userprog] Exec

junhyeok-log 2024. 5. 30. 09:20

exec 시스템 콜 구현 가이드

exec 시스템 콜은 현재 프로세스를 주어진 cmd_line의 실행 파일로 변경하고, 주어진 인자를 전달합니다. 성공할 경우 이 함수는 반환되지 않습니다. 그렇지 않으면 프로그램을 로드하거나 실행할 수 없는 이유로 인해 프로세스는 종료 상태 -1로 종료됩니다. 이 함수는 exec를 호출한 스레드의 이름을 변경하지 않습니다. 파일 디스크립터는 exec 호출을 통해 계속 열려 있어야 합니다.

주요 요구사항

  1. 프로세스 변경:
    현재 프로세스를 cmd_line에 주어진 실행 파일로 변경합니다.
    주어진 인자를 전달하여 새로운 프로세스를 시작합니다.

  2. 성공 시 반환 없음:
    exec가 성공적으로 실행되면 호출된 함수는 반환되지 않습니다.

  3. 실패 시 종료:
    프로그램을 로드하거나 실행할 수 없는 경우 프로세스는 종료 상태 -1로 종료됩니다.
    실패 이유는 파일을 찾을 수 없거나, 파일을 실행할 수 없거나, 메모리 부족 등일 수 있습니다.

  4. 스레드 이름 유지:
    exec 호출을 통해 스레드의 이름을 변경하지 않습니다. 스레드의 이름은 이전과 동일하게 유지됩니다.

  5. 파일 디스크립터 유지:
    exec 호출 시 기존에 열려 있던 파일 디스크립터는 계속 열려 있어야 합니다. 새로운 프로세스로 변경되어도 파일 디스크립터는 그대로 유지됩니다.

exec 시스템 콜

int
exec(const char *cmd_line) {
    //  cmd_line: 새로운 프로세스에 실행할 프로그램 명령어
    is_valid_addr(cmd_line);

    struct thread * cur = thread_current();

    char *fn_copy = palloc_get_page (0);
    if (fn_copy == NULL) { 
        exit(-1); 
    }
    strlcpy (fn_copy, cmd_line, PGSIZE);

    if (process_exec(fn_copy) == -1) { 
        // printf("process_exec failed for: %s\n", cmd_line);
        exit(-1);
    }
    NOT_REACHED();
}

process_exec (void *f_name)

/* Switch the current execution context to the f_name.
 * Returns -1 on fail. */
int
process_exec (void *f_name) {
    char *file_name = f_name;
    bool success;
    struct thread *cur = thread_current();
    /* We cannot use the intr_frame in the thread structure.
     * This is because when current thread rescheduled,
     * it stores the execution information to the member. */
    struct intr_frame _if;
    _if.ds = _if.es = _if.ss = SEL_UDSEG;
    _if.cs = SEL_UCSEG;
    _if.eflags = FLAG_IF | FLAG_MBS;

    /* We first kill the current context */
    process_cleanup ();

    char *token, *save_ptr;
    char *argv[128];
    int argc = 0;
    for (token = strtok_r(file_name, " ", &save_ptr); token != NULL; token = strtok_r(NULL, " ", &save_ptr)) {
        argv[argc++] = token;
    }
    /* And then load the binary */
    success = load (file_name, &_if);

    /* If load failed, quit. */
    if (!success)
        return -1;
    argument_stack(&argv, argc,&_if);
    //hex_dump(_if.rsp, _if.rsp, USER_STACK - _if.rsp, true);
    palloc_free_page (file_name);

    /* Start switched process. */
    do_iret (&_if);
    NOT_REACHED ();
}

argument_stack을 통해 전달받은 인자를 파싱하고,

do_iret (&_if)에서 context switching이 일어납니다.

'PintOS' 카테고리의 다른 글

[PintOS - VM] Memory Management  (1) 2024.06.07
[PintOS - VM] Introduction  (0) 2024.06.03
[PintOS - Userprog] Wait  (0) 2024.05.29
[PintOS - Userprog] Fork, Exec, Wait 에 들어가기 앞서...  (0) 2024.05.29
[PintOS - Userprog] Write  (0) 2024.05.28