๊ด€๋ฆฌ ๋ฉ”๋‰ด

๋ง๊ฐ๋กœ๊ทธ

PintOS Project2 : User Programs ๋ณธ๋ฌธ

Krafton jungle/PintOS

PintOS Project2 : User Programs

habbn 2024. 3. 21. 13:07
728x90

 


๐Ÿšซ PintOS๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ธฐ ์œ„ํ•œ ์ค€๋น„ ์ค‘ ๋งˆ์ฃผ์นœ ์—๋Ÿฌ

 

pintOS ๊ฐ€์ƒ ๋จธ์‹ ์— ํŒŒ์ผ์„ ๋„ฃ๊ธฐ ์œ„ํ•ด์„œ ๋จผ์ € ํŒŒ์ผ ์‹œ์Šคํ…œ ํŒŒํ‹ฐ์…˜์ด ์žˆ๋Š” ๋ชจ์˜ ๋””์Šคํฌ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. 

pintos-mkdisk filesys.dsk 10 
pintos --fs-disk filesys.dsk -p tests/userprog/args-single:args-single -- -q -f run 'args-single onearg'

 

์œ„์˜ ์ฝ”๋“œ๋Š” ํŒŒ์ผ ์‹œ์Šคํ…œ ํŒŒํ‹ฐ์…˜์œผ๋กœ ์–ด๋–ป๊ฒŒ ๋””์Šคํฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ํŒŒ์ผ ์‹œ์Šคํ…œ์˜ ํ˜•์‹์„ ๋งŒ๋“ค๊ณ , args-single์ด๋ผ๋Š” ์ด๋ฆ„์˜ ํ”„๋กœ๊ทธ๋žจ์„ ์–ด๋–ป๊ฒŒ ์ƒˆ ๋””์Šคํฌ์— ๋งŒ๋“ค๊ณ , onearg ๋ผ๋Š” ์ธ์ž๋ฅผ ์ „๋‹ฌํ•ด์„œ ์‹คํ–‰ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์š”์•ฝ ์ฝ”๋“œ์ด๋‹ค.

 

์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด kernel panic์„ ๋งˆ์ฃผํ•˜๊ฒŒ ๋œ๋‹ค.

