Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
Pintos_Student
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
s2-fidan
Pintos_Student
Commits
7f930d2c
Commit
7f930d2c
authored
2 years ago
by
s2-fidan
Browse files
Options
Downloads
Patches
Plain Diff
save
parent
b35e7104
No related branches found
No related tags found
No related merge requests found
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
src/userprog/process.c
+279
-330
279 additions, 330 deletions
src/userprog/process.c
src/userprog/process.h
+4
-0
4 additions, 0 deletions
src/userprog/process.h
src/userprog/syscall.c
+137
-3
137 additions, 3 deletions
src/userprog/syscall.c
src/userprog/syscall.h
+12
-0
12 additions, 0 deletions
src/userprog/syscall.h
with
432 additions
and
333 deletions
src/userprog/process.c
+
279
−
330
View file @
7f930d2c
...
@@ -31,8 +31,10 @@ tid_t
...
@@ -31,8 +31,10 @@ tid_t
process_execute
(
const
char
*
file_name
)
process_execute
(
const
char
*
file_name
)
{
{
char
*
file_copy
;
char
*
file_copy
;
char
*
ptr
;
tid_t
tid
;
tid_t
tid
;
char
*
ptr
=
NULL
;
int
file_name_length
=
strlen
(
file_name
)
+
1
;
char
program
[
file_name_length
];
/* Make a copy of command line. Otherwise there's a race between the caller and load(). */
/* Make a copy of command line. Otherwise there's a race between the caller and load(). */
file_copy
=
palloc_get_page
(
0
);
file_copy
=
palloc_get_page
(
0
);
...
@@ -40,8 +42,10 @@ process_execute(const char *file_name)
...
@@ -40,8 +42,10 @@ process_execute(const char *file_name)
return
TID_ERROR
;
return
TID_ERROR
;
strlcpy
(
file_copy
,
file_name
,
PGSIZE
);
strlcpy
(
file_copy
,
file_name
,
PGSIZE
);
/* Extract file_name from command line. */
/* Parse first argument as program name */
file_name
=
strtok_r
(
file_name
,
" "
,
&
ptr
);
strlcpy
(
program
,
file_name
,
file_name_length
);
strtok_r
(
program
,
" "
,
&
ptr
);
printf
(
"
\n
Program name: %s
\n\n
"
,
program
)
;
/* Create a new thread to execute FILE_NAME. */
/* Create a new thread to execute FILE_NAME. */
tid
=
thread_create
(
file_name
,
PRI_DEFAULT
,
start_process
,
file_copy
);
tid
=
thread_create
(
file_name
,
PRI_DEFAULT
,
start_process
,
file_copy
);
...
@@ -61,7 +65,7 @@ start_process (void *file_name_)
...
@@ -61,7 +65,7 @@ start_process (void *file_name_)
char
*
file_name
=
file_name_
;
char
*
file_name
=
file_name_
;
struct
intr_frame
if_
;
struct
intr_frame
if_
;
bool
success
;
bool
success
;
char
*
temp
[
50
];
char
*
parse
[
2
50
];
char
*
token
;
char
*
token
;
char
*
ptr
;
char
*
ptr
;
int
count
=
0
;
int
count
=
0
;
...
@@ -69,8 +73,11 @@ start_process (void *file_name_)
...
@@ -69,8 +73,11 @@ start_process (void *file_name_)
for
(
token
=
strtok_r
(
file_name
,
" "
,
&
ptr
);
token
!=
NULL
;
for
(
token
=
strtok_r
(
file_name
,
" "
,
&
ptr
);
token
!=
NULL
;
token
=
strtok_r
(
NULL
,
" "
,
&
ptr
))
token
=
strtok_r
(
NULL
,
" "
,
&
ptr
))
{
{
temp
[
count
++
]
=
token
;
parse
[
count
]
=
token
;
count
++
;
printf
(
"
\n
Tokenized Argument: %s
\n
"
,
parse
[
count
-
1
]);
}
}
printf
(
"
\n
Number of tokenized Arguments : %d
\n
"
,
count
);
/* Initialize interrupt frame and load executable. */
/* Initialize interrupt frame and load executable. */
memset
(
&
if_
,
0
,
sizeof
if_
);
memset
(
&
if_
,
0
,
sizeof
if_
);
...
@@ -78,9 +85,9 @@ start_process (void *file_name_)
...
@@ -78,9 +85,9 @@ start_process (void *file_name_)
if_
.
cs
=
SEL_UCSEG
;
if_
.
cs
=
SEL_UCSEG
;
if_
.
eflags
=
FLAG_IF
|
FLAG_MBS
;
if_
.
eflags
=
FLAG_IF
|
FLAG_MBS
;
success
=
load
(
file_name
,
&
if_
.
eip
,
&
if_
.
esp
);
success
=
load
(
parse
[
0
]
,
&
if_
.
eip
,
&
if_
.
esp
);
argument_pushing
(
&
temp
,
count
,
&
if_
.
esp
);
argument_pushing
(
&
parse
,
count
,
&
if_
.
esp
);
hex_dump
(
if_
.
esp
,
if_
.
esp
,
PHYS_BASE
-
if_
.
esp
,
true
);
hex_dump
(
if_
.
esp
,
if_
.
esp
,
PHYS_BASE
-
if_
.
esp
,
true
);
...
@@ -157,7 +164,7 @@ process_activate (void)
...
@@ -157,7 +164,7 @@ process_activate (void)
interrupts. */
interrupts. */
tss_update
();
tss_update
();
}
}
/* We load ELF binaries. The following definitions are taken
/* We load ELF binaries. The following definitions are taken
from the ELF specification, [ELF1], more-or-less verbatim. */
from the ELF specification, [ELF1], more-or-less verbatim. */
...
@@ -221,7 +228,7 @@ struct Elf32_Phdr
...
@@ -221,7 +228,7 @@ struct Elf32_Phdr
#define PF_W 2
/* Writable. */
#define PF_W 2
/* Writable. */
#define PF_R 4
/* Readable. */
#define PF_R 4
/* Readable. */
static
bool
setup_stack
(
void
**
esp
,
char
*
cmdline
);
static
bool
setup_stack
(
void
**
esp
);
static
bool
validate_segment
(
const
struct
Elf32_Phdr
*
,
struct
file
*
);
static
bool
validate_segment
(
const
struct
Elf32_Phdr
*
,
struct
file
*
);
static
bool
load_segment
(
struct
file
*
file
,
off_t
ofs
,
uint8_t
*
upage
,
static
bool
load_segment
(
struct
file
*
file
,
off_t
ofs
,
uint8_t
*
upage
,
uint32_t
read_bytes
,
uint32_t
zero_bytes
,
uint32_t
read_bytes
,
uint32_t
zero_bytes
,
...
@@ -257,13 +264,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
...
@@ -257,13 +264,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
}
}
/* Read and verify executable header. */
/* Read and verify executable header. */
if
(
file_read
(
file
,
&
ehdr
,
sizeof
ehdr
)
!=
sizeof
ehdr
if
(
file_read
(
file
,
&
ehdr
,
sizeof
ehdr
)
!=
sizeof
ehdr
||
memcmp
(
ehdr
.
e_ident
,
"
\177
ELF
\1\1\1
"
,
7
)
||
ehdr
.
e_type
!=
2
||
ehdr
.
e_machine
!=
3
||
ehdr
.
e_version
!=
1
||
ehdr
.
e_phentsize
!=
sizeof
(
struct
Elf32_Phdr
)
||
ehdr
.
e_phnum
>
1024
)
||
memcmp
(
ehdr
.
e_ident
,
"
\177
ELF
\1\1\1
"
,
7
)
||
ehdr
.
e_type
!=
2
||
ehdr
.
e_machine
!=
3
||
ehdr
.
e_version
!=
1
||
ehdr
.
e_phentsize
!=
sizeof
(
struct
Elf32_Phdr
)
||
ehdr
.
e_phnum
>
1024
)
{
{
printf
(
"load: %s: error loading executable
\n
"
,
file_name
);
printf
(
"load: %s: error loading executable
\n
"
,
file_name
);
goto
done
;
goto
done
;
...
@@ -308,8 +309,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
...
@@ -308,8 +309,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
/* Normal segment.
/* Normal segment.
Read initial part from disk and zero the rest. */
Read initial part from disk and zero the rest. */
read_bytes
=
page_offset
+
phdr
.
p_filesz
;
read_bytes
=
page_offset
+
phdr
.
p_filesz
;
zero_bytes
=
(
ROUND_UP
(
page_offset
+
phdr
.
p_memsz
,
PGSIZE
)
zero_bytes
=
(
ROUND_UP
(
page_offset
+
phdr
.
p_memsz
,
PGSIZE
)
-
read_bytes
);
-
read_bytes
);
}
}
else
else
{
{
...
@@ -452,41 +452,57 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
...
@@ -452,41 +452,57 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
}
}
/* References: J,Choi(2014), pintos. Available from: https://github.com/wookayin/pintos [accessed on 23/11/22]*/
/* References: J,Choi(2014), pintos. Available from: https://github.com/wookayin/pintos [accessed on 23/11/22]*/
static
void
static
void
argument_pushing
(
char
**
parse
,
int
argc
,
void
**
esp
)
argument_pushing
(
char
**
parse
,
int
count
,
void
**
esp
)
{
{
/* Increment Counter */
int
i
,
j
;
int
i
;
int
length
=
0
;
// Argument length
int
len
=
0
;
int
parse0_address
;
// First Argument's Adress
int
argv_addr
[
argc
];
int
address
[
count
];
// Argument adress
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
len
=
strlen
(
parse
[
i
])
+
1
;
/*Push arguments to stack one by one*/
*
esp
-=
len
;
for
(
i
=
count
-
1
;
i
>
-
1
;
i
--
)
memcpy
(
*
esp
,
parse
[
i
],
len
);
{
argv_addr
[
i
]
=
(
int
)
*
esp
;
for
(
j
=
strlen
(
parse
[
i
]);
j
>
-
1
;
j
--
)
{
*
esp
=
*
esp
-
1
;
**
(
char
**
)
esp
=
parse
[
i
][
j
];
length
++
;
/*Count length of arguments we pushed*/
}
}
/*Store address of argument*/
address
[
i
]
=
*
(
unsigned
int
*
)
esp
;
printf
(
"
\n
Adress of %d 's argument: %d
\n
"
,
i
+
1
,
address
[
i
]);
}
printf
(
"
\n
Number of arguments pushed onto stack: %d
\n
"
,
length
);
/* Word Allignment*/
/* Word Allignment*/
*
esp
=
(
int
)
*
esp
&
0xfffffffc
;
for
(
i
=
0
;
i
<
4
-
(
length
%
4
);
i
++
)
{
*
esp
=
*
esp
-
1
;
**
(
uint8_t
**
)
esp
=
0
;
}
/* Last
null
*/
/* Last
argument needs to be NULL
*/
*
esp
-=
4
;
*
esp
-=
4
;
*
(
int
*
)
*
esp
=
0
;
*
*
(
char
**
*
)
esp
=
0
;
/* Use argvs to set **esp */
/*Push argument adress - Use counter to set **esp */
for
(
i
=
argc
-
1
;
i
>=
0
;
i
--
)
{
for
(
i
=
count
-
1
;
i
>=
0
;
i
--
)
{
*
esp
-=
4
;
*
esp
-=
4
;
*
(
int
*
)
*
esp
=
argv_addr
[
i
];
*
*
(
char
***
)
esp
=
address
[
i
];
}
}
/* Set **argv*/
/* Set **argv*/
parse0_address
=
*
(
unsigned
int
*
)
esp
;
*
esp
-=
4
;
*
esp
-=
4
;
*
(
int
*
)
*
esp
=
(
int
)
*
esp
+
4
;
*
*
(
char
***
)
esp
=
(
char
*
)
parse0_address
;
/* Set
argc
*/
/* Set
counter
*/
*
esp
-=
4
;
*
esp
-=
4
;
*
(
int
*
)
*
esp
=
argc
;
*
(
int
*
)
*
esp
=
count
;
/* Set ret*/
/*
Fake Adress -
Set ret*/
*
esp
-=
4
;
*
esp
-=
4
;
*
(
int
*
)
*
esp
=
0
;
*
(
int
*
)
*
esp
=
0
;
}
}
...
@@ -503,77 +519,11 @@ setup_stack (void **esp)
...
@@ -503,77 +519,11 @@ setup_stack (void **esp)
if
(
kpage
!=
NULL
)
if
(
kpage
!=
NULL
)
{
{
success
=
install_page
(((
uint8_t
*
)
PHYS_BASE
)
-
PGSIZE
,
kpage
,
true
);
success
=
install_page
(((
uint8_t
*
)
PHYS_BASE
)
-
PGSIZE
,
kpage
,
true
);
if
(
success
)
{
if
(
success
)
*
esp
=
PHYS_BASE
;
*
esp
=
PHYS_BASE
;
}
else
palloc_free_page
(
kpage
);
}
char
*
token
,
*
temp_ptr
;
char
*
flname_cp
=
malloc
(
strlen
(
file_name
)
+
1
);
strlcpy
(
flname_cp
,
file_name
,
strlen
(
file_name
)
+
1
);
/* argc calculation*/
enum
intr_level
old_level
=
intr_disable
();
int
argc
=
1
;
/* Is the last char a space? - Only one space in the end*/
bool
is_lastchar_space
=
false
;
for
(
int
j
=
0
;
j
!=
strlen
(
file_name
);
j
++
){
if
(
file_name
[
j
]
==
' '
){
if
(
!
is_lastchar_space
)
argc
++
;
is_lastchar_space
=
true
;
}
else
else
is_lastchar_space
=
false
;
palloc_free_page
(
kpage
);
}
intr_set_level
(
old_level
);
int
*
argv
=
calloc
(
argc
,
sizeof
(
int
));
int
i
;
token
=
strtok_r
(
file_name
,
" "
,
&
temp_ptr
);
for
(
i
=
0
;
;
i
++
){
if
(
token
){
*
esp
-=
strlen
(
token
)
+
1
;
memcpy
(
*
esp
,
token
,
strlen
(
token
)
+
1
);
argv
[
i
]
=*
esp
;
token
=
strtok_r
(
NULL
,
" "
,
&
temp_ptr
);
}
else
{
break
;
}
}
/* Word alignment*/
*
esp
-=
((
unsigned
)
*
esp
%
WORD_SIZE
);
/* Null ptr sentinel: null at argv[argc]*/
*
esp
-=
sizeof
(
int
);
/* Push address*/
for
(
i
=
argc
-
1
;
i
>=
0
;
i
--
)
{
*
esp
-=
sizeof
(
int
);
memcpy
(
*
esp
,
&
argv
[
i
],
sizeof
(
int
));
}
}
/* Push argv address*/
int
tmp
=
*
esp
;
*
esp
-=
sizeof
(
int
);
memcpy
(
*
esp
,
&
tmp
,
sizeof
(
int
));
/* Push argc*/
*
esp
-=
sizeof
(
int
);
memcpy
(
*
esp
,
&
argc
,
sizeof
(
int
));
/* Return address*/
*
esp
-=
sizeof
(
int
);
memcpy
(
*
esp
,
&
argv
[
argc
],
sizeof
(
int
));
free
(
flname_cp
);
free
(
argv
);
return
success
;
return
success
;
}
}
...
@@ -593,8 +543,7 @@ install_page (void *upage, void *kpage, bool writable)
...
@@ -593,8 +543,7 @@ install_page (void *upage, void *kpage, bool writable)
/* Verify that there's not already a page at that virtual
/* Verify that there's not already a page at that virtual
address, then map our page there. */
address, then map our page there. */
return
(
pagedir_get_page
(
t
->
pagedir
,
upage
)
==
NULL
return
(
pagedir_get_page
(
t
->
pagedir
,
upage
)
==
NULL
&&
pagedir_set_page
(
t
->
pagedir
,
upage
,
kpage
,
writable
));
&&
pagedir_set_page
(
t
->
pagedir
,
upage
,
kpage
,
writable
));
}
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
This diff is collapsed.
Click to expand it.
src/userprog/process.h
+
4
−
0
View file @
7f930d2c
...
@@ -3,6 +3,10 @@
...
@@ -3,6 +3,10 @@
#include
"threads/thread.h"
#include
"threads/thread.h"
typedef
int
pit_t
;
#define PID_ERROR ((pid_t)-1)
#define PID_INITIALIZING ((pid_t) -2)
tid_t
process_execute
(
const
char
*
file_name
);
tid_t
process_execute
(
const
char
*
file_name
);
int
process_wait
(
tid_t
);
int
process_wait
(
tid_t
);
void
process_exit
(
void
);
void
process_exit
(
void
);
...
...
This diff is collapsed.
Click to expand it.
src/userprog/syscall.c
+
137
−
3
View file @
7f930d2c
#include
"userprog/syscall.h"
#include
"userprog/syscall.h"
#include
<stdbool.h>
#include
<stdio.h>
#include
<stdio.h>
#include
<syscall-nr.h>
#include
<syscall-nr.h>
#include
"threads/interrupt.h"
#include
"threads/interrupt.h"
...
@@ -6,16 +7,149 @@
...
@@ -6,16 +7,149 @@
static
void
syscall_handler
(
struct
intr_frame
*
);
static
void
syscall_handler
(
struct
intr_frame
*
);
/*System call initializer*/
void
void
syscall_init
(
void
)
syscall_init
(
void
)
{
{
intr_register_int
(
0x30
,
3
,
INTR_ON
,
syscall_handler
,
"syscall"
);
intr_register_int
(
0x30
,
3
,
INTR_ON
,
syscall_handler
,
"syscall"
);
}
}
/*Handler for system commands.*/
static
void
static
void
syscall_handler
(
struct
intr_frame
*
f
UNUSED
)
syscall_handler
(
struct
intr_frame
*
f
UNUSED
)
{
{
printf
(
"system call!
\n
"
);
/* References: J,Choi(2014), pintos. Available from: https://github.com/wookayin/pintos [accessed on 27/11/22]*/
int
syscall_number
;
ASSERT
(
sizeof
(
syscall_number
)
==
4
);
/*assuming x86*/
/*The system call number is in the 32-bit word at the caller's stack pointer.*/
read
(
f
->
esp
,
&
syscall_number
,
sizeof
(
syscall_number
));
/*Store the esp, which is needed in the page fault handler.*/
thread_current
()
->
current_esp
=
f
->
esp
;
switch
(
syscall_number
)
{
case
SYS_HALT
:
// 0
{
/*Terminate PintOS*/
syscall_halt
();
break
;
}
case
SYS_WAIT
:
// 2
{
tid_t
tid
;
/*Get argument*/
read
(
f
->
esp
+
4
,
&
tid
,
sizeof
(
tid_t
));
/*Wait for child process*/
f
->
eax
=
syscall_wait
(
tid
);
break
;
}
case
SYS_CREATE
:
// 3
{
const
char
*
file_name
;
unsigned
initial_size
;
/*Get file name and size*/
read
(
f
->
esp
+
4
,
&
file_name
,
sizeof
(
file_name
));
read
(
f
->
esp
+
8
,
&
initial_size
,
sizeof
(
initial_size
));
/*Create file*/
f
->
eax
=
syscall_create
(
file_name
,
initial_size
);
break
;
}
case
SYS_REMOVE
:
// 4
{
const
char
*
file_name
;
bool
return_code
;
/*Get file name*/
read
(
f
->
esp
+
4
,
&
file_name
,
sizeof
(
file_name
));
/*Remove file*/
f
->
eax
=
syscall_remove
(
file_name
);
break
;
}
/* Unimplemented system calls */
default:
printf
(
"ERROR: system call ( %d ) has not implemented!
\n
"
,
syscall_number
);
/* Terminate. */
syscall_exit
(
-
1
);
break
;
}
}
/********SYSTEMCALLS********/
/* Halt */
void
syscall_halt
(
void
)
{
shutdown_power_off
();
/* From shutdown.h */
}
/* Exit */
void
syscall_exit
(
int
status
)
{
struct
thread
*
current_process
=
thread_current
();
current_process
->
process_exit_status
=
status
;
printf
(
"%s: exit(%d)
\n
"
,
current_process
->
name
,
status
);
thread_exit
();
thread_exit
();
}
}
/* Wait */
int
syscall_wait
(
tid_t
tid
)
{
return
process_wait
(
tid
);
}
/* Create File */
bool
syscall_create
(
const
char
*
file_name
,
unsigned
initial_size
)
{
bool
if_created
=
false
;
if
(
filesys_create
(
file_name
,
initial_size
)
==
true
){
if_created
=
true
;
}
return
if_created
;
}
/* Remove File */
bool
syscall_remove
(
const
char
*
file_name
)
{
bool
if_removed
=
false
;
if
(
filesys_remove
(
file_name
)
==
true
){
if_removed
=
true
;
}
return
if_removed
;
}
/****OTHER FUNCTIONS****/
static
int
read
(
void
*
src
,
void
*
dst
,
size_t
bytes
)
{
int32_t
value
;
size_t
i
;
for
(
i
=
0
;
i
<
bytes
;
i
++
)
{
value
=
get_user
(
src
+
i
);
if
(
value
==
-
1
)
// segfault or invalid memory access
fail_invalid_access
();
*
(
char
*
)(
dst
+
i
)
=
value
&
0xff
;
}
return
(
int
)
bytes
;
}
/* Reads a byte at user virtual address UADDR.
UADDR must be below PHYS_BASE.
Returns the byte value if successful, -1 if a segfault
occurred. */
static
int
get_user
(
const
uint8_t
*
uaddr
)
{
if
(
!
is_user_vaddr
(
uaddr
))
return
-
1
;
int
result
;
asm
(
"movl $1f, %0; movzbl %1, %0; 1:"
:
"=&a"
(
result
)
:
"m"
(
*
uaddr
));
return
result
;
}
This diff is collapsed.
Click to expand it.
src/userprog/syscall.h
+
12
−
0
View file @
7f930d2c
#ifndef USERPROG_SYSCALL_H
#ifndef USERPROG_SYSCALL_H
#define USERPROG_SYSCALL_H
#define USERPROG_SYSCALL_H
#include
"threads/thread.h"
#include
<stdbool.h>
#include
<stddef.h>
void
syscall_init
(
void
);
void
syscall_init
(
void
);
void
syscall_halt
(
void
);
void
syscall_exit
(
int
status
);
int
syscall_wait
(
tid_t
tid
);
bool
syscall_create
(
const
char
*
file_name
,
unsigned
initial_size
);
bool
syscall_remove
(
const
char
*
file_name
);
static
int
read
(
void
*
src
,
void
*
dst
,
size_t
bytes
);
static
int
get_user
(
const
uint8_t
*
uaddr
);
#endif
/* userprog/syscall.h */
#endif
/* userprog/syscall.h */
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment