Skip to content
GitLab
Explore
Projects
Groups
Topics
Snippets
Projects
Groups
Topics
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
educg-net-28668-2608132
project2608132-3798
Commits
371b3931
Commit
371b3931
authored
4 months ago
by
N1I1
Browse files
Options
Download
Patches
Plain Diff
feat: proc create
parent
9391d089
main
docs
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
kernel/include/proc.h
+67
-0
kernel/include/proc.h
kernel/proc.c
+206
-0
kernel/proc.c
kernel/switch.S
+50
-0
kernel/switch.S
with
323 additions
and
0 deletions
+323
-0
kernel/include/proc.h
0 → 100644
+
67
−
0
View file @
371b3931
#ifndef PROC_H
#define PROC_H
#include
"type.h"
#include
"riscv.h"
#include
"vm.h"
#define MAX_PROC_NUM 16
#define DEFAULT_PRIORITY 1
#define USER_STACK_TOP 0x7FFFFFFFF000UL
#define USER_STACK_SIZE PAGE_SIZE
#define USER_STACK_BASE (USER_STACK_TOP - USER_STACK_SIZE)
// jsut for test, may be changed
#define USER_CODE_BASE 0x1000000UL
#define USER_HEAP_BASE 0x2000000UL
#define PROC_KERNEL_STACK_BASE 0x90000000UL
#define KERNEL_STACK_SIZE PAGE_SIZE
#define KERNEL_STACK_PAGES 4
#define KERNEL_STACK_SHIFT 14
typedef
struct
Context
{
uint64_t
gpr
[
31
];
uint64_t
sepc
;
uint64_t
sstatus
;
uint64_t
satp
;
uint64_t
scause
;
}
Context
;
typedef
enum
proc_state
{
PROC_UNUSED
,
PROC_EMBRYO
,
PROC_SLEEPING
,
PROC_RUNNABLE
,
PROC_RUNNING
,
PROC_ZOMBIE
,
}
State
;
typedef
struct
ProcessControlBlock
{
uint64_t
*
stack
;
uint64_t
*
kstack
;
uint64_t
pid
;
State
state
;
Context
*
context
;
struct
ProcessControlBlock
*
parent
;
uint8_t
priority
;
pagetable_t
*
pagetable
;
void
*
chan
;
// channel for sleep
uint64_t
kstack_va
;
}
PCB
;
void
init_proc
();
PCB
*
alloc_pcb
();
void
yield
();
void
fork
();
void
exit
();
void
wait
();
void
sleep
(
void
*
chan
);
void
wakeup
(
void
*
chan
);
void
schedule
();
int
alloc_pid
();
void
switch_context
(
Context
**
old_ctx
,
Context
*
new_ctx
);
#endif
This diff is collapsed.
Click to expand it.
kernel/proc.c
0 → 100644
+
206
−
0
View file @
371b3931
#include
"include/proc.h"
#include
"include/page.h"
#include
"include/string.h"
#include
"include/kmallo.h"
#include
"include/printk.h"
static
int
next_pid
=
1
;
static
PCB
proc_table
[
MAX_PROC_NUM
];
static
PCB
*
current
=
NULL
;
inline
int
alloc_pid
()
{
return
next_pid
++
;
}
void
init_proc
()
{
for
(
int
i
=
0
;
i
<
MAX_PROC_NUM
;
i
++
)
{
proc_table
[
i
].
state
=
PROC_UNUSED
;
proc_table
[
i
].
pid
=
0
;
}
}
PCB
*
alloc_pcb
()
{
for
(
int
i
=
0
;
i
<
MAX_PROC_NUM
;
i
++
)
{
if
(
proc_table
[
i
].
state
==
PROC_UNUSED
)
{
PCB
*
p
=
&
proc_table
[
i
];
memset
(
p
,
0
,
sizeof
(
PCB
));
p
->
state
=
PROC_EMBRYO
;
p
->
pid
=
alloc_pid
();
p
->
priority
=
DEFAULT_PRIORITY
;
p
->
kstack
=
(
uint64_t
*
)
alloc_page
();
if
(
!
p
->
kstack
)
{
goto
fail
;
}
p
->
stack
=
(
uint64_t
*
)
alloc_page
();
if
(
!
p
->
stack
)
{
goto
fail
;
}
p
->
kstack_va
=
PROC_KERNEL_STACK_BASE
-
(
i
<<
KERNEL_STACK_SHIFT
);
if
(
p
->
kstack_va
<=
(
uint64_t
)
p
->
kstack
)
{
goto
fail
;
}
p
->
pagetable
=
create_pagetable
();
if
(
!
p
->
pagetable
)
{
#ifdef DEBUG
printk
(
" Failed to create page table!
\n
"
);
#endif
goto
fail
;
}
if
(
map_page
(
p
->
pagetable
,
USER_STACK_BASE
,
(
uint64_t
)
p
->
stack
,
PTE_R
|
PTE_W
|
PTE_U
)
<
0
)
{
#ifdef DEBUG
printk
(
" Failed to map user stack!
\n
"
);
#endif
goto
fail
;
}
// map kernel stack
if
(
map_page
(
p
->
pagetable
,
p
->
kstack_va
,
(
uint64_t
)
p
->
kstack
,
PTE_R
|
PTE_W
)
<
0
)
{
#ifdef DEBUG
printk
(
" Failed to map kernel stack!
\n
"
);
#endif
goto
fail
;
}
p
->
context
=
(
Context
*
)(
p
->
kstack_va
+
KERNEL_STACK_SIZE
-
sizeof
(
Context
));
memset
((
void
*
)
p
->
kstack
,
0
,
PAGE_SIZE
);
return
p
;
fail:
if
(
p
->
stack
)
free_page
(
p
->
stack
);
if
(
p
->
kstack
)
free_page
(
p
->
kstack
);
if
(
p
->
pagetable
)
free_pagetable
(
p
->
pagetable
,
2
);
memset
(
p
,
0
,
sizeof
(
PCB
));
p
->
state
=
PROC_UNUSED
;
#ifdef DEBUG
printk
(
"PCB %d allocation failed
\n
"
,
i
);
#endif
return
NULL
;
}
}
#ifdef DEBUG
printk
(
"No free PCB available!
\n
"
);
#endif
return
NULL
;
}
void
schedule
()
{
PCB
*
prev
=
current
;
PCB
*
next
=
NULL
;
while
(
1
)
{
for
(
int
i
=
0
;
i
<
MAX_PROC_NUM
;
i
++
)
{
if
(
proc_table
[
i
].
state
==
PROC_RUNNABLE
)
{
next
=
&
proc_table
[
i
];
break
;
}
}
if
(
next
)
{
next
->
state
=
PROC_RUNNING
;
if
(
prev
!=
next
)
{
Context
**
old_ctx
=
prev
?
&
prev
->
context
:
NULL
;
current
=
next
;
switch_context
(
old_ctx
,
next
->
context
);
}
break
;
}
}
}
void
yield
()
{
if
(
current
)
{
current
->
state
=
PROC_RUNNABLE
;
schedule
();
}
}
void
exit
()
{
if
(
current
)
{
current
->
state
=
PROC_ZOMBIE
;
free_pagetable
(
current
->
pagetable
,
2
);
free_page
(
current
->
stack
);
free_page
(
current
->
kstack
);
// TODO: clean page table
schedule
();
}
}
void
fork
()
{
PCB
*
child
=
alloc_pcb
();
if
(
!
child
)
return
;
if
(
current
)
{
child
->
parent
=
current
;
child
->
chan
=
0
;
child
->
pagetable
=
copy_pagetable
(
current
->
pagetable
);
if
(
!
child
->
pagetable
)
{
free_page
(
child
->
stack
);
free_page
(
child
->
kstack
);
child
->
state
=
PROC_UNUSED
;
return
;
}
if
(
map_page
(
child
->
pagetable
,
USER_STACK_BASE
,
(
uint64_t
)
child
->
stack
,
PTE_R
|
PTE_W
|
PTE_U
)
<
0
)
{
free_pagetable
(
child
->
pagetable
,
2
);
free_page
(
child
->
stack
);
free_page
(
child
->
kstack
);
child
->
state
=
PROC_UNUSED
;
return
;
}
memcpy
(
child
->
stack
,
current
->
stack
,
PAGE_SIZE
);
*
(
child
->
context
)
=
*
(
current
->
context
);
child
->
state
=
PROC_RUNNABLE
;
}
}
void
wait
()
{
if
(
!
current
)
return
;
for
(
int
i
=
0
;
i
<
MAX_PROC_NUM
;
i
++
)
{
if
(
proc_table
[
i
].
parent
==
current
&&
proc_table
[
i
].
state
==
PROC_ZOMBIE
)
{
proc_table
[
i
].
state
=
PROC_UNUSED
;
return
;
}
}
current
->
state
=
PROC_SLEEPING
;
schedule
();
}
void
sleep
(
void
*
chan
)
{
if
(
!
current
)
return
;
current
->
chan
=
chan
;
current
->
state
=
PROC_SLEEPING
;
schedule
();
}
void
wakeup
(
void
*
chan
)
{
for
(
int
i
=
0
;
i
<
MAX_PROC_NUM
;
i
++
)
{
if
(
proc_table
[
i
].
state
==
PROC_SLEEPING
&&
proc_table
[
i
].
chan
==
chan
)
{
proc_table
[
i
].
state
=
PROC_RUNNABLE
;
proc_table
[
i
].
chan
=
0
;
}
}
}
This diff is collapsed.
Click to expand it.
kernel/switch.S
0 → 100644
+
50
−
0
View file @
371b3931
#define MAP(x, f) f(x)
#define concat_temp(a, b) a ## b
#define concat(a, b) concat_temp(a, b)
#define REGS(f) \
f
(1)
f
(
3
)
f
(
4
)
f
(
5
)
f
(
6
)
f
(
7
)
f
(
8
)
\
f
(9)
f
(
10
)
f
(
11
)
f
(
12
)
f
(
13
)
f
(
14
)
f
(
15
)
f
(
16
)
\
f
(17)
f
(
18
)
f
(
19
)
f
(
20
)
f
(
21
)
f
(
22
)
f
(
23
)
f
(
24
)
\
f
(25)
f
(
26
)
f
(
27
)
f
(
28
)
f
(
29
)
f
(
30
)
f
(
31
)
#define SAVE(n) sd concat(x, n), ((n-1)*8)(sp);
#define RESTORE(n) ld concat(x, n), ((n-1)*8)(sp);
.
section
.
text
.
global
switch_context
#
void
switch_context
(
Context
**
old_ctx
,
Context
*
new_ctx
)
#
a0
:
old_ctx
#
a1
:
new_ctx
switch_context
:
addi
sp
,
sp
,
-
280
MAP
(
SAVE
,
REGS
)
//
csrr
t0
,
sepc
sd
t0
,
31
*
8
(
sp
)
csrr
t0
,
sstatus
sd
t0
,
32
*
8
(
sp
)
csrr
t0
,
satp
sd
t0
,
33
*
8
(
sp
)
csrr
t0
,
scause
sd
t0
,
34
*
8
(
sp
)
sd
sp
,
(
a0
)
mv
sp
,
a1
ld
t0
,
31
*
8
(
sp
)
csrw
sepc
,
t0
ld
t0
,
32
*
8
(
sp
)
csrw
sstatus
,
t0
ld
t0
,
33
*
8
(
sp
)
csrw
satp
,
t0
ld
t0
,
34
*
8
(
sp
)
csrw
scause
,
t0
MAP
(
RESTORE
,
REGS
)
sfence.vma
zero
,
zero
#
flush
TLB
addi
sp
,
sp
,
280
ret
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
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
Menu
Explore
Projects
Groups
Topics
Snippets