projects
/
pintos-anon
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Break GDT, TSS out of init.c, mmu.h.
[pintos-anon]
/
src
/
userprog
/
addrspace.c
diff --git
a/src/userprog/addrspace.c
b/src/userprog/addrspace.c
index eb0de496851a5a340270e8d1cdd38074d677d88e..519da93cc90ed302ddf5ab3ea684d5ff8f95e238 100644
(file)
--- a/
src/userprog/addrspace.c
+++ b/
src/userprog/addrspace.c
@@
-3,11
+3,13
@@
#include "debug.h"
#include "file.h"
#include "filesys.h"
#include "debug.h"
#include "file.h"
#include "filesys.h"
+#include "gdt.h"
+#include "init.h"
#include "lib.h"
#include "mmu.h"
#include "lib.h"
#include "mmu.h"
-#include "malloc.h"
#include "paging.h"
#include "palloc.h"
#include "paging.h"
#include "palloc.h"
+#include "thread.h"
/* We load ELF binaries. The following definitions are taken
from the ELF specification more-or-less verbatim. */
/* We load ELF binaries. The following definitions are taken
from the ELF specification more-or-less verbatim. */
@@
-79,12
+81,12
@@
struct Elf32_Phdr
} while (0)
static bool
} while (0)
static bool
-install_page (struct
addrspace *as
, void *upage, void *kpage)
+install_page (struct
thread *t
, void *upage, void *kpage)
{
/* Verify that there's not already a page at that virtual
address, then map our page there. */
{
/* Verify that there's not already a page at that virtual
address, then map our page there. */
- if (pagedir_get_page (
as
->pagedir, upage) == NULL
- && pagedir_set_page (
as
->pagedir, upage, kpage, true))
+ if (pagedir_get_page (
t
->pagedir, upage) == NULL
+ && pagedir_set_page (
t
->pagedir, upage, kpage, true))
return true;
else
{
return true;
else
{
@@
-94,14
+96,14
@@
install_page (struct addrspace *as, void *upage, void *kpage)
}
static bool
}
static bool
-load_segment (struct
addrspace *as
, struct file *file,
+load_segment (struct
thread *t
, struct file *file,
const struct Elf32_Phdr *phdr)
{
void *start, *end;
uint8_t *upage;
off_t filesz_left;
const struct Elf32_Phdr *phdr)
{
void *start, *end;
uint8_t *upage;
off_t filesz_left;
- ASSERT (
as
!= NULL);
+ ASSERT (
t
!= NULL);
ASSERT (file != NULL);
ASSERT (phdr != NULL);
ASSERT (phdr->p_type == PT_LOAD);
ASSERT (file != NULL);
ASSERT (phdr != NULL);
ASSERT (phdr->p_type == PT_LOAD);
@@
-147,7
+149,7
@@
load_segment (struct addrspace *as, struct file *file,
memset (kpage + read_bytes, 0, zero_bytes);
filesz_left -= read_bytes;
memset (kpage + read_bytes, 0, zero_bytes);
filesz_left -= read_bytes;
- if (!install_page (
as
, upage, kpage))
+ if (!install_page (
t
, upage, kpage))
return false;
}
return false;
}
@@
-155,7
+157,7
@@
load_segment (struct addrspace *as, struct file *file,
}
static bool
}
static bool
-setup_stack (struct
addrspace *as
)
+setup_stack (struct
thread *t
)
{
uint8_t *kpage = palloc_get (PAL_ZERO);
if (kpage == NULL)
{
uint8_t *kpage = palloc_get (PAL_ZERO);
if (kpage == NULL)
@@
-164,27
+166,32
@@
setup_stack (struct addrspace *as)
return false;
}
return false;
}
- return install_page (
as
, ((uint8_t *) PHYS_BASE) - PGSIZE, kpage);
+ return install_page (
t
, ((uint8_t *) PHYS_BASE) - PGSIZE, kpage);
}
bool
}
bool
-addrspace_load (struct
addrspace *as
, const char *filename,
+addrspace_load (struct
thread *t
, const char *filename,
void (**start) (void))
{
struct Elf32_Ehdr ehdr;
void (**start) (void))
{
struct Elf32_Ehdr ehdr;
- struct file *file = NULL;
+ struct file file;
+ bool file_open = false;
off_t file_ofs;
bool success = false;
int i;
off_t file_ofs;
bool success = false;
int i;
- as->pagedir = pagedir_create ();
+ /* Allocate page directory. */
+ t->pagedir = pagedir_create ();
+ if (t->pagedir == NULL)
+ LOAD_ERROR (("page directory allocation failed"));
- file = filesys_open (filename);
- if (file == NULL)
+ /* Open executable file. */
+ file_open = filesys_open (filename, &file);
+ if (!file_open)
LOAD_ERROR (("open failed"));
/* Read and verify executable header. */
LOAD_ERROR (("open failed"));
/* Read and verify executable header. */
- if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr)
+ if (file_read (
&
file, &ehdr, sizeof ehdr) != sizeof ehdr)
LOAD_ERROR (("error reading executable header"));
if (memcmp (ehdr.e_ident, "\177ELF\1\1\1", 7) != 0)
LOAD_ERROR (("file is not ELF"));
LOAD_ERROR (("error reading executable header"));
if (memcmp (ehdr.e_ident, "\177ELF\1\1\1", 7) != 0)
LOAD_ERROR (("file is not ELF"));
@@
-206,14
+213,9
@@
addrspace_load (struct addrspace *as, const char *filename,
{
struct Elf32_Phdr phdr;
{
struct Elf32_Phdr phdr;
- file_seek (file, file_ofs);
- if (file_read (file, &phdr, sizeof phdr) != sizeof phdr)
+ file_seek (
&
file, file_ofs);
+ if (file_read (
&
file, &phdr, sizeof phdr) != sizeof phdr)
LOAD_ERROR (("error reading program header"));
LOAD_ERROR (("error reading program header"));
- printk ("%x: %08x, %08x %08x %08x %05x %05x\n",
- file_tell (file),
- phdr.p_type,
- phdr.p_offset, phdr.p_vaddr, phdr.p_paddr,
- phdr.p_filesz, phdr.p_memsz);
file_ofs += sizeof phdr;
switch (phdr.p_type)
{
file_ofs += sizeof phdr;
switch (phdr.p_type)
{
@@
-233,14
+235,14
@@
addrspace_load (struct addrspace *as, const char *filename,
printk ("unknown ELF segment type %08x\n", phdr.p_type);
break;
case PT_LOAD:
printk ("unknown ELF segment type %08x\n", phdr.p_type);
break;
case PT_LOAD:
- if (!load_segment (
as,
file, &phdr))
+ if (!load_segment (
t, &
file, &phdr))
goto error;
break;
}
}
/* Set up stack. */
goto error;
break;
}
}
/* Set up stack. */
- if (!setup_stack (
as
))
+ if (!setup_stack (
t
))
goto error;
/* Start address. */
goto error;
/* Start address. */
@@
-249,25
+251,29
@@
addrspace_load (struct addrspace *as, const char *filename,
success = true;
error:
success = true;
error:
- if (file
!= NULL
)
- file_close (file);
+ if (file
_open
)
+ file_close (
&
file);
if (!success)
if (!success)
- addrspace_destroy (
as
);
+ addrspace_destroy (
t
);
return success;
}
void
return success;
}
void
-addrspace_destroy (struct
addrspace *as
)
+addrspace_destroy (struct
thread *t
)
{
{
- if (as != NULL && as->pagedir != NULL)
- pagedir_destroy (as->pagedir);
+ if (t->pagedir != NULL)
+ {
+ pagedir_destroy (t->pagedir);
+ t->pagedir = NULL;
+ }
}
void
}
void
-addrspace_activate (struct
addrspace *as)
+addrspace_activate (struct
thread *t)
{
{
- ASSERT (
as
!= NULL);
+ ASSERT (
t
!= NULL);
- if (as->pagedir != NULL)
- pagedir_activate (as->pagedir);
+ if (t->pagedir != NULL)
+ pagedir_activate (t->pagedir);
+ tss->esp0 = (uint32_t) t + PGSIZE;
}
}