크래프톤 정글

Pintos Project1 - 시작 준비

Jerry_K 2024. 11. 2. 09:58

✨ Pint OS 

  • Pintos는 x86-64 아키텍처용으로 설계된 간단한 운영체제 프레임워크
  • Pintos는 커널 스레드, 사용자 프로그램 로딩 및 실행, 파일 시스템을 지원

 

Pint OS projects 

  • Project 1 (Threads): 스레드와 동기화 기초, 기본 스케줄링
  • Project  2 (User Programs): 사용자 프로그램 로딩 및 시스템 호출 구현
  • Project  3 (Virtual Memory): 가상 메모리 관리
  • Project  4 (File System): 파일 시스템 확장

 

Pint OS projects1  주요 내용

기본 스레드 시스템 확장:

  • Pintos에 구현된 간단한 스레드 시스템이 시작점
  • 다양한 스레드 관련 기능을 추가 및 동작 방식을 개선

 

동기화 문제 해결:

  • 스레드 시스템의 확장은 주로 동기화와 관련된 문제를 해결하는 데 중점
  • 락(Lock), 세마포어(Semaphore), 조건 변수(Condition Variable) 등의 동기화 도구들을 사용
  • 스레드 간에 올바른 데이터 접근을 보장하고, 교착 상태를 방지

 

작업 디렉토리:

  • 대부분의 작업은 threads 디렉토리 이뤄짐
  • threads  디렉토리에서 스레드 기능과 동기화 관련 기능을 구현하고 수정
  • 일부 작업은 devices 디렉토리에서도 이뤄짐
    •  ex) 타이머 인터럽트와 관련된 코드를 수정

 

동기화 개념 사전 학습:

  • 본격적인 구현 작업에 들어가기 전, 동기화 관련 자료를 이해하기 ! 
  • 동기화 기법에 대한 이해는 스레드 간 자원 접근을 안전하게 관리하는 데 필수적
  • 여러 스레드가 동시에 작업을 수행할 때 발생하는 문제
  • 이를 해결하기 위한 도구들(락, 세마포어 등)의 작동 방식을 이해

 

QEMU (Quick EMUlator)

  • 오픈 소스 하드웨어 애뮬레이터
  • 가상 머신을 생성하여 다양한 운영 체체를 실행할 수 있는 도구 (핀토스 실행)
권장 개발 환경 
GCC: gcc 7.4.0 (컴파일러 버전)
QEMU: qemu-system-x86_64 version 2.5.0 (에뮬레이터 버전)

 

 

📌 환경 설정 명령어 (로그인 시 자동 실행 설정)

echo "source ~/jungle/PintOS-Project1/activate" >> ~/.bashrc

내 파일 경로 기준으로 작성

 

source ~/.bashrc

 

이 과정으로 매번 수동으로 환경 설정을 하지 않아고, 자동으로 설정된 환경에서 작업 진행 가능 

  • source ./activate는 Pintos 프로젝트가 정상적으로 작동하기 위한 환경 변수들 
  • PATH 환경 변수에 Pintos에서 사용하는 경로를 추가해 Pintos 커맨드 어디서든 실행 가능
  • source는 현재 쉘 세션에 해당 스크립트를 로드하고 실행하는 명령어

 

디렉토리 구조 및 역할 설명 

threads

  • 기본 커널 소스 코드가 들어있음
  • Project 1 부터 여기 있는 파일들 수정
  • 스레드 관리, 스케줄링, 동기화와 관련된 소스 코드 포함

