xv6 시스템 호출 명령어 추가하기

Socra·2023년 5월 15일
0
post-thumbnail

1. 설계


이 작업의 목표는 System call 함수를 이해하고 추가하는 것이다. System call은 운영체제가 제공하는 인터페이스로써 사용자 공간과 구별하여 사용하게 하여 시스템을 보호한다.

리눅스의 ps 명령어와 유사한 시스템 콜 명령어를 xv6에 추가하기 위해, 기존 xv6 시스템에 ‘ps’라는 이름의 시스템 콜과 그를 호출하는 유저 함수를 추가한다. ‘ps’시스템 콜 명령어는 현재 프로세스 상태를 표시한다. 출력을 하는 ps() 함수의 코드는 다음과 같은 알고리즘으로 작성한다.

int ps(void){
    struct proc *p
    cprintf(“pid \t name \t state \t \n”);
    for (p = ptable.proc; p < &ptable.proc[NPROC]; p++){
        if (p->state == SLEEPING)
            cprintf(“%d\t  %s\tSLEEPING\t\n”, p->pid, p->name);
        else if (p->state == RUNNING)
            cprintf(“%d\t  %s\tRUNNING\t\n”, p->pid, p->name);
        else if (p->state == RUNNABLE)
            cprintf(“%d\t  %s\tRUNNABLE\t\n”, p->pid, p->name);
    }
}

루프문의 인덱스로 활용할 proc 구조체 포인터 p를 선언하고, for문을 통해 p를 ptable의 시작 주소(ptable.proc)로 초기화 한 후, ptable의 마지막(ptable.proc[NPROC])까지 순회시킨다. 프로세스의 상태에 따라 pid, 프로세스 이름, 상태를 출력하도록 작성하였다

2. 개발 환경


2-1. 운영체제

작업을 진행할 환경 운영체제로는, 코드 수정 및 디버깅이 용이하고 QEMU 에뮬레이터를 사용하기 용이한 리눅스 우분투를 사용하기 위해 Oracle VM VirtualBox 가상 머신을 통해 가상 환경에 ‘Ubuntu 20.04.4’를 설치해 진행한다.

코드 수정 및 작성은 vim 에디터를 이용한다.

2-2. 패키지 설치

  1. QEMU (Quick Emulator) 설치
    xv6를 가상 환경에서 실행 시키기 위해 리눅스에서 사용하는 가상머신인 QEMU를 설치하였다.

  2. git 설치
    github에서 xv6 Repository를 클론으로 가져오고, 작업을 완료 이후 Repository를 생성하고 github에 등록하기 위해 git 패키지를 설치하였다.

  3. vim 설치
    코드 수정을 용이하게 하기 위해 vi 에디터와 호환되는 문서편집기인 vim 에디터를 설치하였다.

2-3. xv6 복제 및 실행

git clone 명령어를 통해 깃 허브에 공개된 xv6 레포지토리를 로컬로 복제했다.

터미널에서 복제된 xv6-public 디렉토리로 접근 후 make qemu-nox 명령어를 통해 QEMU 에뮬레이터로 xv6를 실행(부팅)하였다.

3. 구현


3-1. syscall.h 수정

‘syscall.h’에는 시스템 콜 종류들이 정의되어 있다. ‘syscall.h’ 헤더 파일에 추가할 ‘ps’ 시스템 콜 명령어를 추가한다.

3-2. defs.h

커널 모드의 시스템 콜 ‘sys_ps’를 정의한다.

3-3. user.h 수정

유저 라이브러리 헤더 ‘user.h’에는 사용자 모드에서 시스템 호출을 하는 함수들이 정의되어 있다. ‘user.h’에 ‘ps()’를 추가해 유저 모드에서 ps() 시스템 콜 함수를 사용할 수 있도록 한다. ‘user.h’에 시스템 콜이 정의되어야 사용자 모드에서 시스템 콜이 가능하다.

3-4. sysproc.c 수정

추가하고자 하는 시스템 콜이 프로세스와 관련된 정의이기 때문에, ‘sysproc.c’에 시스템 콜 ‘sys_ps()’를 정의한다.

3-5. usys.S 수정

‘usys.S’에서는 SYSCALL(name) 매크로를 통해 name에 해당하는 시스템 콜을 정의한다.

매크로에 따르면, ‘movl $SYS_## name, %eax;’를 통해 syscall.h에 정의된 SYS_name의 번호를 eax 레지스터에 저장한다.

