Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
Pintos
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Model registry
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
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
Project Purple Stallion
Pintos
Commits
6bb13964
Commit
6bb13964
authored
5 years ago
by
ja3-saxby
Browse files
Options
Downloads
Plain Diff
Merge branch 'feature/argument-parsing' into Alex/6-Implement-populate-stack-process
parents
3a2337ea
ed4402d3
No related branches found
No related tags found
1 merge request
!5
Alex/6 implement populate stack process
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
userprog/argument_parsing.h
+17
-5
17 additions, 5 deletions
userprog/argument_parsing.h
userprog/parse_arguments.c
+25
-2
25 additions, 2 deletions
userprog/parse_arguments.c
userprog/process.c
+21
-14
21 additions, 14 deletions
userprog/process.c
with
63 additions
and
21 deletions
userprog/argument_parsing.h
+
17
−
5
View file @
6bb13964
/*
* argument_parsing.h --prototypes functions required for parsing arguments from
* command line and placing these into the program stack structure.
*
* Authored by Joshua Saxby
*/
#ifndef USERPROG_ARGUMENT_PARSING_H
#ifndef USERPROG_ARGUMENT_PARSING_H
#define USERPROG_ARGUMENT_PARSING_H
#define USERPROG_ARGUMENT_PARSING_H
// some macros for argument length and count limits
// TODO: decide how many arguments we want --is 255 the standard number?
#define USERPROG_ARGV_COUNT 255
// TODO: clarify what a sensible value for this is
#define USERPROG_RAW_ARGV_LENGTH 255
/*
/*
* Given a string containing the command invoking the program `command_line`
* Given a string containing the command invoking the program `command_line`
* and a pointer to an array of C strings (pointer to `char* argv[]`), parse
* and an array of C strings (pointer to `char* argv[]`), parse `command_line`
* `command_line` into individual arguments, populate `argv` with these and
* into individual arguments, populate `argv` with these and return the number
* return the number of arguments that were parsed (this is the value that can
* of arguments that were parsed (this is the value that can be used for `argc`).
* be used for `argc`).
*/
*/
int
parse_arguments
(
const
char
*
command_line
,
char
**
*
argv
);
int
parse_arguments
(
const
char
*
command_line
,
char
**
argv
);
/*
/*
* Given stack pointer `esp`, argument count `argc` and arguments array `argv`,
* Given stack pointer `esp`, argument count `argc` and arguments array `argv`,
...
...
This diff is collapsed.
Click to expand it.
userprog/parse_arguments.c
+
25
−
2
View file @
6bb13964
/*
* parse_arguments.c --implements function for parsing a command-line string
* into the program arguments contained within it.
*
* Authored by Joshua Saxby
*/
#include
<stddef.h>
#include
<string.h>
#include
"userprog/argument_parsing.h"
#include
"userprog/argument_parsing.h"
int
parse_arguments
(
const
char
*
command_line
,
char
***
argv
)
{
int
parse_arguments
(
const
char
*
command_line
,
char
**
argv
)
{
#warning "Implement me"
int
argc
=
0
;
// the state pointer required by strtok_r() for use between calls
char
*
state_pointer
;
// first call to strtok_r() is the only one where string to parse is passed
argv
[
0
]
=
strtok_r
(
command_line
,
" "
,
&
state_pointer
);
argc
++
;
// now, parse token-by-token for any additional arguments
char
*
token
=
strtok_r
(
NULL
,
" "
,
&
state_pointer
);
// continue while still tokens to read and maximum arg count is not reached
while
(
token
!=
NULL
&&
argc
<
USERPROG_ARGV_COUNT
)
{
argv
[
argc
]
=
token
;
argc
++
;
token
=
strtok_r
(
NULL
,
" "
,
&
state_pointer
);
}
return
argc
;
}
}
This diff is collapsed.
Click to expand it.
userprog/process.c
+
21
−
14
View file @
6bb13964
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
#include
<stdio.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<stdlib.h>
#include
<string.h>
#include
<string.h>
#include
"userprog/argument_parsing.h"
#include
"userprog/gdt.h"
#include
"userprog/gdt.h"
#include
"userprog/pagedir.h"
#include
"userprog/pagedir.h"
#include
"userprog/tss.h"
#include
"userprog/tss.h"
...
@@ -20,7 +21,6 @@
...
@@ -20,7 +21,6 @@
static
thread_func
start_process
NO_RETURN
;
static
thread_func
start_process
NO_RETURN
;
static
bool
load
(
const
char
*
cmdline
,
void
(
**
eip
)
(
void
),
void
**
initial_stack_pointer
);
static
bool
load
(
const
char
*
cmdline
,
void
(
**
eip
)
(
void
),
void
**
initial_stack_pointer
);
/* Starts a new thread running a user program loaded by parsing
/* Starts a new thread running a user program loaded by parsing
COMMAND. The new thread may be scheduled (and may even exit)
COMMAND. The new thread may be scheduled (and may even exit)
before process_execute() returns. Returns the new process's
before process_execute() returns. Returns the new process's
...
@@ -29,24 +29,22 @@ tid_t
...
@@ -29,24 +29,22 @@ tid_t
process_execute
(
const
char
*
command
)
process_execute
(
const
char
*
command
)
{
{
char
*
command_copy
;
char
*
command_copy
;
tid_t
tid
;
/* Make a copy of COMMAND.
/* Make a copy of COMMAND.
Otherwise there's a race between the caller and load(). */
Otherwise there's a race between the caller and load(). */
command_copy
=
palloc_get_page
(
0
);
command_copy
=
palloc_get_page
(
0
);
if
(
command_copy
==
NULL
)
if
(
command_copy
==
NULL
)
return
TID_ERROR
;
return
TID_ERROR
;
strlcpy
(
command_copy
,
command
,
PGSIZE
);
strlcpy
(
command_copy
,
command
,
PGSIZE
);
// we need to extract out the filename from the command string
char
*
file_name
;
char
*
save_ptr
;
// this is the save pointer expected by strtok_r()
// file name is the first part of the command-line (space-delimited)
file_name
=
strtok_r
(
command
,
" "
,
&
save_ptr
);
tid_t
tid
;
/* Create a new thread to execute COMMAND. */
/* Create a new thread to execute COMMAND. */
/*
tid
=
thread_create
(
file_name
,
PRI_DEFAULT
,
start_process
,
command_copy
);
* FIXME: right now, COMMAND is assumed to be just the filename on its own
*
* If this is not the case (if the user passed a program name with arguments),
* then loading will fail.
* NOTE: remove this comment block when argument parsing is implemented.
*/
tid
=
thread_create
(
command
,
PRI_DEFAULT
,
start_process
,
command_copy
);
if
(
tid
==
TID_ERROR
)
if
(
tid
==
TID_ERROR
)
palloc_free_page
(
command_copy
);
palloc_free_page
(
command_copy
);
...
@@ -218,7 +216,7 @@ static bool load_segment (struct file *file, off_t ofs, uint8_t *upage,
...
@@ -218,7 +216,7 @@ 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
,
bool
writable
);
bool
writable
);
/* Loads an ELF executable from
FILE_NAME
into the current thread.
/* Loads an ELF executable from
COMMAND
into the current thread.
Stores the executable's entry point into *EIP
Stores the executable's entry point into *EIP
and its initial stack pointer into *initial_stack_pointer.
and its initial stack pointer into *initial_stack_pointer.
Returns true if successful, false otherwise. */
Returns true if successful, false otherwise. */
...
@@ -232,6 +230,14 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer)
...
@@ -232,6 +230,14 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer)
bool
success
=
false
;
bool
success
=
false
;
int
i
;
int
i
;
// extract arguments (including file name)
char
*
argv
[
USERPROG_ARGV_COUNT
];
// copy the command string so we have a separate copy to manipulate
char
command_copy
[
USERPROG_RAW_ARGV_LENGTH
];
strlcpy
(
command_copy
,
cmdline
,
USERPROG_RAW_ARGV_LENGTH
);
int
argc
=
parse_arguments
(
command_copy
,
argv
);
char
*
file_name
=
argv
[
0
];
// file name is always argument 0
/* Allocate and activate page directory. */
/* Allocate and activate page directory. */
t
->
pagedir
=
pagedir_create
();
t
->
pagedir
=
pagedir_create
();
if
(
t
->
pagedir
==
NULL
)
if
(
t
->
pagedir
==
NULL
)
...
@@ -239,7 +245,7 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer)
...
@@ -239,7 +245,7 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer)
process_activate
();
process_activate
();
/* Open executable file. */
/* Open executable file. */
file
=
filesys_open
(
cmdlin
e
);
file
=
filesys_open
(
file_nam
e
);
if
(
file
==
NULL
)
if
(
file
==
NULL
)
{
{
...
@@ -320,7 +326,7 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer)
...
@@ -320,7 +326,7 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer)
}
}
/* Set up stack. */
/* Set up stack. */
if
(
!
setup_stack
(
initial_stack_pointer
))
if
(
!
setup_stack
(
initial_stack_pointer
,
argv
,
argc
))
goto
done
;
goto
done
;
/* Start address. */
/* Start address. */
...
@@ -456,6 +462,7 @@ setup_stack (void **initial_stack_pointer, char **argv, int argc)
...
@@ -456,6 +462,7 @@ setup_stack (void **initial_stack_pointer, char **argv, int argc)
success
=
install_page
(((
uint8_t
*
)
PHYS_BASE
)
-
PGSIZE
,
kpage
,
true
);
success
=
install_page
(((
uint8_t
*
)
PHYS_BASE
)
-
PGSIZE
,
kpage
,
true
);
if
(
success
)
{
if
(
success
)
{
*
initial_stack_pointer
=
PHYS_BASE
-
12
;
*
initial_stack_pointer
=
PHYS_BASE
-
12
;
populate_stack
(
initial_stack_pointer
,
argc
,
argv
);
}
else
}
else
palloc_free_page
(
kpage
);
palloc_free_page
(
kpage
);
}
}
...
...
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