From 557942cd6a8ccc0f54211642d966cf728ccb2b99 Mon Sep 17 00:00:00 2001 From: mywnajsldkf Date: Wed, 7 Jun 2023 08:21:34 +0000 Subject: [PATCH 1/8] =?UTF-8?q?=E2=9C=A8=20feat=20:=20file=5Fname=20?= =?UTF-8?q?=EB=B3=B5=EC=82=AC=20#16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - const 타입인 file_name을 tokenizing 하기 위해 복제 --- userprog/process.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/userprog/process.c b/userprog/process.c index 9388e50..4dad362 100644 --- a/userprog/process.c +++ b/userprog/process.c @@ -329,6 +329,10 @@ load (const char *file_name, struct intr_frame *if_) { bool success = false; int i; + char *copy_filename; // file_name이 const 이므로 변경할 수 없기 때문에, 새롭게 작성해준다. + copy_filename = palloc_get_page (0); + strlcpy (copy_filename, file_name, MAXIMUM_NUMBER); + /* Allocate and activate page directory. */ t->pml4 = pml4_create (); if (t->pml4 == NULL) From 967617448901003e6e78fee9e72baaadd35fbf44 Mon Sep 17 00:00:00 2001 From: mywnajsldkf Date: Wed, 7 Jun 2023 08:24:17 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=E2=9C=A8=20feat=20:=20command=20line=20par?= =?UTF-8?q?sing=20#16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - strtok_r 함수를 이용해서 tokenizing - tokenizing한 token을 argv 배열에 저장 --- userprog/process.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/userprog/process.c b/userprog/process.c index 4dad362..8118b35 100644 --- a/userprog/process.c +++ b/userprog/process.c @@ -339,10 +339,26 @@ load (const char *file_name, struct intr_frame *if_) { goto done; process_activate (thread_current ()); + // command line parsing + char *argv[MAXIMUM_NUMBER/2]; + char *token, *save_ptr; + int argc = 0; + + token = strtok_r(copy_filename, BLANK_DELIMETER, &save_ptr); + argv[argc] = token; + + while (token != NULL){ + token = strtok_r(NULL, BLANK_DELIMETER, &save_ptr); + argc++; + argv[argc] = token; + } + + copy_filename = argv[0]; + /* Open executable file. */ - file = filesys_open (file_name); + file = filesys_open (copy_filename); if (file == NULL) { - printf ("load: %s: open failed\n", file_name); + printf ("load: %s: open failed\n", copy_filename); goto done; } From ddc5238b0734e21af7a3f1e58e061ef4d83cae87 Mon Sep 17 00:00:00 2001 From: mywnajsldkf Date: Wed, 7 Jun 2023 08:27:53 +0000 Subject: [PATCH 3/8] =?UTF-8?q?=E2=9C=A8=20feat=20:=20user=20stack?= =?UTF-8?q?=EC=97=90=20=ED=8C=8C=EC=8B=B1=ED=95=9C=20argument=EB=A5=BC=20?= =?UTF-8?q?=EB=8B=B4=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?#16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - file_name 파싱 결과를 담을 배열을 생성한다. - argv 뒤에서부터 인자들을 userstack에 저장한다. - 단어 정렬을 위해 패딩을 추가한다. - argv를 채운다. - rdi, rsi를 지정한다. - fake address를 저장한다. --- include/userprog/process.h | 1 + userprog/process.c | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/include/userprog/process.h b/include/userprog/process.h index 4365424..a6afd2f 100644 --- a/include/userprog/process.h +++ b/include/userprog/process.h @@ -9,5 +9,6 @@ int process_exec (void *f_name); int process_wait (tid_t); void process_exit (void); void process_activate (struct thread *next); +void argument_stack(char **argv, int argc, struct intr_frame *if_); #endif /* userprog/process.h */ diff --git a/userprog/process.c b/userprog/process.c index 8118b35..bc7769f 100644 --- a/userprog/process.c +++ b/userprog/process.c @@ -437,6 +437,7 @@ load (const char *file_name, struct intr_frame *if_) { /* TODO: Your code goes here. * TODO: Implement argument passing (see project2/argument_passing.html). */ + argument_stack(argv, argc, if_); // argv: list, argc: token_count, if_: interrupt_frame success = true; done: @@ -657,3 +658,49 @@ setup_stack (struct intr_frame *if_) { return success; } #endif /* VM */ + +void +argument_stack(char **argv, int argc, struct intr_frame *if_) +{ + // file_name 파싱 결과를 담을 배열 생성 -> s_argv + char *arg_address[MAXIMUM_NUMBER]; + + // word-align 전까지 + // argv 뒤에서부터 인자들을 userstack에 저장한다. + // /bin/ls -l foo bar + for (int i = argc-1; i >= 0; i--) + { + int arg_len = strlen(argv[i]) + 1; // 1은 sentinel(\0)을 의미한다. + if_->rsp = if_->rsp - (arg_len); // 인자 크기만큼 스택을 늘려준다., 시야를 더 늘린다. 스택 포인터를 이동시킨다. + memcpy(if_->rsp, argv[i], arg_len); + arg_address[i] = if_->rsp; + } + + // word-algin + while (if_->rsp % 8 != 0) + { + if_->rsp--; + *(uint8_t *) if_->rsp = 0; // 포인터 타입이 unit8_t이니까 rsp 데이터에 0을 넣는다.-> 패딩을 채운다. + } + + // argv를 채운다. + for (int i = argc; i >= 0; i--) + { + if_->rsp = if_->rsp - 8; + if (i == argc) // null sentinel 자리 + { + *(char **) if_->rsp = 0; + // memset(if_->rsp, 0, sizeof(char **)); + } + else + memcpy(if_->rsp, &arg_address[i], sizeof(char *)); + } + + // rdi, rsi + if_->R.rdi = argc; + if_->R.rsi = if_->rsp; + + // fake address를 저장한다. + if_->rsp = if_->rsp - 8; + memset(if_->rsp, 0, sizeof(char *)); +} \ No newline at end of file From dfac672f94832cdb56f7e287e31693dcb0088886 Mon Sep 17 00:00:00 2001 From: mywnajsldkf Date: Wed, 7 Jun 2023 08:28:56 +0000 Subject: [PATCH 4/8] =?UTF-8?q?=E2=9C=A8=20feat=20:=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=20=EA=B2=B0=EA=B3=BC=20=ED=99=95=EC=9D=B8=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20hex=5Fdump=20=ED=95=A8=EC=88=98=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=20#16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userprog/process.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/userprog/process.c b/userprog/process.c index bc7769f..8e76a66 100644 --- a/userprog/process.c +++ b/userprog/process.c @@ -184,6 +184,8 @@ process_exec (void *f_name) { if (!success) return -1; + hex_dump(_if.rsp, _if.rsp, USER_STACK - _if.rsp, true); + /* Start switched process. */ do_iret (&_if); NOT_REACHED (); From 7d7d7ade186126c5fed97973e37f6a14f90b0f0e Mon Sep 17 00:00:00 2001 From: mywnajsldkf Date: Wed, 7 Jun 2023 08:29:28 +0000 Subject: [PATCH 5/8] =?UTF-8?q?=E2=9C=A8=20feat=20:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=84=B8=EC=8A=A4=EA=B0=80=20=EC=8B=A4=ED=96=89=20=ED=9B=84=20?= =?UTF-8?q?=EB=B0=94=EB=A1=9C=20=EC=A2=85=EB=A3=8C=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EA=B2=83=EC=9D=84=20=EB=A7=89=EA=B8=B0=20=EC=9C=84=ED=95=B4=20?= =?UTF-8?q?waiting=EC=9D=84=20=EA=B1=B8=EC=96=B4=EC=A4=8C=20#16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userprog/process.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/userprog/process.c b/userprog/process.c index 8e76a66..3bb5be3 100644 --- a/userprog/process.c +++ b/userprog/process.c @@ -206,6 +206,11 @@ process_wait (tid_t child_tid UNUSED) { /* XXX: Hint) The pintos exit if process_wait (initd), we recommend you * XXX: to add infinite loop here before * XXX: implementing the process_wait. */ + for (int i = 0; i < 10000000000; i++) + { + /* code */ + } + return -1; } From e4a162a84855d54b34db8c4e216e38191f961141 Mon Sep 17 00:00:00 2001 From: mywnajsldkf Date: Wed, 7 Jun 2023 12:03:53 +0000 Subject: [PATCH 6/8] =?UTF-8?q?=F0=9F=93=9D=20chores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 전처리기 사용을 위해 #define USERFROG 추가(안해도 된다) - define 추가 --- threads/init.c | 1 + userprog/process.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/threads/init.c b/threads/init.c index aae924d..f4cb245 100644 --- a/threads/init.c +++ b/threads/init.c @@ -21,6 +21,7 @@ #include "threads/palloc.h" #include "threads/pte.h" #include "threads/thread.h" +#define USERPROG #ifdef USERPROG #include "userprog/process.h" #include "userprog/exception.h" diff --git a/userprog/process.c b/userprog/process.c index 3bb5be3..3ea04c0 100644 --- a/userprog/process.c +++ b/userprog/process.c @@ -21,6 +21,8 @@ #ifdef VM #include "vm/vm.h" #endif +#define BLANK_DELIMETER " " +#define MAXIMUM_NUMBER 128 static void process_cleanup (void); static bool load (const char *file_name, struct intr_frame *if_); From 1b90f44603d3d84bdb6989abf3d5e4930e7c235f Mon Sep 17 00:00:00 2001 From: mywnajsldkf Date: Wed, 14 Jun 2023 06:58:44 +0000 Subject: [PATCH 7/8] =?UTF-8?q?=F0=9F=93=9D=20chores=20:=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=B6=94=EA=B0=80=20#16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userprog/process.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/userprog/process.c b/userprog/process.c index 3ea04c0..27853a5 100644 --- a/userprog/process.c +++ b/userprog/process.c @@ -162,6 +162,8 @@ __do_fork (void *aux) { /* Switch the current execution context to the f_name. * Returns -1 on fail. */ +// 사용자가 입력한 명령을 수행하도록 프로그램을 메모리에 올려 실행한다. +// 실행 프로그램 파일과 옵션을 구분하는 작업을 추가한다. int process_exec (void *f_name) { char *file_name = f_name; @@ -179,6 +181,7 @@ process_exec (void *f_name) { process_cleanup (); /* And then load the binary */ + // file_name과 interrupt_frame을 load한다. success = load (file_name, &_if); /* If load failed, quit. */ @@ -186,6 +189,10 @@ process_exec (void *f_name) { if (!success) return -1; + /** + * Project2: Command Line Parsing + * parsing 결과 디버깅 + */ hex_dump(_if.rsp, _if.rsp, USER_STACK - _if.rsp, true); /* Start switched process. */ @@ -208,7 +215,12 @@ process_wait (tid_t child_tid UNUSED) { /* XXX: Hint) The pintos exit if process_wait (initd), we recommend you * XXX: to add infinite loop here before * XXX: implementing the process_wait. */ - for (int i = 0; i < 10000000000; i++) + + /** + * Project2: Command Line Parsing + * 프로세스 종료 대기 + */ + for (int i = 0; i < 100000000; i++) { /* code */ } @@ -338,8 +350,11 @@ load (const char *file_name, struct intr_frame *if_) { bool success = false; int i; - char *copy_filename; // file_name이 const 이므로 변경할 수 없기 때문에, 새롭게 작성해준다. + /* Project2: Command Line Parsing */ + // file_name이 const 이므로 변경할 수 없기 때문에, 복사해준다. + char *copy_filename; copy_filename = palloc_get_page (0); + // 생성한 copy_filename 문자열에 file_name을 복제해준다. strlcpy (copy_filename, file_name, MAXIMUM_NUMBER); /* Allocate and activate page directory. */ @@ -353,9 +368,12 @@ load (const char *file_name, struct intr_frame *if_) { char *token, *save_ptr; int argc = 0; + // 첫번째 이름을 받아온다. + // save_ptr은 앞 문자열을 자르고 남은 문자열의 가장 앞을 가리키는 포인터 주소값을 말한다. token = strtok_r(copy_filename, BLANK_DELIMETER, &save_ptr); - argv[argc] = token; - + argv[argc] = token; // 첫번째 인자가 저장된다.(ex. args-single onearg라면, args-single 저장) + + // 공백을 기준으로 문자열을 잘라서 argv 배열에 저장한다. while (token != NULL){ token = strtok_r(NULL, BLANK_DELIMETER, &save_ptr); argc++; @@ -445,7 +463,7 @@ load (const char *file_name, struct intr_frame *if_) { /* TODO: Your code goes here. * TODO: Implement argument passing (see project2/argument_passing.html). */ - + /* Project2: Argument Stack */ argument_stack(argv, argc, if_); // argv: list, argc: token_count, if_: interrupt_frame success = true; @@ -668,24 +686,25 @@ setup_stack (struct intr_frame *if_) { } #endif /* VM */ +/* Project2: Command Line Parsing */ void argument_stack(char **argv, int argc, struct intr_frame *if_) { - // file_name 파싱 결과를 담을 배열 생성 -> s_argv + // file_name 파싱 결과를 담을 배열을 생성한다. char *arg_address[MAXIMUM_NUMBER]; // word-align 전까지 - // argv 뒤에서부터 인자들을 userstack에 저장한다. + // argv 뒤에서부터 인자들을 userstack에 저장한다.(NULL 끝 값은 제외한다.) // /bin/ls -l foo bar for (int i = argc-1; i >= 0; i--) { int arg_len = strlen(argv[i]) + 1; // 1은 sentinel(\0)을 의미한다. - if_->rsp = if_->rsp - (arg_len); // 인자 크기만큼 스택을 늘려준다., 시야를 더 늘린다. 스택 포인터를 이동시킨다. + if_->rsp = if_->rsp - (arg_len); // 인자 크기만큼 스택 포인터를 이동시킨다. memcpy(if_->rsp, argv[i], arg_len); - arg_address[i] = if_->rsp; + arg_address[i] = if_->rsp; // arg_address 배열에 현재 문자열 시작 위치를 저장한다. } - // word-algin + // word-algin -> 정렬하기 위해 while (if_->rsp % 8 != 0) { if_->rsp--; @@ -699,7 +718,6 @@ argument_stack(char **argv, int argc, struct intr_frame *if_) if (i == argc) // null sentinel 자리 { *(char **) if_->rsp = 0; - // memset(if_->rsp, 0, sizeof(char **)); } else memcpy(if_->rsp, &arg_address[i], sizeof(char *)); From aeb6debac2c1ff7668eb3845feea769f1b310174 Mon Sep 17 00:00:00 2001 From: mywnajsldkf Date: Wed, 14 Jun 2023 07:26:33 +0000 Subject: [PATCH 8/8] =?UTF-8?q?=F0=9F=93=9D=20choers=20:=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=EC=A0=84=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EA=B8=B0=20=EC=82=AD=EC=A0=9C=20#16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- threads/init.c | 1 - 1 file changed, 1 deletion(-) diff --git a/threads/init.c b/threads/init.c index f4cb245..aae924d 100644 --- a/threads/init.c +++ b/threads/init.c @@ -21,7 +21,6 @@ #include "threads/palloc.h" #include "threads/pte.h" #include "threads/thread.h" -#define USERPROG #ifdef USERPROG #include "userprog/process.h" #include "userprog/exception.h"