- 받은 문자열을 parsing 후 argv, argc에 저장
- stack에 인자넣기
in threads.init.c
/* Pintos main program. */
int
main (void) {
...
/* Break command line into arguments and parse options. */
argv = read_command_line ();
argv = parse_options (argv);
...
/* Run actions specified on kernel command line. */
run_actions (argv);
}
pintos --fs-disk=10 -p tests/userprog/args-single:args-single -- -q -f run 'args-single onearg' 명령어를 사용했다면
--fs-disk=10 -p tests/userprog/args-single:args-single
→ 파일 시스템 디스크 크기 설정 및 프로그램 등록
--
→ 커널 옵션과 유저 프로그램 명령어를 나누는 경계
이후의 인자들은 LOADER_ARGS에 저장되어 read_command_line() 함수로 전달
-q -f run 'args-single onearg'
→ 커널 명령줄 인자 (argv[]) 로 들어가며 이 부분이 read_command_line()과 parse_options()에서 처리됨
LOADER_ARGS에 있는 문자열 → argv[] 배열로 파싱
커널 명령줄을 단어 단위로 분리한 후, argv 배열에 저장
argv[0] = "-q"
argv[1] = "-f"
argv[2] = "run"
argv[3] = "args-single onearg" // 큰따옴표나 작은따옴표는 하나의 인자로 처리됨
argv[4] = NULL
-로 시작하는 옵션을 처리
ARGV[] 배열에서 옵션들을 파싱한 후, 첫 번째 인자를 반환
argv[0] == "-q"
• name = "-q", value = NULL
• power_off_when_done = true 설정
argv[1] == "-f"
• name = "-f", value = NULL
• format_filesys = true 설정
// parse_options(argv) 호출 이후 반환되는 argv:
argv[0] = "run"
argv[1] = "args-single onearg"
argv[2] = NULL
static const struct action actions[] = {
{"run", 2, run_task},
command line에서 run option을 준 경우, run_task 를 실행시킨다
Runs the task specified in ARGV[1]
static void
run_task (char **argv) {
const char *task = argv[1]; //argv[0]은 run, argv[1]부터 filename이 시작되는 문자열
printf ("Executing '%s':\n", task);
#ifdef USERPROG
if (thread_tests){
run_test (task);
} else {
process_wait (process_create_initd (task));
}
#else
run_test (task);
#endif
printf ("Execution of '%s' complete.\n", task);
}
argv[0]은 run, argv[1]부터 filename이 시작되는 문자열
task=argv[1]
process_create_initd (task)
tid_t
process_create_initd (const char *file_name) {
char *fn_copy;
tid_t tid;
/* Make a copy of FILE_NAME.
* Otherwise there's a race between the caller and load(). */
fn_copy = palloc_get_page (0);
if (fn_copy == NULL)
return TID_ERROR;
strlcpy (fn_copy, file_name, PGSIZE);
/* Create a new thread to execute FILE_NAME. */
tid = thread_create (file_name, PRI_DEFAULT, initd, fn_copy);
if (tid == TID_ERROR)
palloc_free_page (fn_copy);
return tid;
}
fn_copy는 file_name의 복사본 즉, args-single onearg
process_create_initd("args-single onearg")
└─▶ thread_create (file_name, PRI_DEFAULT, initd, fn_copy);
└─▶ 스레드가 실행되면 kernel_thread(initd, fn_copy)
└─▶ initd("args-single onearg") 실행!
static void
initd (void *f_name) {
#ifdef VM
supplemental_page_table_init (&thread_current ()->spt);
#endif
process_init ();
if (process_exec (f_name) < 0)
PANIC("Fail to launch initd\n");
NOT_REACHED ();
}
process_exec (f_name)
f_name= 'args_single onearg'
/* And then load the binary */
success = load (file_name, &_if);
/* TODO: Your code goes here.
쉽네 ㅋ