๐ป๊ตฌํ ์์ ๋ฆฌ์คํธ๐ผ
1. Memory Management
2. Anonymous Page
3. Stack Growth
4. Memory Mapped Files
5. Swap in/out
์ต๋ช ํ์ด์ง : ํ์ผ(๋์คํฌ) ๊ธฐ๋ฐ์ด ์๋ ์ด๋ค ํ๋์ ์ด๋ฏธ์ง ๊ฐ์ non-disk ํ์ด์ง๋ฅผ ์๋ฏธํ๋ค. ์ปค๋๋ก๋ถํฐ ํ ๋น๋ ํ์ด์ง๋ก์, ์ต๋ช ๋งตํ์ ๋ฐฑ์ ํ์ผ์ด๋ ์ฅ์น๊ฐ ์๋ค. ์ฝ๋ ์ธ๊ทธ๋จผํธ์ ๋ฐ์ดํฐ ์ธ๊ทธ๋จผํธ๋ ํ์ผ ๊ธฐ๋ฐ ํ์ด์ง์์ load ๋๋ ๋ฐ๋ฉด, ์ต๋ช ํ์ด์ง๋ ์คํ๊ณผ ํ์ ํ ๋นํด์ค๋ค. ์ต๋ช ํ์ด์ง๋ฅผ ๋ํ๋ด๋ ๊ตฌ์กฐ์ฒด์ธ anon_page๋ anon.h์ ์ ์ธ๋์ด ์๋ค. ๋ํ struct page๋ฅผ ๋ณด๋ฉด, ํ์ด์ง๊ฐ ์ต๋ช ํ์ด์ง์ธ ๊ฒฝ์ฐ๋ฅผ ์ํด struct anon_page anon์ ๋ฉค๋ฒ๋ก ํฌํจํ๊ณ ์๋ค.
์ง์ฐ ๋ก๋ฉ์ ํ์ฉํ ํ์ด์ง ์ด๊ธฐํ : ์ง์ฐ ๋ก๋ฉ์ ํ์ ์์ ๊น์ง ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ฉ์ ์ง์ฐ์ํค๋ ๋ฐฉ๋ฒ์ด๋ค. ํ์ด์ง๊ฐ ํ ๋น๋์๋ค๋ ๊ฒ์ ๋์๋๋ ํ์ด์ง ๊ตฌ์กฐ์ฒด๋ ์์ง๋ง ์ฐ๊ฒฐ๋ ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ ํ๋ ์์ด ์์ง ์๊ณ ํ์ด์ง์ ๋ํ ์ค์ ๋ด์ฉ๋ค์ด ์์ง ๋ก๋๋์ง ์์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. ํ์ด์ง ํดํธ๋ฅผ ํตํด ์ค์ ๋ก ๋ก๋๊ฐ ํ์ํ๋ค๋ ์๊ทธ๋์ ๋ฐ์ ๋ ๋ด์ฉ๋ค์ด ๋ก๋ ๋ ๊ฒ์ด๋ค.
ํ์ด์ง๋ 3๊ฐ์ง ํ์
์ด ์๊ณ , ๊ฐ ํ์ด์ง ํ์
๋ณ๋ก ์ด๊ธฐํ ๋ฃจํด์ด ๋ค๋ฅด๋ค. high-level ๊ด์ ์์ ํ์ด์ง ์ด๊ธฐํ ๊ณผ์ ์ ๋ณด์.
ํ์ด์ง๋ ์ด๊ธฐํ->ํ์ด์งํดํธ->์ง์ฐ๋ก๋ฉ->์ค์์ธ->์ค์์์->โฆ->์ญ์ ๋ผ๋ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ๋๋ค. ํ์ด์ง ํ์ ๋ณ๋ก ์ด๊ธฐํ ๋ฐฉ๋ฒ์ด ๋ค๋ฅธ ๊ฒ์ฒ๋ผ, ์๋ช ์ฃผ๊ธฐ์ ๊ฐ ์ํ ๋ณ์ด๋ง๋ค ํ์ด์ง ํ์ ๋ณ๋ก ๋ค๋ฅธ ํ๋ก์์ ๊ฐ ์๊ตฌ๋๋ค. ์ด๋ฒ ํ๋ก์ ํธ์์ ๊ฐ ํ์ด์ง ํ์ ๋ณ๋ก ๋ค๋ฅธ ์ํ ๋ณ์ด์ ๊ณผ์ ๋ค์ ๊ตฌํํด์ผ ํ๋ค.
์ง์ฐ ๋ก๋ฉ์์๋ ํ๋ก์ธ์ค๊ฐ ์คํ์ ์์ํ ๋, ๋น์ฅ ํ์ํ ๋ฉ๋ชจ๋ฆฌ ํํธ๋ง ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋๋ค. ์ง์ฐ ๋ก๋ฉ์ ๋์์ ๋ชจ๋ ๋ฐ์ด๋๋ฆฌ ์ด๋ฏธ์ง๋ค์ ๋ก๋ํ๋ ์ฆ์ ๋ก๋ฉ๋ณด๋ค ์๋์ ์ผ๋ก ์ค๋ฒํค๋๋ฅผ ์ค์ผ ์ ์๋ค.
์ง์ฐ ๋ก๋ฉ์ ์ง์ํ๊ธฐ ์ํ VM_UNINIT๋ผ๊ณ ๋ถ๋ฆฌ๋ ํ์ด์ง ํ์
์ด ์๋ค. ๋ชจ๋ ํ์ด์ง๋ค์ ์ด๊ธฐ์ VM_UNINIT ํ์
์ ํ์ด์ง๋ก ์์ฑ๋๋ค.
enum vm_type {
/* page not initialized */
VM_UNINIT = 0,
/* page not related to the file, aka anonymous page */
VM_ANON = 1,
/* page that realated to the file */
VM_FILE = 2,
/* page that hold the page cache, for project 4 */
VM_PAGE_CACHE = 3,
/* Bit flags to store state */
/* Auxillary bit flag marker for store information. You can add more
* markers, until the value is fit in the int. */
VM_MARKER_0 = (1 << 3),
VM_MARKER_1 = (1 << 4),
/* DO NOT EXCEED THIS VALUE. */
VM_MARKER_END = (1 << 31),
};
uninit_page ๊ตฌ์กฐ์ฒด๋ก ์ด๊ธฐํ๋์ง ์์ ํ์ด์ง๋ค์ ์ํ ํ์ด์ง ๊ตฌ์กฐ์ฒด๋ฅผ ์ ๊ณตํ๋ค. ์ด๊ธฐํ๋์ง ์์ ํ์ด์ง๋ฅผ ์์ฑ, ์ด๊ธฐํ, ์ญ์ ํ๋ ํจ์๋ค์ include/vm/uninit.c์์ ์ฐพ์ ์ ์๋ค.
ํ์ด์ง ํดํธ๊ฐ ์ผ์ด๋๋ฉด, ํ์ด์ง ํดํธ ํธ๋ค๋ฌ๋ vm_try_handle_fault ํจ์์๊ฒ ์ ์ด๊ถ์ ๋๊ธด๋ค. ์ด ํจ์๋ ์ ํจํ ํ์ด์ง ํดํธ์ธ์ง๋ฅผ ์ฐ์ ๊ฒ์ฌํ๋ค. ์ด ํ์ด์ง ํดํธ๊ฐ ์ ํจํ์ง ์์ ํ์ด์ง์ ์ ๊ทผํ ํดํธ๋ผ๋ฉด ์ ํจํ ํ์ด์ง ํดํธ์ผ ๊ฒ์ด๋ค. ๊ทธ๊ฒ ์๋ bogus ํดํธ๋ผ๋ฉด ํ์ด์ง์์ ์ฝํ
์ธ ๋ฅผ ๋ก๋ํ๊ณ ์ ์ ํ๋ก๊ทธ๋จ์๊ฒ ์ ์ด๊ถ์ ๋ฐํํด์ผํ๋ค.
โ bogus fault : ๋ฌผ๋ฆฌ๋ฉ๋ชจ๋ฆฌ์ ๋งตํ๋์ด ์์ง๋ง ์ฝํ
์ธ ๊ฐ ๋ก๋ ๋์ด ์์ง ์์ ๊ฒฝ์ฐ
โ ๋งตํ์ด ์๋ ๊ฑฐ๋ฉด valid page fault, ๋งตํ์ ๋์ด์๋๋ฐ ์ฝํ
์ธ ๊ฐ ๋ก๋๊ฐ ์๋ ๊ฑฐ๋ฉด bogus fault
Bogus ํ์ด์ง ํดํธ๊ฐ ์ผ์ด๋๋ 3๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ์๋ค. ์ง์ฐ ๋ก๋ฉ ํ์ด์ง, ์ค์ ์์ ํ์ด์ง, ์ฐ๊ธฐ ๋ณดํธ ํ์ด์ง. ์ง๊ธ์ ์ฒซ ๋ฒ์งธ ์ผ์ด์ค์ธ ์ง์ฐ ๋ก๋ ํ์ด์ง์ ๋ํด์๋ง ์๊ฐํด๋ณด์. ๋ง์ฝ ์ง์ฐ ๋ก๋ฉ ๋๋ฌธ์ ํ์ด์ง ํดํธ๊ฐ ์ผ์ด๋๋ฉด, ์ปค๋์ ์ธ๊ทธ๋จผํธ๋ฅผ ์ง์ฐ ๋ก๋ฉํ๊ธฐ ์ํด vm_alloc_page_with_initializer ํจ์์์ ์ธํ ํด ๋์ ์ด๊ธฐํ ํจ์๋ฅผ ํธ์ถํ๋ค. userprog/process.c์ ์๋ lazy_load_segment ํจ์๋ฅผ ๊ตฌํํด์ผ ํ๋ค.
bool vm_alloc_page_with_initializer (enum vm_type type, void *upage,
bool writable, vm_initializer *init, void *aux);
Userprog/process.c ์ ์๋ load_segment์ lazy_load_segment๋ฅผ ๊ตฌํํด๋ผ. ์คํํ์ผ๋ก๋ถํฐ ์ธ๊ทธ๋จผํธ๊ฐ ๋ก๋ ๋๋ ๊ฒ์ ๊ตฌํํด๋ผ. ์ด๋ฌํ ๋ชจ๋ ํ์ด์ง๋ค์ ์ง์ฐ ๋ก๋๋ ๊ฒ์ด๋ค. ์ฆ, ์ด ํ์ด์ง๋ค์ ๋ฐ์ํ page fault๋ฅผ ์ปค๋์ด ๋ค๋ฃฐ ๊ฒ์ด๋ค.
Program loader์ ํต์ฌ์ธ userprog/process.c์ load_segment loop ๋ด๋ถ๋ฅผ ์์ ํด์ผํ๋ค. ๋ฃจํ๋ฅผ ๋ ๋๋ง๋ค load_segment๋ ๋๊ธฐ ์ค์ธ ํ์ด์ง ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ๋ vm_alloc_page_with _initializer๋ฅผ ํธ์ถํ๋ค. ํ์ด์ง ํดํธ๊ฐ ๋ฐ์ํ๋ ์๊ฐ์ ์ธ๊ทธ๋จผํธ๊ฐ ์ค์ ๋ก ํ์ผ์์ ๋ก๋๋ ๋๋ค.
โ bool load_segment() : ํ์ฌ ์ฝ๋๋ ๋ฉ์ธ ๋ฃจํ ์์์ ํ์ผ๋ก๋ถํฐ ์ฝ์ ๋ฐ์ดํธ์ ์์ 0์ผ๋ก ์ฑ์์ผ ํ ๋ฐ์ดํธ์ ์๋ฅผ ์ธก์ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ ๋๊ธฐ ์ค์ธ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ๋ vm_alloc_page_with_initializer ํจ์๋ฅผ ํธ์ถํ๋ค. ์ด ํจ์์๊ฒ ์ ๊ณตํ aux ์ธ์๋ก์จ, ๋ณด์กฐ ๊ฐ๋ค์ ์ค์ ํ ํ์๊ฐ ์๋ค. ๋ฐ์ด๋๋ฆฌ ํ์ผ์ ๋ก๋ํ ๋ ํ์์ ์ธ ์ ๋ณด๋ฅผ ํฌํจํ๋ ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ข๋ค.
โ bool lazy_load_segment() : load_segment ํจ์ ๋ด๋ถ์ vm_alloc_page_with_initializer์ ๋ค ๋ฒ์งธ ์ธ์๊ฐ lazy_load_segment๋ผ๋ ๊ฒ์ ์์์ฐจ๋ ธ์ ๊ฒ์ด๋ค. ์ด ํจ์๋ ์คํ ๊ฐ๋ฅํ ํ์ผ์ ํ์ด์ง๋ค์ ์ด๊ธฐํํ๋ ํจ์์ด๊ณ page fault๊ฐ ๋ฐ์ํ ๋ ํธ์ถ๋๋ค. ์ด ํจ์๋ ํ์ด์ง ๊ตฌ์กฐ์ฒด์ aux๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค. aux๋ load_segment์์ ๋น์ ์ด ์ค์ ํ๋ ์ ๋ณด๋ค. ์ด ์ ๋ณด๋ฅผ ์ฌ์ฉํ์ฌ ์ธ๊ทธ๋จผํธ๋ฅผ ์ฝ์ ํ์ผ์ ์ฐพ๊ณ ์ต์ข
์ ์ผ๋ก๋ ์ธ๊ทธ๋จผํธ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์์ ์ฝ์ด์ผํ๋ค.
์คํ ํ ๋น๋ถ๋ถ์ด ์๋ก์ด ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ์์คํ
์ ์ ํฉํ ์ ์๋๋ก userprog/process.c์ ์๋ setup_stack์ ์์ ํด์ผํ๋ค. ์ฒซ ์คํ ํ์ด์ง๋ ์ง์ฐ์ ์ผ๋ก ํ ๋น๋ ํ์๊ฐ ์๋ค. ํ์ด์ง ํดํธ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๊ธฐ๋ค๋ฆด ํ์์์ด ๊ทธ๊ฒ(์คํ ํ์ด์ง)์ ๋ก๋๋ ๋ ์ปค๋งจ๋ ๋ผ์ธ์ ์ธ์๋ค๊ณผ ํจ๊ป ํ ๋นํ๊ณ ์ด๊ธฐํ ํ ์ ์๋ค. ๋น์ ์ ์คํ์ ํ์ธํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํด์ผํ๋ค. ๋น์ ์ vm/vm.h์ vm_type์ ์๋ ๋ณด์กฐ marker(VM_MARKER_0)๋ค์ ํ์ด์ง๋ฅผ ๋งํนํ๋๋ฐ ์ฌ์ฉํ ์ ์๋ค.
์ต์ข
์ ์ผ๋ก spt_find_page๋ฅผ ๊ฑฐ์ณ spt๋ฅผ ์ฐธ๊ณ ํ์ฌ fault๋ ์ฃผ์์ ๋์ํ๋ ํ์ด์ง ๊ตฌ์กฐ์ฒด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ํจ์ vm_try_handle_fault๋ฅผ ์์ ํด๋ผ.