우선 PintOS 는 2004년 스탠포드 대학에서 만들어진 교육용 운영체제라고 한다.
해당 과정은 KAIST 에서 진행하는 KAIST PintOS 과정으로 진행된다.
https://casys-kaist.github.io/pintos-kaist/
처음에는 너무 방대한 양의 이론들과 자료들이 넘쳐나서.. 뭐부터 공부해야할지 갈피가 안잡혔는데
우선 코치님들이 PintOS 바이블이라고 설명해주신 Gitbook -> KAIST 강의 -> 한양대 강의 자료를 보고 프로젝트 진행의 갈피를 잡을 수 있었다.
1. PintOS 에서의 GDB 사용법
-g
옵션을 사용해서 컴파일 해야한다.- 적절한 정보를 포함한 컴파일이 가능하다.
- GDB 실행
gdb [file]
- gdb로 인자 넘기기
(gdb) set args argument
continue(c)
: breakpoint를 만날 때까지 프로그램 실행step(s)
: 함수 내부로 진입next(n)
: 함수 건너뜀finish
: 함수 종료 및 중지return [value]
: 함수 실행을 취소하고 [value] 로 돌아감list
: 현재 실행 중인 부분의 소스코드 출력list [number]
: [number] 번째 줄 출력list [function]
: [function]의 소스 코드 출력set listsize [n]
:list
명령어를 쳤을때 보여지는 라인 수 조정
whatis [var]
: 변수 타입 출력print(p) [var]
: 변수 출력
- 원하는 곳에 중단점 설정
break(b) [number]
break(b) [func]
break(b) [file:func]
break(b) [file:number]
info break
delete [number]
: 이전에 설정해둔 중단점 제거
PintOS 디버그 방법
- terminal 1
>>> pintos --gdb -- -q run alarm-multiple
(새로운 터미널을 연다.)
- terminal 2
>>> gdb --tui kernel.o # gdb 진입 >>> target remote localhost:1234
2. 테스트 방법
>>> cd ./pintos-kaist/threads
>>> make
>>> pintos -- -q run alarm-single # pintos -- -q run [테스트 명]
>>> pintos -- -q run alarm-multiple
- -q 옵션 : 프로그램이 호출된 이후 종료된다.
- 빌드 파일이 꼬여서 안되는 경우가 많으니, make 전에 make clean 을 습관화하자! 🤣
3. QEMU
- What is qemu?
Qemu 는 PC 환경을 위한 하나의 프로세스 애뮬레이터로, 프로세스 뿐만 아니라 각종 주변기기까지 애뮬레이터한다.
하나의 가상 컴퓨터를 구축해주는 소프트웨어로, 가상화 솔루션의 하나라고 보면 된다.
Guest 운영체제가 하드웨어 자원에 대한 접근을 요청할 때
- 해당 요청을 Qemu로 보낸다.
- 요청을 받은 Qemu는 해당 명령을 변환한다.
- 하드웨어로 해당 명령을 전달해서 요청을 처리한다.
Project 1. Introduction
🎯 Goal : 최소한으로 작동하는 스레드 시스템 구현, 동기화 문제 이해
- 주로
threads
디렉토리에서 작업하며,devices
디렉토리를 작업하게 될 수도 있다. threads
컴파일은 디렉토리에서 이루어져야한다.
1. 스레드 이해하기
- 이미 구현되어 있는 사항
- 스레드 생성
- 스레드 완료
- 스레드 전환을 위한 스케줄러
- 동기화 프리미티브(semaphores, locks, condition variables, and optimization barreier)
thread_creat()
- 새로운 컨텍스트를 생성한다.
- 컨텍스트에서 실행할 함수를
thread_create()
의 인수로제공한다. - 주어진 시간에 하나의 스레드가 실행되고 나머지는 비활성화된다.
- 함수 리턴 → 스레드 종료
- 스케줄러는 다음에 실행할 스레드를 결정한다.
- 만약 실행 준비된 스레드 존재 ❌ →
idle()
스레드가 실행된다. - synchronization primitives는 하나의 스레드가 또다른 스레드의 작업 수행을 위해 대기해야할 때 컨텍스트 스위칭을 할 수 있다.
thread_launch()
_ by. treads/tread.c (⭐️ 이해할 필요는 없음)- 컨텍스트 스위칭의 메커니즘이 구현되어있다.
- 현재 실행중인 스레드의 상태를 저장하고 전환하려는 스레드의 상태를 복원한다.
📢 gdb 이용해서 컨텍스트 스위치를 통해 추적하라.
schedule()
에 중단점을 설정해서 어떤 과정이 발생되는 지를 파악하라.- 한 스레드가
iret
을 실행할 때(do_iret()
) 또다른 스레드가 작동된다. - 핀토스에서 각 스레드는 4kb미만의 작은 고정 크기의 실행 스택이 할당된다.
- 스택 할당의 대안으로 page allocator와 block allocator를 사용할 수 있다. (ref)
2. 소스 파일
- ⭑ : 현재 프로젝트랑 관련있는 파일들
threads
threads
├── Make.vars
├── Makefile
├── init.c # 커널 초기화(main()을 포함한다.) ⭑
├── interrupt.c # 기본 인터럽트 처리
├── intr-stubs.S # 저수준 인터럽트 처리
├── kernel.lds.S # 커널 연결 링커 스크립트
├── loader.S # 커널 로더
├── malloc.c # malloc 구현
├── mmu.c # 페이지 테이블 작업(lab 1 이후)
├── palloc.c # page allocator
├── start.S
├── synch.c
├── targets.mk
└── thread.c # 기본 스레드 ⭑
devices
devices
├── disk.c
├── input.c # 입력 레이어
├── intq.c # 인터럽트 큐
├── kbd.c # 키보드 드라이버
├── serial.c
├── targets.mk
├── timer.c # 초당 100회 작동하는 시스템 타이머 ⭑
└── vga.c # VGA 디스플레이 드라이버 - 텍스트 쓰기 담당(x)
lib
lib/user
의 경우 프로젝트 2에서 사용해야한다.(커널의 일부는 아니다.)
lib
├── arithmetic.c
├── debug.c
├── kernel
│ ├── bitmap.c # 비트맵 구현(프로젝트 1 이외, 원한다면 사용)
│ ├── console.c
│ ├── debug.c # 디버깅 지원
│ ├── hash.c # 해시 테이블 구현(프로젝트 3)
│ ├── list.c # 이중 연결 리스트 구현(주석 훑어보는 것 추천) ⭑
│ └── targets.mk
├── random.c # 난수 생성
├── stdio.c
├── stdlib.c
├── string.c
├── targets.mk
└── user
├── console.c
├── debug.c
├── entry.c
├── syscall.c
└── user.lds
3. 동기화
- 모든 동기화 문제는 인터럽트를 끄면 해결할 수 있다.
- 인터럽트가 꺼져 있는 동안에는 동시성이 없으므로 경쟁 조건이 발생할 가능성이 없다.
- But, 해당 방법으로 해결하지말고 세마포어, 락, 상태 변수를 이용해서 해결해라!
threads/synch.c
를 읽어라synch.c
인터럽트를 비활성화해서 구현한다.- 커널 스레드와 인터럽트 처리기 공유되는 데이터를 조정한다.
- 인터럽트 핸들러는 sleep 할 수 없기 때문에, lock을 할 수가 없다.
→ 인터럽트를 꺼서 커널 스레드와 인터럽트 핸들러 간에 공유되는 데이터를 보호한다.
- 인터럽트를 끄면 인터럽트 핸들링 latency가 매우 증가할 수 있다.
synch.c
동기화 프리미티브는 인터럽트를 비활성화하면서 구현된다.
- busy waiting 이 없어야한다. →
thread_yield()
는 busy waiting 의 형태이다.
🙋 synchronization primitives?
Synchronization primitives는 플랫폼에 의해 제공되는 단순한 소프트웨어 메커니즘이다. 이것의 목적은 스레드나 프로세스의 동기화이다. 일반적으로 저수준의 메커니즘이다. (e.g. atomic operations, memory barriers, spinlocks, context switches etc).
ref. primitives
- Our pintos project : semaphores, locks, condition variables, optimization barreier
지옥의 핀토스 주간.. 시작,,,ㅠㅠㅠㅠ 아자 👊🏻
끝의 끝까지 하면 기회는 반드시 온다.
'🌱 Dev Diary > 📄 TIL' 카테고리의 다른 글
Project 1. Priority Scheduling 구현 (1) (1) | 2022.12.26 |
---|---|
Project 1. Alarm Clock 구현 (0) | 2022.12.24 |
Team Session - File Descriptor(FD) (1) | 2022.12.11 |
Malloc Lab 구현 (0) | 2022.12.08 |
Team Session - Data Segment (0) | 2022.12.08 |