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
6ac63998
Commit
6ac63998
authored
May 19, 2021
by
benkma
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Lab 14 Finished
parent
5e25224b
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
137 additions
and
45 deletions
+137
-45
k-alloc.cc
k-alloc.cc
+3
-3
k-cpu.cc
k-cpu.cc
+2
-7
k-proc.cc
k-proc.cc
+3
-1
kernel.cc
kernel.cc
+112
-32
kernel.hh
kernel.hh
+11
-1
lib.hh
lib.hh
+1
-0
u-lib.hh
u-lib.hh
+5
-1
No files found.
k-alloc.cc
View file @
6ac63998
...
...
@@ -128,9 +128,9 @@ void* kalloc(size_t sz) {
asan_mark_memory
(
ka2pa
(
ptr
),
PAGESIZE
,
false
);
// initialize to `int3`
memset
(
ptr
,
0xCC
,
PAGESIZE
);
log_printf
(
"kalloc of order %d returning frame %d
\n
"
,
pBlock
->
order
,
pBlock
->
frameNumber
());
//
log_printf("kalloc of order %d returning frame %d\n", pBlock->order, pBlock->frameNumber());
}
else
{
log_printf
(
"kalloc of order %d fail
led
\n
"
,
order
);
//log_printf("kalloc of order %d fai
led\n", order);
}
return
ptr
;
}
...
...
@@ -180,7 +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
);
//
log_printf("kfree of block starting at frame %d with order %d\n",pBlock->frameNumber(),pBlock->order);
auto
irqs
=
mem_lock
.
lock
();
...
...
k-cpu.cc
View file @
6ac63998
...
...
@@ -91,13 +91,6 @@ 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
...
...
@@ -119,6 +112,8 @@ void cpustate::schedule(proc* yielding_from) {
// no need to skip `current_` if no other runnable procs
yielding_from
=
nullptr
;
}
// run `current_`
set_pagetable
(
current_
->
pagetable_
);
...
...
k-proc.cc
View file @
6ac63998
...
...
@@ -13,11 +13,13 @@ proc::proc() {
}
proc
::~
proc
()
{
log_printf
(
"proc::~proc
\n
"
);
//
log_printf("proc::~proc\n");
if
(
!
pagetable_
){
return
;
}
int
pid
=
id_
;
assert
(
!
children_link_
.
is_linked
());
assert
(
!
exited_link_
.
is_linked
());
{
spinlock_guard
guard
(
ptable_lock
);
ptable
[
pid
]
=
nullptr
;
...
...
kernel.cc
View file @
6ac63998
...
...
@@ -7,6 +7,10 @@
#include "k-vmiter.hh"
#include "obj/k-firstprocess.h"
// Debugging Information
#pragma GCC push_options
#pragma GCC optimize("O0")
// kernel.cc
//
// This is the kernel.
...
...
@@ -18,11 +22,13 @@ std::atomic<unsigned long> ticks;
std
::
atomic
<
int
>
kdisplay
;
static
void
tick
();
static
proc
*
create_init_process
();
static
void
create_init_process
();
static
void
boot_process_start
(
pid_t
pid
,
const
char
*
program_name
);
void
find_mapped_memory
();
const
pid_t
INIT_PID
=
1
;
proc
*
initProc
=
nullptr
;
spinlock
children_lock
;
// global lock for manupulating children lists
// kernel_start(command)
...
...
@@ -39,31 +45,33 @@ void kernel_start(const char* command) {
ptable
[
i
]
=
nullptr
;
}
// Start Init Process
proc
*
initProc
=
create_init_process
();
// start first process
create_init_process
();
boot_process_start
(
2
,
CHICKADEE_FIRST_PROCESS
);
cpus
[
0
].
schedule
(
nullptr
);
assert
(
false
);
}
void
init_process
()
{
// run the init process
while
(
true
)
{
initProc
->
syscall_waitpid
(
0
,
W_NOHANG
);
initProc
->
yield
();
}
assert
(
false
);
}
proc
*
create_init_process
()
{
proc
*
initProc
=
knew
<
proc
>
();
void
create_init_process
()
{
initProc
=
knew
<
proc
>
();
assert
(
initProc
);
initProc
->
init_
user
(
INIT_PID
,
early_pagetable
);
initProc
->
init_
kernel
(
INIT_PID
,
init_process
);
initProc
->
ppid_
=
INIT_PID
;
{
spinlock_guard
guard
(
ptable_lock
);
assert
(
!
ptable
[
INIT_PID
]);
ptable
[
INIT_PID
]
=
initProc
;
}
return
initProc
;
cpus
[
INIT_PID
%
ncpu
].
enqueue
(
initProc
)
;
}
// boot_process_start(pid, name)
...
...
@@ -91,11 +99,6 @@ 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)
{
...
...
@@ -104,6 +107,16 @@ void boot_process_start(pid_t pid, const char* name) {
ptable
[
pid
]
=
p
;
}
// add as child of init process
{
spinlock_guard
guard
(
children_lock
);
initProc
->
children_
.
push_back
(
p
);
}
// map console to initial process
int
error_code
=
p
->
syscall_map_console
(
ktext2pa
(
console
));
assert
(
!
error_code
);
// add to run queue
cpus
[
pid
%
ncpu
].
enqueue
(
p
);
log_printf
(
"
\n
End boot_process_start()"
);
...
...
@@ -270,12 +283,15 @@ uintptr_t proc::syscall(regstate* regs) {
return
syscall_map_console
(
regs
->
reg_rdi
);
case
SYSCALL_EXIT
:
syscall_exit
(
regs
->
reg_rdi
);
syscall_exit
(
(
int32_t
)
regs
->
reg_rdi
);
assert
(
false
);
// will not be reached
case
SYSCALL_SLEEP
:
return
syscall_sleep
(
regs
->
reg_rdi
);
case
SYSCALL_WAITPID
:
return
syscall_waitpid
((
pid_t
)
regs
->
reg_rdi
,
(
int
)
regs
->
reg_rsi
);
default:
// no such system call
log_printf
(
"%d: no such system call %u
\n
"
,
id_
,
regs
->
reg_rax
);
...
...
@@ -283,21 +299,83 @@ uintptr_t proc::syscall(regstate* regs) {
}
}
// Debugging Information
#pragma GCC push_options
#pragma GCC optimize("O0")
int
proc
::
syscall_exit
(
uint64_t
exitCode
)
{
uintptr_t
proc
::
syscall_waitpid
(
pid_t
childPid
,
int
options
)
{
proc
*
child
=
nullptr
;
if
(
options
&
W_NOHANG
)
{
spinlock_guard
guard1
(
ptable_lock
);
spinlock_guard
guard2
(
children_lock
);
if
(
this
->
exited_
.
empty
())
{
if
(
this
->
children_
.
empty
())
{
return
E_CHILD
&
0xffffffff
;
}
else
{
return
E_AGAIN
&
0xffffffff
;
}
}
if
(
childPid
)
{
child
=
ptable
[
childPid
];
// if there is no such child or it is not mine, return an error
if
(
!
child
||
child
->
ppid_
!=
id_
){
return
E_CHILD
&
0xffffffff
;
}
if
(
child
->
pstate_
!=
ps_exit
)
{
return
E_AGAIN
&
0xffffffff
;
}
exited_
.
erase
(
child
);
}
else
{
child
=
this
->
exited_
.
pop_front
();
}
}
else
{
while
(
true
)
{
{
spinlock_guard
guard1
(
ptable_lock
);
spinlock_guard
guard2
(
children_lock
);
if
(
this
->
exited_
.
empty
()
&&
this
->
children_
.
empty
()){
return
E_CHILD
&
0xffffffff
;
}
if
(
childPid
)
{
child
=
ptable
[
childPid
];
if
(
!
child
||
child
->
ppid_
!=
id_
)
{
return
E_CHILD
&
0xffffffff
;
}
if
(
child
->
pstate_
==
ps_exit
){
exited_
.
erase
(
child
);
break
;
}
}
else
{
child
=
this
->
exited_
.
pop_front
();
if
(
child
)
{
break
;
}
}
}
yield
();
}
}
assert
(
child
);
uintptr_t
result
=
((
int64_t
)
child
->
exitStatus_
<<
32
)
|
(
child
->
id_
&
0xffffffff
);
delete
child
;
return
result
;
}
int
proc
::
syscall_exit
(
int32_t
exitCode
)
{
this
->
exitStatus_
=
exitCode
;
set_pagetable
(
early_pagetable
);
pstate_
=
ps_exit
;
{
spinlock_guard
guard
(
ptable_lock
);
for
(
int
i
=
1
;
i
<
NPROC
;
++
i
)
{
proc
*
otherProc
=
ptable
[
i
];
if
(
otherProc
&&
otherProc
->
ppid_
==
id_
)
{
otherProc
->
ppid_
=
INIT_PID
;
}
{
// do child cleanup
spinlock_guard
guard1
(
ptable_lock
);
spinlock_guard
guard2
(
children_lock
);
proc
*
child
;
while
((
child
=
this
->
children_
.
pop_front
())){
child
->
ppid_
=
INIT_PID
;
initProc
->
children_
.
push_back
(
child
);
}
while
((
child
=
this
->
exited_
.
pop_front
())){
child
->
ppid_
=
INIT_PID
;
initProc
->
exited_
.
push_back
(
child
);
}
ptable
[
ppid_
]
->
children_
.
erase
(
this
);
ptable
[
ppid_
]
->
exited_
.
push_back
(
this
);
}
yield_noreturn
();
}
...
...
@@ -320,13 +398,13 @@ int proc::syscall_map_console(uintptr_t addr) {
return
0
;
}
#pragma GCC pop_options
// proc::syscall_fork(regs)
// Handle fork system call.
int
proc
::
syscall_fork
(
regstate
*
regs
)
{
log_printf
(
"
\n
Begin syscall_fork()"
);
//
log_printf("\nBegin syscall_fork()");
pid_t
pid
=
0
;
proc
*
child
=
knew
<
proc
>
();
if
(
!
child
){
...
...
@@ -405,10 +483,15 @@ int proc::syscall_fork(regstate* regs) {
// Arranging for 0 to be returned to the child process
child
->
regs_
->
reg_rax
=
0
;
{
spinlock_guard
guard
(
children_lock
);
this
->
children_
.
push_back
(
child
);
}
// Add to run queue
cpus
[
pid
%
ncpu
].
enqueue
(
child
);
log_printf
(
"End syscall_fork()"
);
//
log_printf("End syscall_fork()");
return
pid
;
}
...
...
@@ -600,9 +683,6 @@ void tick() {
* to one address, can we find the value when we read from the other address?
* Disable optimizations so we can step through this in a debugger.
*/
#pragma GCC push_options
#pragma GCC optimize ("O0")
void
find_mapped_memory
()
{
long
lowCanonical
=
0x0
;
long
highCanonical
=
0xffff800000000000
;
...
...
kernel.hh
View file @
6ac63998
...
...
@@ -43,6 +43,15 @@ struct __attribute__((aligned(4096))) proc {
list_links
runq_links_
;
// manages children list
list_links
children_link_
;
list
<
proc
,
&
proc
::
children_link_
>
children_
;
// manage exit status and list
int32_t
exitStatus_
;
list_links
exited_link_
;
list
<
proc
,
&
proc
::
exited_link_
>
exited_
;
proc
();
~
proc
();
...
...
@@ -69,7 +78,8 @@ struct __attribute__((aligned(4096))) proc {
int
syscall_fork
(
regstate
*
regs
);
int
syscall_map_console
(
uintptr_t
addr
);
int
syscall_sleep
(
uint64_t
msec
);
int
syscall_exit
(
uint64_t
exitCode
);
int
syscall_exit
(
int32_t
exitCode
);
uintptr_t
syscall_waitpid
(
pid_t
childPid
,
int
options
);
uintptr_t
syscall_read
(
regstate
*
reg
);
uintptr_t
syscall_write
(
regstate
*
reg
);
...
...
lib.hh
View file @
6ac63998
...
...
@@ -273,6 +273,7 @@ struct bitset_view {
#define SYSCALL_MAP_CONSOLE 128
#define SYSCALL_SLEEP 129
#define SYSCALL_GET_PPID 130
#define SYSCALL_WAITPID 131
// System call error return values
...
...
u-lib.hh
View file @
6ac63998
...
...
@@ -148,7 +148,11 @@ inline pid_t sys_getppid() {
// waits for any child. If `options == W_NOHANG`, returns immediately.
inline
pid_t
sys_waitpid
(
pid_t
pid
,
int
*
status
=
nullptr
,
int
options
=
0
)
{
return
E_NOSYS
;
uintptr_t
result
=
make_syscall
(
SYSCALL_WAITPID
,
(
uintptr_t
)
pid
,
(
uintptr_t
)
options
);
if
(
status
){
*
status
=
(
result
>>
32
)
&
0xffffffff
;
}
return
result
&
0xffffffff
;
}
// sys_read(fd, buf, sz)
...
...
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