3-6. syscall.c 수정


‘syscall.c’의 윗부분 에서는 extern int로 시스템 호출 함수들을 전역 변수로써 선언하고 있다. 앞서 ‘sysproc.c’에서 작성했던 함수를 전역 변수로 선언해주었다.

아래엔 시스템 콜 함수들이 static int (*syscalls[])(void) 형태로 함수 포인터형 배열로 선언되어 있다. 포인터 배열이기 때문에, 각 값에는 함수의 메모리 주소가 기록된다.

추가할 ps명령어를 같은 형식으로 추가하였다.

3-7. proc.c 수정



ptable의 proc 구조체의 구조를 참고하여, p라는 proc 구조체 포인터를 만들고, 루프문으로 ptable의 시작 주소로 초기화하여 p++로 순회 시키며 ptable의 마지막 프로세스일 때까지 프로세스의 상태에 따라 p->pid, p->name, p->state를 출력시켰다.

xv6에서 프로세스가 생성될 때 pid가 올라가며 부여되어 ptable에 저장되기 때문에, 추가한 ps() 명령어를 사용한다면 ptable을 시작부터 순회했기 때문에 pid에 대해 오름차순으로 정렬될 것이다.

3-8. ps.c 파일 작성


실제로 시스템 콜 ps()를 호출하는 ‘ps.c’ 파일을 작성한다.

3-9. Makefile 수정



생성한 ‘ps.c’ 파일을 연결하기 위해 ‘Makefile’에 생성한 ‘ps.c’를 추가시킨다.

4. 결과 및 결과 분석


xv6에서 ls 명령어를 통해 추가한 ps 시스템 콜을 호출하는 유저 프로그램 ’ps’가 추가된 것을 확인할 수 있다.

<그림 4-1><그림 4-2><그림 4-3>

그림 4-1에서, 추가한 ps 명령어를 통해 현재 프로세스들의 상태가 정상적으로 출력되고 있음을 볼 수 있다. pid 3인 프로세스는 앞에서 호출한 ls 명령어로 생성된 프로세스에게 부여되었다가 종료되며 사라진 것으로 보인다.

앞에서 예측했던 바와 같이, 지역변수로 선언한 proc 구조체 포인터를 ptable에 대하여 이터레이터로써 순회시켰기 때문에 pid에 따라 정렬되는 듯한 모습으로 출력되었다.

그림 4-2에서, sh 명령어로 쉘을 실행한 후 ps 명령어로 프로세스가 정상적으로 생성되었음을 확인하였다.

그림 4-3에서는, kill 명령어를 통해 pid 5의 프로세스를 종료하였다. 그림 3에서 pid5의 sh가 사라진 것을 볼 수 있으며, kill의 pid가 7로 부여됐을 것이므로 마지막 실행한 ps의 pid는 8이다.

이번 작업을 통해 xv6의 프로세스 관리, 유저 공간과 커널 공간의 구분, 시스템 콜 호출 방식을 코드를 수정하면서 직접 확인해 볼 수 있었다.

(그림 출처: xv6: a simple, Unix-like teaching operating system, xv6 book rev11)

위 그림과 같이, xv6는 실행 중인 프로그램에 서비스를 제공하는 커널의 전통적인 형태를 취한다. 프로세스라고 불리는 실행 중인 각 프로그램은 명령어, 데이터 및 스택을 포함하는 메모리를 갖고 있다. 명령어는 프로그램의 연산을 실행시키고, 데이터는 계산에 사용되는 변수 등이 들어 갈 수 있으며 스택은 함수와 같은 프로그램의 프로시저 호출을 구성한다.

프로세스가 시스템 호출을 하면(시스템 함수 사용 등의 목적으로), 시스템 호출은 커널로 들어가고, 커널은 서비스를 수행하고 반환한다.

즉, 프로세스는 시스템 콜에 의해 사용자 공간과 커널 공간 사이에서 번갈아 실행된다는 것을 알 수 있다.

5. 참고 자료


• xv6 source code, https://github.com/mit-pdos/xv6-public
• a simple, Unix-like teaching operating system, xv6 book rev11
• Xv6, a simple Unix-like teaching operating system, https://pdos.csail.mit.edu/6.828/2021/xv6.html
• boot xv6, https://pdos.csail.mit.edu/6.828/2018/homework/xv6-boot.html

0개의 댓글