create() μμ€ν
μ½μ νΈμΆνμ λ,NULL, λΉμ μ ν¬μΈν°, νμΌ μ΄λ¦ κΈΈμ΄ μ ν λ±μ λ€μν μν©μ λν μμΈ μ²λ¦¬λ₯Ό ν¬ν¨ν΄μΌ ν©λλ€.userprog/syscall.cuserprog/syscall.h#include "userprog/syscall.h" // μμ€ν
μ½ μΈν°νμ΄μ€ μ μ
#include <stdio.h> // printf μ¬μ©
#include <syscall-nr.h> // μμ€ν
μ½ λ²νΈ μ μ
#include "threads/interrupt.h" // μΈν°λ½νΈ λ±λ‘μ©
#include "threads/thread.h" // thread_current λ±
#include "threads/loader.h" // μ¬μ©μ νλ‘κ·Έλ¨ λ‘λ© κ΄λ ¨
#include "userprog/gdt.h" // μΈκ·Έλ¨ΌνΈ μ 보
#include "threads/flags.h" // νλκ·Έ λΉνΈ
#include "intrinsic.h" // write_msr λ±
#include "devices/input.h" // input_getc() μ¬μ©μ μν΄
#include "threads/init.h" // power_off() μ¬μ©μ μν΄
#include "threads/synch.h" // lock μ¬μ©μ μν΄
#include "filesys/filesys.h" // filesys_create() μ¬μ©μ μν΄
#include "threads/vaddr.h" // is_user_vaddr() μ¬μ©μ μν΄
#include "threads/mmu.h" // pml4_get_page() μ¬μ©μ μν΄
struct lock file_lock; // νμΌ μμ€ν
λκΈ°νλ₯Ό μν μ μ λ½
void syscall_entry (void); // syscall μ§μ
ν¨μ
void syscall_handler (struct intr_frame *); // syscall νΈλ€λ¬
#define MSR_STAR 0xc0000081 // syscall μΈκ·Έλ¨ΌνΈ μ§μ MSR
#define MSR_LSTAR 0xc0000082 // syscall νΈλ€λ¬ μ£Όμ MSR
#define MSR_SYSCALL_MASK 0xc0000084 // syscall μ§μ
μ λ§μ€νΉν νλκ·Έ
void syscall_init (void) {
// μ¬μ©μ/컀λ λͺ¨λ μ ν μ μΈκ·Έλ¨ΌνΈ μ€μ
write_msr(MSR_STAR, ((uint64_t)SEL_UCSEG - 0x10) << 48 |
((uint64_t)SEL_KCSEG) << 32);
// syscall μ§μ
μ§μ μ€μ
write_msr(MSR_LSTAR, (uint64_t) syscall_entry);
// μΈν°λ½νΈ λ§μ€νΉ μ€μ (IF, TF, DF λ±)
write_msr(MSR_SYSCALL_MASK,
FLAG_IF | FLAG_TF | FLAG_DF | FLAG_IOPL | FLAG_AC | FLAG_NT);
// νμΌ μμ€ν
λ½ μ΄κΈ°ν
lock_init(&file_lock);
}
// μμ€ν
μ½ νΈλ€λ¬
void syscall_handler(struct intr_frame *f) {
uint64_t syscall_num = f->R.rax; // syscall λ²νΈλ raxμ μ μ₯λ¨
switch (syscall_num) {
case SYS_HALT:
sys_halt(); // μμ€ν
μ’
λ£
break;
case SYS_EXIT:
sys_exit((int)f->R.rdi); // νμ¬ νλ‘μΈμ€ μ’
λ£
break;
case SYS_WRITE:
f->R.rax = sys_write((int)f->R.rdi, (const void *)f->R.rsi, (unsigned)f->R.rdx);
break;
case SYS_READ:
f->R.rax = sys_read((int)f->R.rdi, (void *)f->R.rsi, (unsigned)f->R.rdx);
break;
case SYS_CREATE:
f->R.rax = sys_create((const char *)f->R.rdi, (unsigned)f->R.rsi);
break;
default:
printf("Unknown system call: %lld\n", syscall_num);
sys_exit(-1); // μ μλμ§ μμ μμ€ν
μ½μ΄λ©΄ κ°μ μ’
λ£
break;
}
}
// μμ€ν
μ½: create
bool sys_create(const char *file, unsigned initial_size) {
// fileμ΄ NULLμ΄κ±°λ μ μ μμμ΄ μλκ±°λ, λ§€νλμ§ μμ κ°μ μ£ΌμμΌ κ²½μ° μ’
λ£
if (file == NULL || !is_user_vaddr(file) || pml4_get_page(thread_current()->pml4, file) == NULL) {
sys_exit(-1);
}
lock_acquire(&file_lock); // λκΈ°νλ₯Ό μν΄ λ½ νλ
bool success = filesys_create(file, initial_size); // μ€μ νμΌ μμ±
lock_release(&file_lock); // λ½ ν΄μ
return success; // μ±κ³΅ μ¬λΆ λ°ν
}
#ifndef USERPROG_SYSCALL_H
#define USERPROG_SYSCALL_H
#include <stdbool.h> // bool νμ
μ¬μ©μ μν ν€λ
void syscall_init(void); // syscall μ€μ ν¨μ
void sys_halt(void); // μμ€ν
μ’
λ£
void sys_exit(int status); // νλ‘μΈμ€ μ’
λ£
int sys_write(int fd, const void *buffer, unsigned size); // μΆλ ₯
int sys_read(int fd, void *buffer, unsigned size); // μ
λ ₯
bool sys_create(const char *file, unsigned initial_size); // νμΌ μμ±
#endif /* userprog/syscall.h */
ν΄λΉ ꡬνμΌλ‘ λ€μμ ν μ€νΈλ₯Ό λͺ¨λ ν΅κ³Όνμμ΅λλ€:
create-normalcreate-emptycreate-nullcreate-bad-ptrcreate-longcreate-existscreate-boundκ° ν μ€νΈλ λ€μκ³Ό κ°μ μΌμ΄μ€λ₯Ό κ²μ¦ν©λλ€:
| ν μ€νΈ μ΄λ¦ | κ²μ¦ λ΄μ© |
|---|---|
| create-normal | μΌλ° νμΌ μμ±μ΄ κ°λ₯νκ° |
| create-empty | ν¬κΈ° 0μΈ νμΌμ λ§λ€ μ μλκ° |
| create-null | file μΈμκ° NULLμΌ λ μμΈμ²λ¦¬ νλκ° |
| create-bad-ptr | μλͺ»λ μ£ΌμμΌ λ νλ‘μΈμ€λ₯Ό μ’ λ£νλκ° |
| create-long | νμΌ μ΄λ¦μ΄ λ§€μ° κΈΈμ΄λ λμνλκ° |
| create-exists | μ΄λ―Έ μ‘΄μ¬νλ νμΌμ΄ μμΌλ©΄ μ€ν¨νλκ° |
| create-bound | κ²½κ³ κΈΈμ΄μ μ΄λ¦λ νμ©νλκ° |
μ΄λ² create() μμ€ν
μ½ κ΅¬νμμ μ€μ λ‘ μ§μ μμ ν νμΌμ λ€μ λ κ°λΏμ
λλ€:
| νμΌ κ²½λ‘ | μ€λͺ |
|---|---|
userprog/syscall.c | μμ€ν
μ½ λ³Έμ²΄ ꡬν (sys_create() ν¨μ μ μ ν¬ν¨) |
userprog/syscall.h | μμ€ν
μ½ ν¨μ μ μΈ λ° #include <stdbool.h> μΆκ° |
λν, λ€μ νμΌλ€μ μμ νμ§ μμμ§λ§ syscall.c λ΄λΆμμ νμν κΈ°λ₯μ μ¬μ©νκΈ° μν΄ includeλ§ νμμ΅λλ€:
| νμΌ κ²½λ‘ | μ¬μ© λͺ©μ |
|---|---|
filesys/filesys.h | filesys_create() ν¨μ νΈμΆμ μν΄ |
threads/synch.h | λ½ μλ£κ΅¬μ‘° λ° lock_acquire, lock_release μ¬μ©μ μν΄ |
threads/vaddr.h | is_user_vaddr()λ‘ μ¬μ©μ μ£ΌμμΈμ§ νμΈνκΈ° μν΄ |
threads/mmu.h | pml4_get_page()λ‘ μ£Όμ λ§€ν μ¬λΆλ₯Ό νμΈνκΈ° μν΄ |
threads/init.h | power_off() νΈμΆμ μν΄ |
devices/input.h | (νμ¬λ μ¬μ©νμ§ μμμΌλ, read() ꡬν μ νμ μμ ) |
μμ½νλ©΄, μ§μ μμ ν 건 syscall.c, syscall.h λ¨ λ νμΌμ΄λ©°,
λλ¨Έμ§λ μ΄λ―Έ PintOSμ μ μλ κΈ°λ₯λ€μ λΆλ¬μμ νμ©νλ λ°©μμΌλ‘ κ°λ°μ μ§ννμμ΅λλ€.
μ΄λ μ΄ν λ€λ₯Έ μμ€ν
μ½μ ꡬνν λλ λμΌν ν¨ν΄μΌλ‘ λ°λ³΅λ κ²μ
λλ€.