threads 세부 디렉토리

  • loader.S, loader.h:
    • 커널 로더로, 부팅 시 커널을 디스크에서 메모리로 로드
    • 이후 bootstrap() 함수로 점프하는 초기화 코드
    • 수정할 필요 없음.
  • kernel.lds.S:
    • 커널을 메모리에 링크하는 스크립트
    • start.S가 커널 이미지의 시작에 위치
    • 수정할 필요 없음.
  • init.c, init.h:
    • 커널 초기화 및 main() 함수가 정의
    • 커널이 부팅될 때 초기화하는 항목을 확인
    • 초기화가 필요한 코드가 있으면 여기에 추가
  • thread.c, thread.h:
    • 기본 스레드 기능이 정의된 파일
    • 스레드 관련 구조체인 struct thread를 정 의
    • 이 구조체는 프로젝트 1~4에서 자주 수정
    • 프로젝트 1에서 대부분의 작업이 이 파일에서 이루어짐
  • palloc.c, palloc.h:
    • 페이지 할당기
    • 메모리를 4KB 페이지 단위로 할당
    • 시스템 메모리를 관리할 때 참고
  • malloc.c, malloc.h:
    • 커널 전용 malloc()와 free() 함수의 간단한 구현체
    • . 작은 블록 단위로 메모리를 할당하는데 유용
  • interrupt.c, interrupt.h:
    • 기본 인터럽트 처리와 제어 함수를 정의
    • 인터럽트를 켜고 끄는 함수들도 포함
  • intr-stubs.S, intr-stubs.h:
    • 저수준 인터럽트 처리에 필요한 어셈블리 코드
    • 인터럽트를 처리하는 데 필요한 기본적인 설정을 도움
  • synch.c, synch.h:
    • 동기화 도구(세마포어, 락, 조건 변수, 최적화 장벽 등)가 구현
    • 동기화와 관련된 모든 프로젝트에서 자주 사용
  • mmu.c, mmu.h:
    • x86-64 페이지 테이블 연산 함수가 포함
    • 페이지 테이블을 다루기 위한 기능을 정의
    • 프로젝트 3에서 자세히 다룸
  • io.h:
    • I/O 포트 접근 함수가 포함
    • devices 디렉토리 코드에서 주로 사용
  • vaddr.h, pte.h:
    • 가상 주소 및 페이지 테이블 엔트리를 다루는 함수와 매크로가 포함
    • 주로 프로젝트 3에서 중요하게 다룸
  • flags.h:
    • x86-64 플래그 레지스터의 일부 비트를 정의하는 매크로가 포함
    • 프로젝트에 큰 영향 없음

 

devices

  • (키보드,타이머,디스크 등) I/O interfacing을 위한 소스코드
  • Project 1에서 timer 코드를 수정
  • 그 외엔 코드 수정 필요 없음 

devices 세부 디렉토리

  • timer.c, timer.h:
    • 시스템 타이머
    • 본적으로 1초에 100번 틱을 발생
    • 스레드 스케줄링이나 동기화에 활용
    • 프로젝트 1에서 이 코드를 수정
  • vga.c, vga.h:
    • VGA 디스플레이 드라이버
    • 화면에 텍스트를 출력
    • printf()가 이 드라이버를 호출하므로 직접 호출할 필요는 없음
  • serial.c, serial.h:
    • 직렬 포트 드라이버
    • printf()가 이 코드를 사용해 출력
  • block.c, block.h:
    • 블록 디바이스 추상화 계층
    • 디스크와 같은 랜덤 액세스 가능한 블록 디바이스의 작업을 정의
    • 프로젝트 2부터 사용
  • ide.c, ide.h:
    • 최대 4개의 IDE 디스크에서 섹터를 읽고 쓰는 기능을 지원
  • partition.c, partition.h:
    • 디스크 파티션을 이해하고
    • 디스크를 여러 파티션으로 나누어 관리
  • kbd.c, kbd.h:
    • 키보드 드라이버
    •  키보드 입력을 받아 input 레이어로 전달
  • input.c, input.h:
    • 입력 레이어
    •  키보드나 직렬 포트 드라이버로부터 받은 입력 문자를 큐에 저장
  • intq.c, intq.h:
    • 인터럽트 큐로, 원형 큐를 사용해 커널 스레드와 인터럽트 핸들러가 접근
  • rtc.c, rtc.h:
    • 실시간 시계(RTC) 드라이버로, 커널이 현재 날짜와 시간을 확인
    • 주로 thread/init.c에서 랜덤 시드 값을 결정할 때 사용
  • speaker.c, speaker.h:
    • PC 스피커를 통해 음을 출력할 수 있는 드라이버
  • pit.c, pit.h:
    • 프로그래머블 인터럽트 타이머(PIT)를 설정하는 코드
    • timer.c와 speaker.c에서 각각의 디바이스에 맞는 채널을 사용해 설정

 

 

