PintOS_Project02_Argumentpassing 시작 전

전두엽힘주기·2025년 5월 18일

PintOS

목록 보기
7/20
  1. 받은 문자열을 parsing 후 argv, argc에 저장
  2. 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()에서 처리됨

argv = read_command_line ();

LOADER_ARGS에 있는 문자열 → argv[] 배열로 파싱

커널 명령줄을 단어 단위로 분리한 후, argv 배열에 저장

argv[0] = "-q"
argv[1] = "-f"
argv[2] = "run"
argv[3] = "args-single onearg"   // 큰따옴표나 작은따옴표는 하나의 인자로 처리됨
argv[4] = NULL

argv = parse_options (argv);

-로 시작하는 옵션을 처리

ARGV[] 배열에서 옵션들을 파싱한 후, 첫 번째 인자를 반환

  1. *argv가 -로 시작하는 동안 반복

argv[0] == "-q"
• name = "-q", value = NULL
• power_off_when_done = true 설정

argv[1] == "-f"
• name = "-f", value = NULL
• format_filesys = true 설정

  1. argv[2] == "run" (더 이상 -로 시작하지 않음) → 반복 종료
// parse_options(argv) 호출 이후 반환되는 argv:
argv[0] = "run"
argv[1] = "args-single onearg"
argv[2] = NULL

run_actions (argv);

static const struct action actions[] = {
		{"run", 2, run_task},

command line에서 run option을 준 경우, run_task 를 실행시킨다

run_task (char **argv)

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)

process_create_initd (const char *file_name)

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") 실행!

initd (void *f_name)

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)

process_exec (f_name)

f_name= 'args_single onearg'

	/* And then load the binary */
	success = load (file_name, &_if);

load (const char file_name, struct intr_frame if_)

/* TODO: Your code goes here.

  • TODO: Implement argument passing */

2개의 댓글

comment-user-thumbnail
2025년 5월 18일

쉽네 ㅋ

1개의 답글