PKUOS - Pintos
Pintos source browser for PKU Operating System course
|
#include "userprog/process.h"
#include <debug.h>
#include <inttypes.h>
#include <round.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "userprog/gdt.h"
#include "userprog/pagedir.h"
#include "userprog/tss.h"
#include "filesys/directory.h"
#include "filesys/file.h"
#include "filesys/filesys.h"
#include "threads/flags.h"
#include "threads/init.h"
#include "threads/interrupt.h"
#include "threads/palloc.h"
#include "threads/thread.h"
#include "threads/vaddr.h"
Go to the source code of this file.
Data Structures | |
struct | Elf32_Ehdr |
Executable header. More... | |
struct | Elf32_Phdr |
Program header. More... | |
Macros | |
#define | PE32Wx PRIx32 |
For use with ELF types in printf(). More... | |
#define | PE32Ax PRIx32 |
Print Elf32_Addr in hexadecimal. More... | |
#define | PE32Ox PRIx32 |
Print Elf32_Off in hexadecimal. More... | |
#define | PE32Hx PRIx16 |
Print Elf32_Half in hexadecimal. More... | |
#define | PT_NULL 0 |
Values for p_type. More... | |
#define | PT_LOAD 1 |
Loadable segment. More... | |
#define | PT_DYNAMIC 2 |
Dynamic linking info. More... | |
#define | PT_INTERP 3 |
Name of dynamic loader. More... | |
#define | PT_NOTE 4 |
Auxiliary info. More... | |
#define | PT_SHLIB 5 |
Reserved. More... | |
#define | PT_PHDR 6 |
Program header table. More... | |
#define | PT_STACK 0x6474e551 |
Stack segment. More... | |
#define | PF_X 1 |
Flags for p_flags. More... | |
#define | PF_W 2 |
Writable. More... | |
#define | PF_R 4 |
Readable. More... | |
Typedefs | |
typedef uint32_t | Elf32_Word |
We load ELF binaries. More... | |
typedef uint32_t | Elf32_Addr |
typedef uint32_t | Elf32_Off |
typedef uint16_t | Elf32_Half |
Functions | |
static bool | load (const char *file_name, void(**eip)(void), void **esp) |
Loads an ELF executable from FILE_NAME into the current thread. More... | |
tid_t | process_execute (const char *file_name) |
Starts a new thread running a user program loaded from FILENAME. More... | |
static void | start_process (void *file_name_) |
A thread function that loads a user process and starts it running. More... | |
int | process_wait (tid_t child_tid UNUSED) |
Waits for thread TID to die and returns its exit status. More... | |
void | process_exit (void) |
Free the current process's resources. More... | |
void | process_activate (void) |
Sets up the CPU for running user code in the current thread. More... | |
static bool | setup_stack (void **esp) |
Create a minimal stack by mapping a zeroed page at the top of user virtual memory. More... | |
static bool | validate_segment (const struct Elf32_Phdr *phdr, struct file *file) |
Checks whether PHDR describes a valid, loadable segment in FILE and returns true if so, false otherwise. More... | |
static bool | load_segment (struct file *file, off_t ofs, uint8_t *upage, uint32_t read_bytes, uint32_t zero_bytes, bool writable) |
Loads a segment starting at offset OFS in FILE at address UPAGE. More... | |
static bool | install_page (void *upage, void *kpage, bool writable) |
load() helpers. More... | |
Variables | |
static thread_func start_process | NO_RETURN |
#define PE32Wx PRIx32 |
#define PF_X 1 |
#define PT_NULL 0 |
typedef uint32_t Elf32_Addr |
typedef uint16_t Elf32_Half |
typedef uint32_t Elf32_Word |
load() helpers.
Adds a mapping from user virtual address UPAGE to kernel virtual address KPAGE to the page table.
If WRITABLE is true, the user process may modify the page; otherwise, it is read-only. UPAGE must not already be mapped. KPAGE should probably be a page obtained from the user pool with palloc_get_page(). Returns true on success, false if UPAGE is already mapped or if memory allocation fails.
Definition at line 457 of file process.c.
References NULL, pagedir_get_page(), pagedir_set_page(), and thread_current().
Referenced by load_segment(), and setup_stack().
|
static |
Loads an ELF executable from FILE_NAME into the current thread.
Stores the executable's entry point into *EIP and its initial stack pointer into *ESP. Returns true if successful, false otherwise.
Definition at line 209 of file process.c.
References Elf32_Ehdr::e_entry, Elf32_Ehdr::e_ident, Elf32_Ehdr::e_machine, Elf32_Ehdr::e_phentsize, Elf32_Ehdr::e_phnum, Elf32_Ehdr::e_phoff, Elf32_Ehdr::e_type, Elf32_Ehdr::e_version, file_close(), file_length(), file_name, file_read(), file_seek(), filesys_open(), load_segment(), memcmp(), NULL, Elf32_Phdr::p_filesz, Elf32_Phdr::p_flags, Elf32_Phdr::p_memsz, Elf32_Phdr::p_offset, Elf32_Phdr::p_type, Elf32_Phdr::p_vaddr, pagedir_create(), PF_W, PGMASK, PGSIZE, printf(), process_activate(), PT_DYNAMIC, PT_INTERP, PT_LOAD, PT_NOTE, PT_NULL, PT_PHDR, PT_SHLIB, PT_STACK, ROUND_UP, setup_stack(), thread_current(), and validate_segment().
Referenced by start_process().
|
static |
Loads a segment starting at offset OFS in FILE at address UPAGE.
In total, READ_BYTES + ZERO_BYTES bytes of virtual memory are initialized, as follows:
- READ_BYTES bytes at UPAGE must be read from FILE starting at offset OFS. - ZERO_BYTES bytes at UPAGE + READ_BYTES must be zeroed.
The pages initialized by this function must be writable by the user process if WRITABLE is true, read-only otherwise.
Return true if successful, false if a memory allocation error or disk read error occurs.
Definition at line 383 of file process.c.
References ASSERT, file_read(), file_seek(), install_page(), memset(), NULL, PAL_USER, palloc_free_page(), palloc_get_page(), pg_ofs(), and PGSIZE.
Referenced by load().
void process_activate | ( | void | ) |
Sets up the CPU for running user code in the current thread.
This function is called on every context switch.
Definition at line 123 of file process.c.
References pagedir_activate(), thread_current(), and tss_update().
Referenced by load(), and thread_schedule_tail().
tid_t process_execute | ( | const char * | file_name | ) |
Starts a new thread running a user program loaded from FILENAME.
The new thread may be scheduled (and may even exit) before process_execute() returns. Returns the new process's thread id, or TID_ERROR if the thread cannot be created.
Definition at line 29 of file process.c.
References file_name, NULL, palloc_free_page(), palloc_get_page(), PGSIZE, PRI_DEFAULT, start_process(), strlcpy(), thread_create(), and TID_ERROR.
Referenced by run_task().
void process_exit | ( | void | ) |
Free the current process's resources.
Definition at line 96 of file process.c.
References NULL, pagedir_activate(), pagedir_destroy(), and thread_current().
Referenced by thread_exit().
int process_wait | ( | tid_t child_tid | UNUSED | ) |
Waits for thread TID to die and returns its exit status.
If it was terminated by the kernel (i.e. killed due to an exception), returns -1. If TID is invalid or if it was not a child of the calling process, or if process_wait() has already been successfully called for the given TID, returns -1 immediately, without waiting.
This function will be implemented in problem 2-2. For now, it does nothing.
Definition at line 89 of file process.c.
Referenced by run_task().
|
static |
Create a minimal stack by mapping a zeroed page at the top of user virtual memory.
Definition at line 430 of file process.c.
References install_page(), NULL, PAL_USER, PAL_ZERO, palloc_free_page(), palloc_get_page(), PGSIZE, and PHYS_BASE.
Referenced by load().
|
static |
A thread function that loads a user process and starts it running.
Definition at line 51 of file process.c.
References intr_frame::cs, intr_frame::ds, intr_frame::eflags, intr_frame::eip, intr_frame::es, intr_frame::esp, file_name, FLAG_IF, FLAG_MBS, intr_frame::fs, intr_frame::gs, load(), memset(), NOT_REACHED, palloc_free_page(), SEL_UCSEG, SEL_UDSEG, intr_frame::ss, and thread_exit().
Referenced by process_execute().
|
static |
Checks whether PHDR describes a valid, loadable segment in FILE and returns true if so, false otherwise.
Definition at line 326 of file process.c.
References file_length(), is_user_vaddr(), Elf32_Phdr::p_filesz, Elf32_Phdr::p_memsz, Elf32_Phdr::p_offset, Elf32_Phdr::p_vaddr, PGMASK, and PGSIZE.
Referenced by load().
|
static |