projects
/
pintos-anon
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Break TSS out of GDT.
[pintos-anon]
/
src
/
userprog
/
addrspace.c
diff --git
a/src/userprog/addrspace.c
b/src/userprog/addrspace.c
index c136ae55d0bef505985e312e6a82b07d8ed0b9f7..1170f16ab92a7f61f1a93ad381ea49ff38208e63 100644
(file)
--- a/
src/userprog/addrspace.c
+++ b/
src/userprog/addrspace.c
@@
-6,9
+6,10
@@
#include "init.h"
#include "lib.h"
#include "mmu.h"
#include "init.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"
+#include "tss.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. */
@@
-80,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
{
@@
-95,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);
@@
-148,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;
}
@@
-156,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)
@@
-165,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"));
@@
-207,8
+213,8
@@
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"));
file_ofs += sizeof phdr;
switch (phdr.p_type)
LOAD_ERROR (("error reading program header"));
file_ofs += sizeof phdr;
switch (phdr.p_type)
@@
-229,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. */
@@
-245,26
+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);
- tss
->esp0 = (uint32_t) pg_round_down (as) + PGSIZE
;
+ if (
t
->pagedir != NULL)
+ pagedir_activate (
t
->pagedir);
+ tss
_set_esp0 ((uint8_t *) t + PGSIZE)
;
}
}