threads 디렉토리의 thread.c, synch.c, timer.c와 같은 파일들은
프로젝트 1에서 주요 수정 대상으로 동기화 문제 해결에 중요한 역할

 

 

 

(아래는 이후 사용 될 예정)

  •  

userprog/

  • user program loader의 소스코드
  • Project2에서 수정 시작
  • 시스템 호출, 프로세스 생성 및 종료, 메모리 항당 기능 이곳에서 처리

 

vm/

  • 거의 비어있는 디렉토리
  • Project3에서 가상메모리 구현 예정
  • Project3에서는 페이지 테이블, 스왑, 페이징 등의 가상 메모리 관련 기능 구현

 

filesys/

  • 기본적인 file system의 소스코드
  • Project2에서 사용하지만, Project4에서 수정
  • 파일 시스템을 이용해 파일 저장,읽어오는 기능 제공
  • Project4에서 파일 시스템 기능 강화 

lib/

  •  표준 C 라이브러리의 일부분 구현
  • 이 디렉토리의 코드들이 Pintos 커널과 그 커널에서 동작하는 User program 으로 컴파일
  • 대부분의 경우 이 코드 수정할 필요 없지만, 특정 기능을 위해 일부 라이브러리 참조 

 

inclue/lib/kernel

  • Pintos 커널에만 포함된 C 라이브러리
  • bitmaps, doubly linked list, hash tables 같은 자료형 구현
  • 커널에서 자유롭게 사용가능한 자료형
  • 이 디렉토리의 헤더들은 #include < ... > 표기법으로 포함시키면 됨

 

test/

  • 각 Project용 테스트 코드 포함
  • 제출하기 전 테스트를 통해 프로젝트가 잘 작동하는지 확인 

 

examples/ 

  • Project2에서 사용할 User program 용 예제들
  • 예제 프로그램을 통해 User program이 상호작용하는 방식 이해

 

include/

  • 프로젝트에서 사용하는 모든 헤더파일이 들어있는 디렉토리
  • include 디렉토리 아래에는 lib, threads, userprog, vm 등 다양한 디렉토리와 헤더 파일 포함
  • 프로젝트에서 모듈 간 인터페이스를 정의  

 

 

build 디렉토리의 주요 파일 설명

Makefile 

  • pintos/src/Makefile.build의 복사본으로, 커널을 빌드하는 방법을 설명
  • 커널 빌드, 객체 파일 생성, 의존성 관리 등 빌드 프로세스 자동화

kernel.o

  • 커널의 전체 객체 파일
  • 개별 커널 소스 파일을 컴파일하여 모든 객체 파일 하나로  linking

kernel.bin

  • 커널의 메모리 이미지 파일
  • 커널을 메모리에 로드하고 실행할 때 사용하는 정확한 바이트 코드
  • 디버그 정보를 제거함으로써 파일 크기를 줄임 

loader.bin

  • 커널 로더의 메모리 이미지 파일
  • 어셈블리어로 작성된 코드
  • 커널을 디스크에서 메모리로 읽어와 실행하는 역할

 

빌드 방법

make
make check

 

  • make check 는 전체를 컴파일하여 너무 오래 걸림

 

make build/tests/threads/alarm-single.result
make build/tests/threads/alarm-multiple.result
make build/tests/threads/alarm-simultaneous.result
make build/tests/threads/alarm-priority.result
make build/tests/threads/alarm-zero.result
make build/tests/threads/alarm-negative.result
  • 해당 명령어로 원하는 부분만 결과 확인 가능
  • (현재 명령어는 alarm 실행 기준)

 

pintos -v -- -q run alarm-single
pintos -v -- -q run alarm-multiple
pintos -v -- -q run alarm-simultaneous
pintos -v -- -q run alarm-priority
pintos -v -- -q run alarm-zero
pintos -v -- -q run alarm-negative
  • result가 나오면 pintos 환경에서 특정 테스트 직접 실행
  • 해당 빌드는 build 경로에서 해야 함

 

다음 포스팅은 Alarm clock 구현 할 예정 !