728x90
반응형
Argument Passing
프로세스 함수
load()
명령어 라인(Command Line)으로 입력받은 파일명과 인자들을 USER STACK에 PUSH하고 레지스터에 argv, argc를 지정
uintptr_t phys_base = if_->rsp;
// 기존에 만들었던 Stack을 사용(오른쪽 인자부터 유저스택에 넣기 위해서 사용)
Stack stack;
int lenArr[100] = {0};
int idx = 0;
int args_count = 1;
int stack_size;
char *addr_list[20];
// 파일명 넣기
push(&stack, file_name);
// 인자 넣기
for (token = strtok_r(NULL, " ", &saveptr); token; token = strtok_r(NULL, " ", &saveptr))
{
push(&stack, token);
args_count++;
}
stack_size = stack.top;
// 역순으로 스택에서 뽑아서 유저스택에 인자 넣기
while (stack.top != 0)
{
char *temp = pop(&stack);
if_->rsp -= strlen(temp) + 1;
memcpy(if_->rsp, temp, strlen(temp) + 1);
addr_list[idx] = (char *)if_->rsp;
idx++;
size += strlen(temp) + 1;
}
// 패딩 넣기
if (size % 8 != 0)
{
int padding_size = 8 - (size % 8);
if_->rsp -= padding_size;
memset(if_->rsp, 0, padding_size);
}
// 구분자 넣기
if_->rsp -= 8;
memset(if_->rsp, 0, 8);
// 인자 담긴 주소 넣기(rsp)
for (int i = 0; i < stack_size; i++)
{
if_->rsp -= 8;
memcpy(if_->rsp, &addr_list[i], sizeof(void *));
}
if_->R.rsi = if_->rsp; // rsp
if_->R.rdi = args_count;
// 리턴 주소(가짜 주소)
if_->rsp -= sizeof(void *);
memset(if_->rsp, 0, sizeof(void *));
// 스택에 잘 들어갔는지 확인
hex_dump(if_->rsp, if_->rsp, phys_base - if_->rsp, true);
시스템 콜 처리
syscall_handler()
void syscall_handler(struct intr_frame *f UNUSED)
{
/* 시스템 콜 넘버 */
int sys_number = f->R.rax;
/*
1번째: %rdi
2번째: %rsi
3번째: %rdx
4번째: %r10
5번째: %r8
6번째: %r9
*/
switch (sys_number)
{
case 0:
halt();
break;
case 1:
exit(f->R.rdi);
break;
case 10:
// 받아온 인자 순서대로 삽입
write(f->R.rdi, f->R.rsi, f->R.rdx);
break;
}
// 여기서 쓰레드 종료하면 한번만 실행되고 끝남
// thread_exit();
}
halt()
power_off만 실행시켜주면 됨
void halt(void)
{
power_off();
};
exit()
현재 실행 중인 쓰레드의 exit_status를 -1로 변경하고 쓰레드를 종료시킴
void exit(int status)
{
// thread_current()->status = THREAD_DYING; //thread_exit에서 수행됨
struct thread *curr = thread_current();
curr->exit_status = status;
printf("%s: exit(%d)\n", curr->name, status);
thread_exit();
}
check_addr()
가상 주소가 매핑된게 없거나 유저 스택보다 같거나 크고 또는 주소가 NULL이면 종료시킴
void check_addr(void *addr)
{
// 가상메모리와 매핑된게 없거나 유저스택보다 같거나 크거나 NULL이면 종료
if (pml4_get_page(thread_current()->pml4, addr) == NULL || !is_user_vaddr(addr) || addr == NULL)
{
exit(-1);
}
}
write()
가상 주소의 유효성을 검사하고 파일 디스크립터가 1인지 체크하고 맞다면 putbuf를 이용해 출력
int write(int fd, const void *buffer, unsigned length)
{
// 주소 유효성 검사
check_addr(buffer);
if (fd != 1)
{
return -1;
}
else
{
putbuf(buffer, length);
}
};
728x90
반응형
'크래프톤 정글 - TIL' 카테고리의 다른 글
크래프톤 정글 5기 TIL - Day 70 (0) | 2024.05.30 |
---|---|
크래프톤 정글 5기 TIL - Day 67~69(Pintos Project 2) (0) | 2024.05.28 |
크래프톤 정글 5기 TIL - Day 60 ~ 64(PintOS Project 2) (0) | 2024.05.20 |
크래프톤 정글 5기 TIL - Day 53 ~ 59 (0) | 2024.05.13 |
크래프톤 정글 5기 TIL - Day 52(알고리즘) (0) | 2024.05.13 |