Kernel PANIC at ../../threads/vaddr.h:87 in vtop(): assertion 
`is_kernel_vaddr (vaddr)' failed.

 

backtrace ๊ฒฐ๊ณผ

Call stack: 0x800421874b 0x80042072c0 0x800420a92f 0x8004214d12 0x8004209704 0x8004209b22 0x800420762b
Translation of call stack:
0x000000800421874b: debug_panic (lib/kernel/debug.c:32)
0x00000080042072c0: thread_yield (threads/thread.c:340)
0x000000800420a92f: sema_up (threads/synch.c:124)
0x0000008004214d12: interrupt_handler (devices/disk.c:526)
0x0000008004209704: intr_handler (threads/interrupt.c:353)
0x0000008004209b22: intr_entry (threads/intr-stubs.o:?)
0x000000800420762b: kernel_thread (threads/thread.c:456)

 

์ด ์˜ค๋ฅ˜๋Š” ํ”„๋กœ์ ํŠธ 1์—์„œ prioirty scheduling์„ ์œ„ํ•ด sema_up ํ•จ์ˆ˜์—์„œ thread_yield ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒƒ์ด ๋ฌธ์ œ์˜€๋‹ค.

ํŒŒ์ผ ์‹œ์Šคํ…œ์—์„œ sema_up์„ ํ˜ธ์ถœํ•  ๋•Œ externel interrupt๋ฅผ ๋„์ง€ ์•Š์•„์„œ assert๊ฐ€ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ๋ผ๊ณ  ํ•œ๋‹ค.

 

๊ทธ๋ž˜์„œ thread.c์—์„œ thread_try_yield() ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๊ณ  sema_up() ๋ถ€๋ถ„๋„ ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ์—๋Ÿฌ ํ•ด๊ฒฐ!

/* thread.c */

void thread_try_yield(void){
	if(!list_empty(&ready_list) && thread_current() != idle_thread && !(intr_context()))
		thread_yield();
}
/* synch.c */

void
sema_up (struct semaphore *sema) {
	enum intr_level old_level;

	ASSERT (sema != NULL);

	old_level = intr_disable ();

	if (!list_empty (&sema->waiters))
	{
		list_sort(&sema->waiters, cmp_priority, NULL);
		//sema->waiters์— ์žˆ๋Š” ๋งจ ์•ž ์“ฐ๋ ˆ๋“œ๋ฅผ ๊นจ์šด๋‹ค.
		thread_unblock (list_entry (list_pop_front (&sema->waiters),
				struct thread, elem));			
	}

	sema->value++;

	intr_set_level (old_level);	
	
	//cpu ์–‘๋ณด
	thread_try_yield();
}

 


Argument passing

userํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๊ธฐ ์ „์— ํ”„๋กœ๊ทธ๋žจ์— ๋Œ€ํ•œ ์ธ์ž๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค.

 

es) "/bin/ls -l foo bar" ์ธ์ž ์ฒ˜๋ฆฌํ•˜๊ธฐ

 

1. ๋ช…๋ น์–ด๋กœ ๋‹จ์–ด๋ฅผ ๋ถ„ํ• ํ•œ๋‹ค. /bin/ls, -l , foo, bar

2. ๊ฐ ๋ฌธ์ž์—ด์˜ ์ฃผ์†Œ + ๊ฒฝ๊ณ„์กฐ๊ฑด์„ ์œ„ํ•œ ๋„ํฌ์ธํ„ฐ๋ฅผ ์Šคํƒ์— ์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ ์ˆœ์„œ๋กœ ํ‘ธ์‹œํ•œ๋‹ค.

    ->  argv[0] ์ด ๊ฐ€์žฅ ๋‚ฎ์€ ๊ฐ€์ƒ ์ฃผ์†Œ๋ฅผ ๊ฐ€์ง„๋‹ค.

    -> ์ตœ๊ณ ์˜ ์„ฑ๋Šฅ์„ ์œ„ํ•ด ์ฒซ ๋ฒˆ์งธ ํ‘ธ์‹œ ์ „์— ์Šคํƒ ํฌ์ธํ„ฐ๋ฅผ 8์˜ ๋ฐฐ์ˆ˜๋กœ ์ •๋ ฌํ•œ๋‹ค.

3. %rsi๊ฐ€ argv ์ฃผ์†Œ( argv[0]์˜ ์ฃผ์†Œ)๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ํ•˜๊ณ , %rdi๋ฅผ argc๋กœ ์„ค์ •ํ•œ๋‹ค.

4. ๋งˆ์ง€๋ง‰์œผ๋กœ ๊ฐ€์งœ return address๋ฅผ ํ‘ธ์‹œํ•œ๋‹ค.

    -> entry ํ•จ์ˆ˜๋Š” ์ ˆ๋Œ€ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์ง€๋งŒ, ํ•ด๋‹น ์Šคํƒ ํ”„๋ ˆ์ž„์€ ๋‹ค๋ฅธ ์Šคํƒ ํ”„๋ ˆ์ž„๋“ค๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.

 

์Šคํƒ ํฌ์ธํ„ฐ๋Š” 0x4747ffb8๋กœ ์ดˆ๊ธฐํ™”๋œ๋‹ค.

Address Name Data Type
0x4747fffc argv[3][...] 'bar\0' char[4]
0x4747fff8 argv[2][...] 'foo\0' char[4]
0x4747fff5 argv[1][...] '-l\0' char[3]
0x4747ffed argv[0][...] '/bin/ls\0' char[8]
0x4747ffe8 word-align 0 uint8_t[]
0x4747ffe0 argv[4] 0 char *
0x4747ffd8 argv[3] 0x4747fffc char *
0x4747ffd0 argv[2] 0x4747fff8 char *
0x4747ffc8 argv[1] 0x4747fff5 char *
0x4747ffc0 argv[0] 0x4747ffed char *
0x4747ffb8 return address 0 void (*) ()

 

RDI: 4 | RSI: 0x4747ffc0

 

 

argument passing ์ธ์ž ์ „๋‹ฌ

์ฝ”๋“œ์˜ ํ๋ฆ„

init.c → int main(void) → run_actions(argv) → run_task(char **argv) → process_create_initd(task) → thread_create (file_name, PRI_DEFAULT, initd, fn_copy) → initd→process_exec → load, do_iret

 

1. process_create_initd()

๐Ÿ‘‰๐Ÿป command line์„ parsing ํ•ด์„œ file_name์„ ์ฐพ๋Š”๋‹ค.

 

- ์ธ์ž๋กœ ๋“ค์–ด์˜ค๋Š” file_name์ด ์‹คํ–‰ ์‹œ ์ž…๋ ฅ๋œ command line์ด๋‹ค.

- ์ด command line์„ parsingํ•ด์„œ ํŒŒ์ผ ์ด๋ฆ„์„ ์ฐพ๋Š”๋‹ค.

- parsingํ•ด์„œ ์–ป์–ด๋‚ธ ํŒŒ์ผ ์ด๋ฆ„์ด thread_create ํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.

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);	//file_name์˜ ๋ณต์‚ฌ๋ณธ
	if (fn_copy == NULL)
		return TID_ERROR;
	strlcpy (fn_copy, file_name, PGSIZE);

	//Argument Pasing
	//command_line์„ parsingํ•ด์„œ file_name ์ฐพ๋Š”๋‹ค.
	char *save_ptr;
	strtok_r (file_name, " ", &save_ptr);
	//~Argument Pasing
	
	/* 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;
}

 

2. process_exec()

 

๐Ÿ‘‰๐Ÿป ์ธ์ž๋กœ ๋“ค์–ด์˜ค๋Š” f_name์„ parsing ํ•˜๊ณ  user_stack์— ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์„ push ํ•œ๋‹ค.

 

- parsing ํ•œ ์ธ์ž๋“ค์„ ๋‹ด์„ parse ๋ฐฐ์—ด์˜ ๊ธธ์ด๋Š” 64๋กœ ์ง€์ •ํ•œ๋‹ค.

- strtok_r ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•ด parsing ํ•œ ๊ฒฐ๊ณผ๋ฅผ count์™€ parse์— ๋‹ด์•„๋‘๊ณ , ์•„๋ž˜์—์„œ ์ƒˆ๋กœ ์„ ์–ธํ•œ argument_stack ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ „๋‹ฌํ•œ๋‹ค.

- hex_dump() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•œ๋‹ค. (๋ฉ”๋ชจ๋ฆฌ์˜ ๋‚ด์šฉ์„ 16์ง„์ˆ˜ ํ˜•์‹์œผ๋กœ ์ถœ๋ ฅํ•ด ์ค˜์„œ ์Šคํƒ์— ์ €์žฅ๋œ ๊ฐ’๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.)

int
process_exec (void *f_name) {
	char *file_name = f_name;
	bool success;

	/* We cannot use the intr_frame in the thread structure.
	 * This is because when current thread rescheduled,
	 * it stores the execution information to the member. */
	struct intr_frame _if;
	_if.ds = _if.es = _if.ss = SEL_UDSEG;
	_if.cs = SEL_UCSEG;
	_if.eflags = FLAG_IF | FLAG_MBS;

	/* We first kill the current context */
	process_cleanup ();

	// Argument Passing ~
    	int argc = 0;
    	char *argv[64];		//parssingํ•œ ์ธ์ž๋ฅผ ๋‹ด์„ ๋ฐฐ์—ด
        char *token, *save_ptr;
    
	for (token = strtok_r(file_name, " ", &save_ptr); token != NULL; token = strtok_r(NULL, " ", &save_ptr))
    	{   
		argv[argc++] = token;
	}	
    	// ~ Argument Passing
		
	/* And then load the binary */
	success = load (file_name, &_if);

	// Argument Passing ~
    	argument_stack(argv, argc, &_if); // ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ argv์™€ rsp์˜ ๊ฐ’์„ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด ์ฃผ์†Œ ์ „๋‹ฌ
    
	hex_dump(_if.rsp, _if.rsp, USER_STACK - (uint64_t)_if.rsp, true); // user stack์„ 16์ง„์ˆ˜๋กœ ํ”„๋ฆฐํŠธ
    	// ~ Argument Passing

	/* If load failed, quit. */
	palloc_free_page (file_name);
	if (!success)
		return -1;

	/* Start switched process. */
	do_iret (&_if);
	NOT_REACHED ();
}

 

3. argument_stack()

 

๐Ÿ‘‰๐Ÿป process_exec() ํ•จ์ˆ˜์—์„œ parsing ํ•œ ํ”„๋กœ๊ทธ๋žจ ๋ฆ„๊ณผ ์ธ์ž๋ฅผ ์Šคํƒ์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กœ ์„ ์–ธํ•œ๋‹ค.

 

1. ํ”„๋กœ๊ทธ๋žจ ์ด๋ฆ„, ์ธ์ž ๋ฌธ์ž์—ด push

์Šคํƒ์€ ์•„๋ž˜ ๋ฐฉํ–ฅ์œผ๋กœ ์ปค์ง€๋ฏ€๋กœ ์Šคํƒ์— ์ธ์ž๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ์˜ค๋ฅธ์ชฝ-> ์™ผ์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ push

 

2. word-align(8์˜ ๋ฐฐ์ˆ˜)๋กœ ๋งž์ถฐ์ฃผ๊ธฐ

๊ฐ ๋ฌธ์ž์—ด์„ push ํ•˜๊ณ  ๋‚˜์„œ 8byte ๋‹จ์œ„๋กœ ์ •๋ ฌํ•˜๊ธฐ ์œ„ํ•ด padding์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

3. ์ธ์ž ๋ฌธ์ž์—ด ์ข…๋ฃŒ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” 0 push

์ •๋ ฌํ•˜๊ณ  ๋‚˜์„œ 0์„ push ํ•œ๋‹ค. (์ธ์ž ๋ฌธ์ž์—ด๋“ค์˜ ์ข…๋ฃŒ๋ฅผ ์˜๋ฏธํ•œ๋‹ค)

 

4. ๊ฐ ์ธ์ž ๋ฌธ์ž์—ด์˜ ์ฃผ์†Œ push

์ธ์ž ๋ฌธ์ž์—ด push ํ•˜๋ฉด์„œ argv์— ๋‹ด์•„๋‘” ๊ฐ ๋ฌธ์ž์—ด์˜ ์ฃผ์†Œ๋ฅผ push ํ•œ๋‹ค.

 

5. fake return address

๋‹ค์Œ ์ธ์ŠคํŠธ๋Ÿญ์…˜์˜ ์ฃผ์†Œ๋ฅผ push ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ง€๊ธˆ์€ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฑฐ๋ผ์„œ ๋ฐ˜ํ™˜ ์ฃผ์†Œ๊ฐ€ ์—†๋‹ค. ๊ทธ๋ž˜์„œ fake return address๋กœ 0์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

void argument_stack(char **argv, int argc, struct intr_frame *if_)
{
	char *arg_address[128];

	// ํ”„๋กœ๊ทธ๋žจ ์ด๋ฆ„, ์ธ์ž ๋ฌธ์ž์—ด push
	for(int i = argc - 1; i >= 0; i--)
	{
		int arg_i_len = strlen(argv[i]) +1;	//sential(\0) ํฌํ•จ
		if_->rsp -= arg_i_len;			//์ธ์ž ํฌ๊ธฐ๋งŒํผ ์Šคํƒ์„ ๋Š˜๋ ค์คŒ
		memcpy(if_->rsp, argv[i], arg_i_len);	//๋Š˜๋ ค์ค€ ๊ณต๊ฐ„์— ํ•ด๋‹น ์ธ์ž๋ฅผ ๋ณต์‚ฌ
		arg_address[i] = (char *)if_->rsp;	//arg_address์— ์œ„ ์ธ์ž๋ฅผ ๋ณต์‚ฌํ•ด์ค€ ์ฃผ์†Œ๊ฐ’์„ ์ €์žฅ
	}

	// word-align(8์˜ ๋ฐฐ์ˆ˜)๋กœ ๋งž์ถฐ์ฃผ๊ธฐ
	if(if_->rsp % 8 != 0)
	{	
		int padding = if_->rsp % 8;
		if_->rsp -= padding;
		memset(if_->rsp, 0, padding);
	}

	// ์ธ์ž ๋ฌธ์ž์—ด ์ข…๋ฃŒ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” 0 push
	if_->rsp -= 8; 	
	memset(if_->rsp, 0, 8);

	// ๊ฐ ์ธ์ž ๋ฌธ์ž์—ด์˜ ์ฃผ์†Œ push
	for(int i = argc-1; i >= 0; i--)
	{
		if_->rsp -= 8;
		memcpy(if_->rsp, &arg_address[i], 8);
	}

	// fake return address
	if_->rsp -= 8;
	memset(if_->rsp, 0, 8);

	//rdi ์—๋Š” ์ธ์ž์˜ ๊ฐœ์ˆ˜, rsi์—๋Š” argv ์ฒซ ์ธ์ž์˜ ์‹œ์ž‘ ์ฃผ์†Œ ์ €์žฅ
	if_->R.rdi = argc;
	if_->R.rsi = if_->rsp + 8;	//fake return address + 8
}

 

 

4. process_wait

argument passing ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋ ค๋ฉด ์ผ๋‹จ wait๋ฅผ ํ‰๋‚ด๋ผ๋„ ๋‚ด์•ผ ํ•ด์„œ ์ž„์‹œ๋ฐฉํŽธ์œผ๋กœ ๋ฐ˜๋ณต๋ฌธ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

10์–ต์œผ๋กœ ํ•˜๋ฉด ๋„ˆ๋ฌด ๋นจ๋ฆฌ ๋๋‚˜๋ฒ„๋ฆฌ๊ณ  100์–ต์œผ๋กœ ํ•˜๋ฉด time out์ด ๋– ์„œ ์—…๋‹ค์šด๊ฒŒ์ž„ํ•œ ๊ฒฐ๊ณผ 30์–ต์œผ๋กœ ํ•˜๋‹ˆ ์ž˜๋˜์—ˆ๋‹ค.

int
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 < 3000000000; i++);
	return -1;
}

 

Test ๊ฒฐ๊ณผ


User Memory Access

 

์ปค๋„์€ ์ข…์ข… ์‚ฌ์šฉ์ž ํ”„๋กœ๊ทธ๋žจ์ด ์ œ๊ณตํ•œ ํฌ์ธํ„ฐ๋ฅผ ํ†ตํ•ด ๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•ด์•ผ ํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ์ฃผ์†Œ ํฌ์ธํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ปค๋„์€ ์ด๋ฅผ ๋งค์šฐ ์‹ ์ค‘ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.

-> null ํฌ์ธํ„ฐ,

-> ๋งคํ•‘๋˜์ง€ ์•Š์€ ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ 

-> ์ปค๋„ ๊ฐ€์ƒ ์ฃผ์†Œ ๊ณต๊ฐ„(KERN_BASE ์ด์ƒ)

 

check_address

user ํ”„๋กœ๊ทธ๋žจ์ด ์ž˜๋ชป๋œ ํฌ์ธํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋ฉด exit์„ ํ˜ธ์ถœํ•œ๋‹ค.

void check_address(void *file_addr)
{
	struct thread *t = thread_current();
	if(file_addr == "\0" || file_addr == NULL || !is_user_vaddr(file_addr) || pml4_get_page(t->pml4, file_addr) == NULL)
		exit(-1);
}

 

 

File System

System Calls ์ค‘์—๋Š” File System๊ณผ ๊ด€๋ จ๋œ ํ˜ธ์ถœ์ด ๋งŽ์€๋ฐ, Pintos์—์„œ ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” File System์„ ์ œ๊ณตํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— filesys.h ๋˜๋Š” file.h์—์„œ ์ ์ ˆํ•œ ํ•จ์ˆ˜๋ฅผ ์ฐพ์•„์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

File System ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ์—๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค๋งŒ ์‹คํ–‰๋˜๋„๋ก ๋™๊ธฐํ™”๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

file ๊ด€๋ จ๋œ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— syscall.c์—์„œ ์ƒˆ๋กœ ๋งŒ๋“  filesys_lock์„ acquireํ•œ ํ›„์— ์ ‘๊ทผํ•˜๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.

์ดํ›„ ํ”„๋กœ์ ํŠธ์—์„œ ๋™๊ธฐํ™”๋กœ ์ธํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ lock์„ ๊ฑธ์–ด์ค˜์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์— ์ž˜ ๊ฑธ์–ด์ค˜์•ผ ํ•œ๋‹ค..

 

syscall.h์—์„œ filesys_lock์„ ์ „์—ญ์œผ๋กœ ์ƒˆ๋กœ ์„ ์–ธํ•˜๊ณ  syscall_init์—์„œ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

/* userprog/syscall.h */

#ifndef USERPROG_SYSCALL_H
#define USERPROG_SYSCALL_H

void syscall_init (void);
struct lock filesys_lock;

#endif /* userprog/syscall.h */
/* userprog/syscall.c */

void syscall_init(void)
{
...

    lock_init(&filesys_lock);
}

 

System Calls ๊ตฌํ˜„

์œ ์ € ํ”„๋กœ๊ทธ๋žจ์ด ์‹œ์Šคํ…œ ์ฝœ์„ ๋ณด๋‚ด๋ฉด ์‹œ์Šคํ…œ ์ฝœ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹œ์Šคํ…œ ์ฝœ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ›์•„์˜ค๊ณ , ์–ด๋–ค ์‹œ์Šคํ…œ ์ฝœ ์ธ์ž๋“ค์„ ๋ฐ›์•„์˜ค๊ณ , ๊ทธ์— ์•Œ๋งž์€ ์•ก์…˜์„ ์ทจํ•˜๋„๋ก ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

 

์‹œ์Šคํ…œ ์ฝœ ํ•ธ๋“ค๋Ÿฌ์ธ syscall_handler()๊ฐ€ ์ œ์–ด๊ถŒ์„ ์–ป์œผ๋ฉด, ์‹œ์Šคํ…œ ์ฝœ ๋ฒˆํ˜ธ๊ฐ€ %rax์— ์žˆ์œผ๋ฉฐ, ์ธ์ž๊ฐ’๋“ค์€ ์ˆœ์„œ๋Œ€๋กœ ์ „๋‹ฌ๋œ๋‹ค. (%rdi, %rsi, %rdx, %r10, %r8 and %r9)

ํ˜ธ์ถœ์ž์˜ ๋ ˆ์ง€์Šคํ„ฐ๋Š” struct intr_frame์œผ๋กœ ์ „๋‹ฌ๋˜์–ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.(struct infr_frame์€ ์ปค๋„ ์Šคํƒ์— ์žˆ๋‹ค.)

 

์œ ์ € ํ”„๋กœ๊ทธ๋žจ์˜ ํ”„๋กœํ† ํƒ€์ž…์€ include/lib/user/syscall.h ๋‹ด๊ฒจ ์žˆ๋‹ค. (์ด๊ณณ์— ํ—ค๋” ํŒŒ์ผ๊ณผ ๋‹ค๋ฅธ include/lib/user์— ์žˆ๋Š” ํŒŒ์ผ๋“ค์€ ์œ ์ € ํ”„๋กœ๊ทธ๋žจ์—์„œ๋งŒ ์‚ฌ์šฉ๋œ๋‹ค.) 

 

-> user/syscall.c ์—์„œ syscall_handler()๋ฅผ ๊ตฌํ˜„ํ•ด์„œ ์‹œ์Šคํ…œ ์ฝœ ๋ฒˆํ˜ธ, ์ธ์ž๋“ค์„ ๋ฐ›์•„์™€์„œ ๊ทธ์— ์•Œ๋งž์€ ์•ก์…˜์„ ์ทจํ•˜๋„๋ก ์‹œ์Šคํ…œ ์ฝœ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

 

void
syscall_handler (struct intr_frame *f UNUSED) 
{
	frame = f;
	int sys_num = f->R.rax;	 //์‹œ์Šคํ…œ ์ฝœ ๋ฒˆํ˜ธ
	switch(sys_num)
	{
		case SYS_HALT:
			halt();
			break;
		case SYS_EXIT:	
			exit(f->R.rdi);
			break;
		case SYS_FORK:
			f->R.rax = fork(f->R.rdi);
			break;
		case SYS_EXEC:
			f->R.rax = exec(f->R.rdi);
			break;
		case SYS_WAIT:
			f->R.rax = wait(f->R.rdi);
			break;
		case SYS_CREATE:
			f->R.rax = create(f->R.rdi, f->R.rsi);
			break;
		case SYS_OPEN:
			f->R.rax = open(f->R.rdi);
			break;
		case SYS_FILESIZE:
			f->R.rax = filesize(f->R.rdi);
			break;
		case SYS_READ:
			f->R.rax = read(f->R.rdi, f->R.rsi, f->R.rdx);
			break;
		case SYS_WRITE:
			f->R.rax = write(f->R.rdi, f->R.rsi, f->R.rdx);
			break;	
		case SYS_SEEK:
			seek(f->R.rdi, f->R.rsi);
			break;	
		case SYS_TELL:
			f->R.rax = tell(f->R.rdi);
			break;	
		case SYS_CLOSE:
			close(f->R.rdi);
			break;	

		default:
			break;
	}
	//printf ("system call!\n");
	//thread_exit ();
}

 

1. halt

src/include/threads/init.h์— ์„ ์–ธ๋œ power_off()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ ํ•€ํ† ์Šค๋ฅผ ์ข…๋ฃŒํ•œ๋‹ค.

-> #include "threads/init.h" ์ถ”๊ฐ€ํ•ด์•ผ ๋จ

๊ต์ฐฉ ์ƒํƒœ ๋“ฑ์— ๋Œ€ํ•œ ์ผ๋ถ€ ์ •๋ณด๋ฅผ ์žƒ๊ฒŒ ๋˜๋ฏ€๋กœ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

void halt (void) 
{	
    power_off();
}

 

2. exit

 

ํ˜„์žฌ ๋™์ž‘ ์ค‘์ธ ์œ ์ € ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒ์‹œํ‚ค๊ณ , ์ปค๋„๋กœ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋งŒ์•ฝ ํ”„๋กœ์„ธ์Šค์˜ ๋ถ€๋ชจ๊ฐ€ wait ์ƒํƒœ๋ผ๋ฉด , wait์— ๋“ค์–ด๊ฐˆ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ด๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์ƒํƒœ๊ฐ€ 0์ด๋ฉด ์„ฑ๊ณต, 0์ด ์•„๋‹Œ ์ˆ˜๋Š” ์—๋Ÿฌ๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

void exit (int status)
{	
	struct thread *cur = thread_current();
	cur->exit_status = status;
	printf("%s: exit(%d)\n", cur->name, status);
	thread_exit();
}

 

 

3. create

file์„ ์ด๋ฆ„์œผ๋กœ ํ•˜๊ณ  ํฌ๊ธฐ๊ฐ€ inital_size์ธ ์ƒˆ๋กœ์šด ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

์„ฑ๊ณต์ ์œผ๋กœ ํŒŒ์ผ ์ƒ์„ฑํ•˜๋ฉด true, ์‹คํŒจ false ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

์ฃผ์–ด์ง„ ํฌ์ธํ„ฐ ์œ ํšจํ•œ ์ฃผ์†Œ๊ฐ’์„ ๊ฐ€์ง€๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด  check_address() ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜์˜€๋‹ค.

๋งŒ์ผ ์œ ํšจํ•œ ์ฃผ์†Œ๊ฐ’์ด๋ฉด filesys_create()๋กœ ํŒŒ์ผ ์ƒ์„ฑํ•˜๋„๋ก ํ•˜์˜€๋‹ค.

bool create (const char *file, unsigned initial_size)
{	
	check_address(file);
	return filesys_create (file, initial_size);
}

 

4. remove

file์ด๋ผ๋Š” ํŒŒ์ผ์„ ์‚ญ์ œํ•œ๋‹ค.

bool remove (const char *file)
{
	check_address(file);
	return filesys_remove(file);
}

 

 

5.  close()

- ์—ด๋ฆฐ ํŒŒ์ผ์„ ๋‹ซ๋Š”๋‹ค.

- ์‹คํ–‰์„ ๋งˆ์น˜๊ฑฐ๋‚˜ ์ข…๋ฃŒ๋˜๋Š” ํ”„๋กœ์„ธ์Šค๋Š” ์•”๋ฌต์ ์œผ๋กœ ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์—ด๋ฆฐ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋“ค์„ ๋‹ซ๋Š”๋‹ค.

 

์—ด๋ฆฐ ํŒŒ์ผ์„ ๋‹ซ์œผ๋ ค๋ฉด ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ์— ํ•ด๋‹น ํŒŒ์ผ์ด ์žˆ๋Š”์ง€ ํ™•์ธ ํ›„ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ํ…Œ์ด๋ธ”์—์„œ ์ œ๊ฑฐํ•˜๊ณ  ํ•ด๋‹น ํŒŒ์ผ์„ file_close() ํ•˜์—ฌ ๋‹ซ์•„์ฃผ๊ณ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•œ๋‹ค.

 

void close (int fd)
{
	struct file_descrpitor *curr_fd = find_file_descriptor(fd);
   	 //ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์ฐพ์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ ํ•จ์ˆ˜ ์ข…๋ฃŒ
	if(curr_fd == NULL) return NULL;
    	//ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๊ฐ€ ์—ฐ๊ฒฐ๋œ ๋ฆฌ์ŠคํŠธ์—์„œ ํ•ด๋‹น ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.
	list_remove(&curr_fd->fd_elem);
    	//ํŒŒ์ผ ๋‹ซ๋Š”๋‹ค.
	file_close(curr_fd->file);
    	//ํŒŒ์ผ๋””์Šคํฌ๋ฆฝํ„ฐ ํ•ด์ œ
	free(curr_fd);
}

 

๊ทธ๋ฆฌ๊ณ  ๊ผญ ํ—ค๋”ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค!!!! (ํ—ค๋”ํŒŒ์ผ ์ถ”๊ฐ€ ์•ˆํ•ด์„œ ๊ณ„์† ์—๋Ÿฌ๋‚จ)

#include "filesys/file.h"
#include "filesys/filesys.h"

 

5-2 . find_file_descriptor

ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋ชฉ๋ก์—์„œ ์ฃผ์–ด์ง„ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋ฒˆํ˜ธ(fd)๋ฅผ ๊ฐ€์ง„ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์ฐพ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

 

ํ˜„์žฌ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ์˜ ๋ฒˆํ˜ธ์™€ ์ฃผ์–ด์ง„ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์ผ์น˜ํ•˜๋‹ค๋ฉด ํ•ด๋‹น ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ์˜ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ชป ์ฐพ์•˜๋‹ค๋ฉด NULL์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ํ•จ์ˆ˜๋ฅผ ์ข…๋ฃŒํ•œ๋‹ค. 

struct file_descrpitor *find_file_descriptor(int fd)
{
	struct list *fd_list = &thread_current()->fd_list;
	if(list_empty(fd_list)) return NULL;

	struct file_descrpitor *file_descriptor;
	struct list_elem *cur_fd_elem = list_begin(fd_list);

	while(cur_fd_elem != list_end(&fd_list))
	{
		file_descriptor = list_entry(cur_fd_elem, struct file_descrpitor, fd_elem);

		if(file_descriptor->fd_num == fd)
		{
			return file_descriptor;	
		}			
		file_descriptor = list_next(cur_fd_elem);
	}
	return NULL;
}

๐Ÿฅฒ ํ—ค๋งธ๋˜ ์ 

 

close ๋ถ€๋ถ„์—์„œ ๋งŽ์€ ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ๋‹ค.

์™œ๋ƒํ•˜๋ฉด ์ฒ˜์Œ์— find_file_descriptor() ํ•จ์ˆ˜ ์•ˆ์˜ ์ฝ”๋“œ๋“ค์„ close ์•ˆ์—์„œ ์ž‘์„ฑํ•ด์ฃผ๋ฉด์„œ ๋งŒ์•ฝ ํ˜„์žฌ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋ฒˆํ˜ธ๊ฐ€ ์ฃผ์–ด์ง„ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋ฒˆํ˜ธ์ธ์ง€ ํ™•์ธํ•˜๋Š” ์กฐ๊ฑด๋ฌธ ์•ˆ์—์„œ ์‚ญ์ œํ•˜๊ณ  ํŒŒ์ผ ๋‹ซ๋Š” ๋ถ€๋ถ„์œผ๋กœ ๊ตฌํ˜„ ํ–ˆ๋Š”๋ฐ ์ž๊พธ ์•ˆ๋๋‹ค. ์ž๊พธ ์œ ์ € ํ”„๋กœ๊ทธ๋žจ์ด ๋๋‚˜์ง€ ์•Š๋Š” ์—๋Ÿฌ๊ฐ€ ์ƒ๊ฒผ๋Š”๋ฐ ๊ทธ ์ด์œ ๊ฐ€ break๋ฌธ์„ ์•ˆ์ ์–ด์ค˜์„œ....์˜€๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  open์„ ํ•˜๋ฉด์„œ ํ˜„์žฌ ํŒŒ์ผ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ์— ๋™์  ํ• ๋‹น์„ ํ•ด์คฌ๋Š”๋ฐ close ๋ถ€๋ถ„์—์„œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ํ•ด์ œํ•˜๋Š” ๋ถ€๋ถ„์„ ์•ˆ์ ์–ด๋†”์„œ ์ถ”๊ฐ€ํ•ด์คฌ๋‹ค.


 

6. read

- fd๋กœ๋ถ€ํ„ฐ ์—ด๋ฆฐ ํŒŒ์ผ์˜ ํฌ๊ธฐ๋ฅผ ์ฝ๊ณ  ๋ฒ„ํผ์— ๋‹ด๋Š”๋‹ค. ์‹ค์ œ๋กœ ์ฝ์€ ํŒŒ์ผ์˜ ํฌ๊ธฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ ์‹คํŒจ์‹œ -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

- fd๊ฐ€ 0์ด๋ฉด input_getc() ๋ฅผ ์ด์šฉํ•ด์„œ ํ‚ค๋ณด๋“œ ์ž…๋ ฅ์„ ์ฝ์–ด์˜จ๋‹ค.

 

์ฃผ์–ด์ง„ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋ฒˆํ˜ธ์™€ ์ผ์น˜ํ•˜๋Š” ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์ฐพ์•„ ๊ทธ ํŒŒ์ผ์„ ์ฝ์–ด๋“ค์ด๋ฉด๋œ๋‹ค.

int read (int fd, void *buffer, unsigned length)
{
	check_buffer(buffer);
	
	int byte = 0;
	char *ptr = (char *)buffer;
	if(fd == 0)
	{
		for(int i = 0; i < length; i++)
		{
			*ptr++ = input_getc();
			byte ++;
		}
	}
	else
	{
		lock_acquire(&filesys_lock);
		struct file_descriptor *curr_fd = find_file_descriptor(fd);
		if(curr_fd == NULL) return -1;
		byte = file_read(curr_fd->file, buffer, length);
		lock_release(&filesys_lock);
	}
	return byte;
}

 

6-2. filesize

 

์—ด๋ ค์žˆ๋Š” ํŒŒ์ผ์˜ ํฌ๊ธฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.(byte ๋‹จ์œ„๋กœ)

int filesize (int fd)
{
	struct file_descriptor *curr_fd = find_file_descriptor(fd);
	if(curr_fd == NULL) return -1;
	return file_length(curr_fd->file);
}

 

7. write

fd๊ฐ€ 1(ํ‘œ์ค€ ์ถœ๋ ฅ)์ด๋ฉด ์ฝ˜์†”์— ์ถœ๋ ฅ์„ ํ•ด์คฌ๋‹ค๋ฉด ์ด์ œ๋Š”์—ด๋ฆฐ ํŒŒ์ผ fd๋กœ ๋ฒ„ํผ์— ๋‹ด๊ธด size๋งŒํผ ์ถœ๋ ฅํ•ด์•ผ ๋œ๋‹ค.

read์™€ ์ƒ๋‹นํžˆ ์œ ์‚ฌํ•ด์„œ file_write() ํ•จ์ˆ˜๋กœ ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

int write (int fd, const void *buffer, unsigned length)
{
	check_buffer(buffer);
	int byte = 0;
	if(fd == 1)
	{
		putbuf(buffer, length);
		byte = length;
	}else
	{
		struct file_descriptor *curr_fd = find_file_descriptor(fd);
		if(curr_fd == NULL) return NULL;
		lock_acquire(&filesys_lock);
		byte = file_write(curr_fd->file, buffer, length);
		lock_release(&filesys_lock);

	}
	return byte;
}

 

8. open()

file ์„ ์—ด๊ธฐ ์œ„ํ•ด์„œ๋Š” ์‹œ์Šคํ…œ ์ฝœ open() ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

open์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” 

1. file์ด ์œ ํšจํ•œ ์ฃผ์†Œ๊ฐ’์ธ์ง€๋ฅผ ๊ฒ€์ฆํ•ด์•ผ ํ•œ๋‹ค.

2. filesys_open๋ฅผ ํ˜ธ์ถœํ•ด์„œ ํŒŒ์ผ์„ openํ•œ๋‹ค.

3. process_add_file ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์„œ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ํ…Œ์ด๋ธ”์— ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๊ณ  fd๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

4. ํŒŒ์ผ๋””์Šคํฌ๋ฆฝํ„ฐ ํ…Œ์ด๋ธ”์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ(fd == -1)์ธ ๊ฒฝ์šฐ์—” ํŒŒ์ผ์„ ๋‹ซ๊ณ  -1์„ ๋ฆฌํ„ดํ•œ๋‹ค.

5. ์˜คํ”ˆํ•œ ํŒŒ์ผ์˜ fd๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

int open (const char *file)
{
	check_address(file);
	struct file *file_open = filesys_open(file);
	if(file_open == NULL)
		return -1;

	int	fd = process_add_file(file_open);
	if(fd == -1)
		file_close(file_open);

	return fd;
}

 

8-2 process_add_file()

ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ ํŒŒ์ผ๋””์Šคํฌ๋ฆฝํ„ฐ์— ํ˜„์žฌ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

ํ•ด๋‹น ํŒŒ์ผ์˜ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

int process_add_file(struct file *file)
{
	struct thread *curr = thread_current();
	struct file_descriptor *cur_fd = malloc(sizeof(struct file_descriptor));
	struct list *fd_list = &thread_current()->fd_list;
	
	cur_fd->file = file;
	cur_fd->fd_num = (curr->last_create_fd)++;	
	
	list_push_back(fd_list, &cur_fd->fd_elem);

	return cur_fd->fd_num; 
}

 

 

 

728x90

'Krafton jungle > PintOS' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

PintOS Project3 : Memory Management  (0) 2024.03.28
PintOS Project1 : Threads - Alarm Clock , Priority Scheduling  (1) 2024.03.09