이 글은 pintos 프로젝트의 정답 코드 및 이론을 포함하고 있습니다.
pintos의 취지 특성 상 개인의 공부, 고민 과정이 정말 중요하다고 생각하며
프로젝트 풀이에 대한 스포일러를 받고싶지 않으신 분은 읽으시는걸 비추천 합니다.
그냥 아주 난리가 났다..
이번 글은 PintOS 구현보다는 개념과 왜 이걸 해야하는지 , 그리고 어떻게 구현해야 하는지에 대한 로드맵을 정리할 생각이다.
계속 구현하면서 드는 생각이
물론 내가 코딩하는 코드들을 정확하게 이해하고 구현할 실력이 있다면 모를까 이제 코딩 시작한지 얼마 안된 햇병아리가 감당할 수 있는 부분이 아니라는 생각이 들었다.
그래서 이번 PintOS에서는 구현도 '중요'하지만 개념을 정확하게 얻어가는 것에 집중을 할 생각이다. 안되는거 붙잡고 때써봤자 선생님이 와서 숙제 줄여주는것도 아니고 최대한 내가 얻어먹을 수 있는건 다 먹고 가겠다는 마음가짐이다.
이전 Alarm clock 프로젝트와의 차이점을 소개 한 후, 어떻게 진행되는지에 대해 알려주고 있다.
프로젝트1인 alarm clock은 커널의 한 부분이었다. 그렇기에 우리가 코딩한 코드들은 커널의 한 부분으로서 시스템에 접근할 수 있는 권한이 있었다. 하지만 프로젝트2부터는 이러한 이점은 전혀 주어지지 않을 것이다.
프로젝트2부터는 프로그램이 실행되어야 한다. 각각의 프로세스는 싱글스레드 환경이며 , 여러 프로세스를 로드하고 실행할때 환상(추상화)를 만족시키는 방향으로 관리해야 한다는 것을 의미한다.
즉 , 위의 말을 요약하자면 다음과 같다.
프로젝트 1은 커널에서 접근하는 코드들이기 때문에 권한이 많았다.
하지만 프로젝트는 프로세스를 실행하는 것이기 때문에 시스템 콜을 이용하여 커널에서 접근해야 한다.
여러 프로세스가 작동할때 문제가 생기지 않게 코드를 짜야한다.
프로젝트 1에서는 커널에 직접 돌렸기 때문에 유저가 파일을 실행하지 않았다. 하지만 이번에는 명령어로 파일을 실행시켜야 하기 때문에 User stack에 인자값을 push해야 한다.
먼저 알아야 할 내용은 register를 어떻게 써야 하는가? 이다.
다음 레지스터를 주의깊게 보자.
rax - 값 반환 레지스터, 시스템 콜의 번호를 가리키기도 함
rdi - 문자열 출발지 주소,
rsi - 문자열 목적지 주소,
rsp - 스택 포인터 , 스택의 제일 밑부분을 가리킴
이를 위해서 우리가 해야 할 일은 다음과 같다.
strtok_r 을 이용해서 f_name을 파싱한다.
rdi에 파싱된 부분의 개수를 입력
load로 파일을 불러온 후
list[]로 string을 저장한다.
padding을 집어넣어서 데이터 크기를 맞춘 후
데이터를 집어넣는다.
rsp는 계속 갱신해주다 데이터를 다 집어넣었으면 rsi를 rsp의 값으로 갱신하고 끝낸다.
위의 과정을 하고 나면 다음과 같은 상황이 나온다.
/bin/ls -l foo bar 명령어 실행
여기서 중요하게 봐야 할 포인트는 다음과 같다.
Adress는 처음에는 불규칙적으로 감소하다 , Padding을 넣은 char 구간부터는 일정하게(char 크기만큼) 감소한다.
padding을 넣은 주소의 Data는 원본 데이터를 가리키는 포인터이다.
RDI는 파싱된 단어의 개수이다.
RSI는 데이터를 읽어들일 지점을 가리키고 있다.
그러니까, 위의 레지스터 설명과 함께 이해를 하면
RSI의 주소부터 위로 4칸까지 읽어들인다.
라는 말이 되고 , 그렇게 읽어들이면
0x4747ffed -> '/bin/ls\0'
0x4747fff5 -> '-l\0'
0x4747fff8 -> 'foo\0'
0x4747fffc -> 'bar\0'
즉 , /bin/ls -l foo bar 가 읽어지게 되는 것이다.
레지스터 마다 쓰임세가 다르고 사용방법도 다르다.
결국 스택을 사용하려면 스택포인터 , rsi , rdi가 필요하며
반환값을 저장할 rax도 필요하다는걸 알게 되었다.
드디어 프로젝트 2번째의 첫번째 과제가 끝났다..!
앞으로 할 과제도 많이 있고 이제 시작에 불과하다.
요즘 잘때 꿈 내용은 기억이 안나긴 하는데 아마 코딩하다가 막히고 fix하고 막히고 하는 꿈인거 같다.
잠을 자도 편하게 못자는데 , 빨리 pintos 과제를 끝냈으면 좋겠다..