728x90
코드
static bool
load_segment (struct file *file, off_t ofs, uint8_t *upage,
uint32_t read_bytes, uint32_t zero_bytes, bool writable) {
ASSERT ((read_bytes + zero_bytes) % PGSIZE == 0);
ASSERT (pg_ofs (upage) == 0);
ASSERT (ofs % PGSIZE == 0);
file_seek (file, ofs);
while (read_bytes > 0 || zero_bytes > 0) {
/* Do calculate how to fill this page.
* We will read PAGE_READ_BYTES bytes from FILE
* and zero the final PAGE_ZERO_BYTES bytes. */
size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE;
size_t page_zero_bytes = PGSIZE - page_read_bytes;
/* Get a page of memory. */
uint8_t *kpage = palloc_get_page (PAL_USER);
if (kpage == NULL)
return false;
/* Load this page. */
if (file_read (file, kpage, page_read_bytes) != (int) page_read_bytes) {
palloc_free_page (kpage);
return false;
}
memset (kpage + page_read_bytes, 0, page_zero_bytes);
/* Add the page to the process's address space. */
if (!install_page (upage, kpage, writable)) {
printf("fail\n");
palloc_free_page (kpage);
return false;
}
/* Advance. */
read_bytes -= page_read_bytes;
zero_bytes -= page_zero_bytes;
upage += PGSIZE;
}
return true;
}
목적
file 내에서 ofs부터 시작해 upage라는 주소공간에 세그먼트를 불러들입니다. 이 함수를 통해 초기화된 페이지들에 대해서 만약 writable이 true로 넘어왔다면 writable해야 하고, 그렇지 않으면 read-only여야 합니다. 만약 메모리 할당 에러나 디스크 읽기 에러가 난 경우에는 false를 반환합니다.
요약: 파일[ofs:] 로 읽어서 페이지 할당받고 가상->물리 매핑도 추가해줌.
루틴
호출되는 곳
/userprog/process.c의 load 함수
case PT_LOAD:
if (validate_segment (&phdr, file)) {
bool writable = (phdr.p_flags & PF_W) != 0;
uint64_t file_page = phdr.p_offset & ~PGMASK;
uint64_t mem_page = phdr.p_vaddr & ~PGMASK;
uint64_t page_offset = phdr.p_vaddr & PGMASK;
uint32_t read_bytes, zero_bytes;
if (phdr.p_filesz > 0) {
/* Normal segment.
* Read initial part from disk and zero the rest. */
read_bytes = page_offset + phdr.p_filesz;
zero_bytes = (ROUND_UP (page_offset + phdr.p_memsz, PGSIZE)
- read_bytes);
} else {
/* Entirely zero.
* Don't read anything from disk. */
read_bytes = 0;
zero_bytes = ROUND_UP (page_offset + phdr.p_memsz, PGSIZE);
}
if (!load_segment (file, file_page, (void *) mem_page,
read_bytes, zero_bytes, writable))
goto done;
}
- PT_LOAD : ELF의 타입이다. PT_LOAD는 loadable한 elf파일. 더 많은 정보는 [ELF1] 1-2를 보라고 한다.
- validate_segment : PHDR이 valid하고 loadable segment를 가리키는지 확인한다.
- PHDR : ELF 내 세그먼트의 종류, ELF header, Program header, Section header가 있다. (참고할 곳)
728x90
'🚩 3. Projects & Retrospect > SW사관학교 정글 4기' 카테고리의 다른 글
| 정글 수료 그 후, 무엇을 할까? (2) | 2022.08.26 |
|---|---|
| install_page (0) | 2022.06.11 |
| [SW사관학교 정글] Week 09~10 회고 (0) | 2022.06.08 |
| 정글 Chapter 3. 정글 끝까지 - 1, 2 회고 (0) | 2022.06.08 |
| [Project 2 - Userprogram] 시스템콜, 시스템콜 핸들러 (0) | 2022.06.05 |
댓글