Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
chickadee
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Matija Benko
chickadee
Commits
eddbc88e
Commit
eddbc88e
authored
May 05, 2021
by
benkma
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finished Lab 11
parent
1233725a
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
112 additions
and
23 deletions
+112
-23
k-alloc.cc
k-alloc.cc
+2
-0
k-cpu.cc
k-cpu.cc
+7
-0
k-memviewer.cc
k-memviewer.cc
+1
-1
k-proc.cc
k-proc.cc
+24
-0
k-vmiter.hh
k-vmiter.hh
+6
-6
kernel.cc
kernel.cc
+59
-12
kernel.hh
kernel.hh
+4
-2
p-allocator.cc
p-allocator.cc
+2
-2
p-testkalloc.cc
p-testkalloc.cc
+7
-0
No files found.
k-alloc.cc
View file @
eddbc88e
...
...
@@ -180,6 +180,7 @@ void kfree(void* ptr) {
block
*
pBlock
=
block
::
blockAtKernelAddress
(
ptr
);
assert
(
!
(
pBlock
->
isFree
));
assert
(
pBlock
->
ka
==
ptr
);
log_printf
(
"kfree of block starting at frame %d with order %d
\n
"
,
pBlock
->
frameNumber
(),
pBlock
->
order
);
auto
irqs
=
mem_lock
.
lock
();
...
...
@@ -188,6 +189,7 @@ void kfree(void* ptr) {
pBlock
->
cloalesce
();
mem_lock
.
unlock
(
irqs
);
}
void
block
::
cloalesce
()
{
...
...
k-cpu.cc
View file @
eddbc88e
...
...
@@ -91,6 +91,13 @@ void cpustate::schedule(proc* yielding_from) {
// increment schedule counter
++
nschedule_
;
if
(
yielding_from
->
pstate_
==
proc
::
ps_exit
)
{
log_printf
(
"
\n
Start exit for PID %d
\n
"
,
yielding_from
->
id_
);
delete
yielding_from
;
yielding_from
=
idle_task_
;
log_printf
(
"End Process exit
\n\n
"
);
}
// find a runnable process
while
(
!
current_
||
current_
->
pstate_
!=
proc
::
ps_runnable
...
...
k-memviewer.cc
View file @
eddbc88e
...
...
@@ -97,7 +97,7 @@ void memusage::refresh() {
auto
irqs
=
p
->
lock_pagetable_read
();
if
(
p
->
pagetable_
&&
p
->
pagetable_
!=
early_pagetable
)
{
for
(
ptiter
it
(
p
);
it
.
low
();
it
.
next
())
{
for
(
ptiter
it
(
p
,
pid
);
it
.
low
();
it
.
next
())
{
mark
(
it
.
pa
(),
f_kernel
|
f_process
(
pid
));
}
mark
(
ka2pa
(
p
->
pagetable_
),
f_kernel
|
f_process
(
pid
));
...
...
k-proc.cc
View file @
eddbc88e
...
...
@@ -12,6 +12,30 @@ spinlock ptable_lock; // protects `ptable`
proc
::
proc
()
{
}
proc
::~
proc
()
{
log_printf
(
"proc::~proc
\n
"
);
if
(
!
pagetable_
){
return
;
}
int
pid
=
id_
;
{
spinlock_guard
guard
(
ptable_lock
);
ptable
[
pid
]
=
nullptr
;
}
for
(
vmiter
parentIterator
(
this
);
parentIterator
.
low
();
parentIterator
.
next
())
{
if
(
parentIterator
.
user
())
{
auto
range
=
physical_ranges
.
find
((
uintptr_t
)
parentIterator
.
pa
());
bool
isConsole
=
range
->
type
()
==
mem_console
;
if
(
!
isConsole
)
{
parentIterator
.
kfree_page
();
}
}
}
for
(
ptiter
it
(
pagetable_
,
0
);
it
.
low
();
it
.
next
())
{
it
.
kfree_ptp
();
// `kfree(ptp())` + clear mapping
}
delete
pagetable_
;
}
// proc::init_user(pid, pt)
// Initialize this `proc` as a new runnable user process with PID `pid`
...
...
k-vmiter.hh
View file @
eddbc88e
...
...
@@ -104,8 +104,8 @@ class vmiter {
class
ptiter
{
public:
// Initialize a physical iterator for `pt` with initial virtual address 0
inline
ptiter
(
x86_64_pagetable
*
pt
);
inline
ptiter
(
const
proc
*
p
);
inline
ptiter
(
x86_64_pagetable
*
pt
,
uintptr_t
va
);
inline
ptiter
(
const
proc
*
p
,
uintptr_t
va
);
// Return true once `ptiter` has iterated over all page table pages
// (not including the top-level page table page)
...
...
@@ -235,12 +235,12 @@ inline void vmiter::kfree_page() {
*
pep_
=
0
;
}
inline
ptiter
::
ptiter
(
x86_64_pagetable
*
pt
)
inline
ptiter
::
ptiter
(
x86_64_pagetable
*
pt
,
uintptr_t
va
)
:
pt_
(
pt
)
{
go
(
0
);
go
(
va
);
}
inline
ptiter
::
ptiter
(
const
proc
*
p
)
:
ptiter
(
p
->
pagetable_
)
{
inline
ptiter
::
ptiter
(
const
proc
*
p
,
uintptr_t
va
)
:
ptiter
(
p
->
pagetable_
,
va
)
{
}
inline
uintptr_t
ptiter
::
va
()
const
{
return
va_
&
~
pageoffmask
(
level_
);
...
...
kernel.cc
View file @
eddbc88e
...
...
@@ -51,6 +51,7 @@ void kernel_start(const char* command) {
// Only called at initial boot time.
void
boot_process_start
(
pid_t
pid
,
const
char
*
name
)
{
log_printf
(
"
\n
Begin boot_process_start()
\n
"
);
// look up process image in initfs
memfile_loader
ld
(
memfile
::
initfs_lookup
(
name
),
kalloc_pagetable
());
assert
(
ld
.
memfile_
&&
ld
.
pagetable_
);
...
...
@@ -67,6 +68,11 @@ void boot_process_start(pid_t pid, const char* name) {
vmiter
(
p
,
MEMSIZE_VIRTUAL
-
PAGESIZE
).
map
(
stkpg
,
PTE_PWU
);
p
->
regs_
->
reg_rsp
=
MEMSIZE_VIRTUAL
;
// map console to initial process
int
error_code
=
p
->
syscall_map_console
(
ktext2pa
(
console
));
assert
(
!
error_code
);
// add to process table (requires lock in case another CPU is already
// running processes)
{
...
...
@@ -77,6 +83,7 @@ void boot_process_start(pid_t pid, const char* name) {
// add to run queue
cpus
[
pid
%
ncpu
].
enqueue
(
p
);
log_printf
(
"
\n
End boot_process_start()"
);
}
...
...
@@ -234,7 +241,14 @@ uintptr_t proc::syscall(regstate* regs) {
return
bufcache
::
get
().
sync
(
drop
);
}
case
SYSCALL_MAP_CONSOLE
:
return
syscall_map_console
(
regs
);
return
syscall_map_console
(
regs
->
reg_rdi
);
case
SYSCALL_EXIT
:
set_pagetable
(
early_pagetable
);
pstate_
=
ps_exit
;
yield_noreturn
();
assert
(
false
);
// will not be reached
default:
// no such system call
log_printf
(
"%d: no such system call %u
\n
"
,
id_
,
regs
->
reg_rax
);
...
...
@@ -245,8 +259,7 @@ uintptr_t proc::syscall(regstate* regs) {
// Debugging Information
#pragma GCC push_options
#pragma GCC optimize("O0")
int
proc
::
syscall_map_console
(
regstate
*
regs
)
{
uintptr_t
addr
=
regs
->
reg_rdi
;
int
proc
::
syscall_map_console
(
uintptr_t
addr
)
{
if
(
addr
%
PAGESIZE
||
addr
>
VA_LOWMAX
)
{
return
E_INVAL
;
}
...
...
@@ -260,11 +273,13 @@ int proc::syscall_map_console(regstate* regs) {
// Handle fork system call.
int
proc
::
syscall_fork
(
regstate
*
regs
)
{
log_printf
(
"
\n
Begin syscall_fork()"
);
pid_t
pid
=
0
;
proc
*
child
=
knew
<
proc
>
();
x86_64_pagetable
*
pt
=
kalloc_pagetable
();
assert
(
child
);
if
(
!
child
){
return
E_NOSYS
;
}
{
spinlock_guard
guard
(
ptable_lock
);
for
(
int
i
=
1
;
i
<
NPROC
;
++
i
)
{
...
...
@@ -275,29 +290,60 @@ int proc::syscall_fork(regstate* regs) {
}
}
}
assert
(
pid
);
if
(
!
pid
)
{
delete
child
;
return
E_NOSYS
;
}
if
(
!
pt
)
{
{
spinlock_guard
guard
(
ptable_lock
);
ptable
[
pid
]
=
nullptr
;
}
delete
child
;
return
E_NOSYS
;
}
child
->
init_user
(
pid
,
pt
);
// Copy user-accessible Memory
bool
memError
=
false
;
for
(
vmiter
parentIterator
(
this
);
parentIterator
.
low
();
parentIterator
.
next
())
{
if
(
parentIterator
.
user
())
{
vmiter
childIterator
=
vmiter
(
pt
,
parentIterator
.
va
());
auto
range
=
physical_ranges
.
find
((
uintptr_t
)
parentIterator
.
pa
());
if
(
range
->
type
()
==
mem_console
)
{
childIterator
.
map
(
parentIterator
.
pa
(),
parentIterator
.
perm
());
bool
isConsole
=
range
->
type
()
==
mem_console
;
if
(
isConsole
)
{
int
result
=
childIterator
.
try_map
(
parentIterator
.
pa
(),
parentIterator
.
perm
());
if
(
result
)
{
memError
=
true
;
break
;
}
}
else
{
// Allocate a new frame for the child
void
*
newFrame
=
kalloc
(
PAGESIZE
);
assert
(
newFrame
);
if
(
!
newFrame
){
memError
=
true
;
break
;
}
// Copy the parent's page contents to the child's page
memcpy
(
newFrame
,
parentIterator
.
kptr
(),
PAGESIZE
);
// Map the child's virtual address to the new frame with the proper permission
childIterator
.
map
(
ka2pa
(
newFrame
),
parentIterator
.
perm
());
int
result
=
childIterator
.
try_map
(
ka2pa
(
newFrame
),
parentIterator
.
perm
());
if
(
result
)
{
memError
=
true
;
break
;
}
}
}
}
if
(
memError
)
{
{
spinlock_guard
guard
(
ptable_lock
);
ptable
[
pid
]
=
nullptr
;
}
delete
child
;
return
E_NOSYS
;
}
// Copy Registers
memcpy
(
child
->
regs_
,
regs
,
sizeof
(
regstate
));
...
...
@@ -308,6 +354,7 @@ int proc::syscall_fork(regstate* regs) {
// Add to run queue
cpus
[
pid
%
ncpu
].
enqueue
(
child
);
log_printf
(
"End syscall_fork()"
);
return
pid
;
}
...
...
kernel.hh
View file @
eddbc88e
...
...
@@ -24,7 +24,7 @@ struct elf_program;
// Process descriptor type
struct
__attribute__
((
aligned
(
4096
)))
proc
{
enum
pstate_t
{
ps_blank
=
0
,
ps_runnable
=
PROC_RUNNABLE
,
ps_broken
ps_blank
=
0
,
ps_runnable
=
PROC_RUNNABLE
,
ps_broken
,
ps_exit
};
// These four members must come first:
...
...
@@ -43,6 +43,7 @@ struct __attribute__((aligned(4096))) proc {
proc
();
~
proc
();
NO_COPY_OR_ASSIGN
(
proc
);
inline
bool
contains
(
uintptr_t
addr
)
const
;
...
...
@@ -64,6 +65,7 @@ struct __attribute__((aligned(4096))) proc {
inline
bool
resumable
()
const
;
int
syscall_fork
(
regstate
*
regs
);
int
syscall_map_console
(
uintptr_t
addr
);
uintptr_t
syscall_read
(
regstate
*
reg
);
uintptr_t
syscall_write
(
regstate
*
reg
);
...
...
@@ -74,7 +76,7 @@ struct __attribute__((aligned(4096))) proc {
private:
static
int
load_segment
(
const
elf_program
&
ph
,
proc_loader
&
ld
);
int
syscall_map_console
(
regstate
*
reg
);
};
#define NPROC 16
...
...
p-allocator.cc
View file @
eddbc88e
...
...
@@ -13,8 +13,8 @@ uint8_t* stack_bottom;
void
process_main
()
{
sys_kdisplay
(
KDISPLAY_MEMVIEWER
);
//
int error_code = sys_map_console(console);
//assert(!error_code);
//
Console assignment:
/*console_printf(0x5000, "Hello Professor Foster,\n");
console_printf(0x5000, "We are in week four of the quarter and I'm learning a lot of\n");
console_printf(0x5000, "C++ programming in OS!\n");
...
...
p-testkalloc.cc
View file @
eddbc88e
...
...
@@ -7,5 +7,12 @@ void process_main() {
// Note that panic() will prouce a page fault if there is no console
// (https://github.com/CS161/chickadee/issues/14)
int
pid
=
sys_fork
();
if
(
pid
){
sys_exit
(
0
);
}
while
(
true
)
{
sys_yield
();
}
panic
(
"testkalloc not implemented!
\n
"
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment