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-17064-1466468
OSKernel2023-LuoOS-3311
Commits
a9dc4a9d
Commit
a9dc4a9d
authored
2 years ago
by
某某某
Browse files
Options
Download
Patches
Plain Diff
feat: impl removeMapping;
feat: impl mappingtype and sharing type; chore: PageMgr.alloc typo
parent
f86ab41a
master
FAT
dev-zyc1
execve-fat-bug
ktrapexit-bug
master_alternate
sleep_bug
times_bug
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
include/alloc.hh
+1
-1
include/alloc.hh
include/vm.hh
+47
-3
include/vm.hh
kernel/ld.cc
+1
-1
kernel/ld.cc
kernel/vm.cc
+53
-0
kernel/vm.cc
with
102 additions
and
5 deletions
+102
-5
include/alloc.hh
+
1
−
1
View file @
a9dc4a9d
...
...
@@ -14,7 +14,7 @@ namespace alloc
PageMgr
(
xlen_t
start
,
xlen_t
end
);
~
PageMgr
();
xlen_t
alloc
(
size_t
pages
);
xlen_t
free
(
xlen_t
pages
,
int
order
);
xlen_t
free
(
PageNum
ppn
,
int
order
);
inline
void
print
(){
printf
(
"buddy: |"
);
for
(
xlen_t
i
=
0
;
i
<
buddyTreeSize
;
i
++
)
printf
(
"%d | "
,
buddyNodes
[
i
]
-
1
);
printf
(
"
\n
"
);
}
...
...
This diff is collapsed.
Click to expand it.
include/vm.hh
+
47
−
3
View file @
a9dc4a9d
...
...
@@ -3,6 +3,7 @@
#include
"common.h"
#include
"klib.hh"
#include
"TINYSTL/vector.h"
#define moduleLevel LogLevel::debug
namespace
vm
...
...
@@ -49,6 +50,7 @@ namespace vm
};
inline
bool
isValid
(){
return
fields
.
v
;
}
inline
void
setValid
(){
fields
.
v
=
1
;
}
inline
void
setInvalid
(){
raw
.
perm
=
0
;
}
inline
void
setPTNode
(){
fields
.
r
=
fields
.
w
=
fields
.
x
=
0
;
}
inline
bool
isLeaf
(){
return
fields
.
r
|
fields
.
w
|
fields
.
x
;
}
inline
perm_t
perm
(){
return
raw
.
perm
;
}
...
...
@@ -98,28 +100,51 @@ namespace vm
inline
PageNum
pages
()
const
{
return
pages_
;}
inline
PageNum
ppn
()
const
{
return
ppn_
;}
inline
klib
::
string
toString
()
const
{
return
klib
::
format
(
"<VMO>@0x%lx[%lx]
\n
"
,
ppn
(),
pages
());}
static
VMO
alloc
(
PageNum
pages
,
CloneType
type
=
CloneType
::
clone
);
static
VMO
alloc
(
PageNum
pages
,
CloneType
=
CloneType
::
clone
);
bool
operator
==
(
const
VMO
&
other
){
return
ppn_
==
other
.
ppn_
&&
pages_
==
other
.
pages_
;}
private
:
};
struct
PageMapping
{
enum
Prot
{
none
=
0x0
,
read
=
0x4
,
write
=
0x2
,
exec
=
0x1
};
enum
class
MappingType
:
uint8_t
{
Normal
,
MMap
,
normal
=
0x0
,
file
=
0x1
,
anon
=
0x2
};
enum
class
SharingType
:
uint8_t
{
/// @brief changes aren't visible to others, copy on write
privt
=
0x0
,
/// @brief not implemented
copy
=
0x1
,
/// @brief changes are shared
shared
=
0x2
};
PageNum
vpn
;
VMO
vmo
;
const
perm_t
perm
;
const
MappingType
type
=
MappingType
::
Normal
;
const
MappingType
mapping
=
MappingType
::
normal
;
const
SharingType
sharing
=
SharingType
::
privt
;
inline
PageNum
ppn
()
const
{
return
vmo
.
ppn
();}
inline
PageNum
pages
()
const
{
return
vmo
.
pages
();}
inline
klib
::
string
toString
()
const
{
return
klib
::
format
(
"%lx=>%s"
,
vpn
,
vmo
.
toString
());}
inline
PageMapping
clone
()
const
{
return
PageMapping
{
vpn
,
vmo
.
clone
(),
perm
};}
inline
static
perm_t
prot2perm
(
Prot
prot
){
perm_t
rt
=
0
;
using
masks
=
PageTableEntry
::
fieldMasks
;
if
(
prot
&
read
)
rt
|=
masks
::
r
;
if
(
prot
&
write
)
rt
|=
masks
::
w
;
if
(
prot
&
exec
)
rt
|=
masks
::
x
;
return
rt
;
}
bool
operator
==
(
const
PageMapping
&
other
){
return
vpn
==
other
.
vpn
&&
vmo
==
other
.
vmo
&&
perm
==
other
.
perm
&&
mapping
==
other
.
mapping
&&
sharing
==
other
.
sharing
;}
};
class
PageTable
{
private:
pgtbl_t
root
;
static
pgtbl_t
createPTNode
();
static
bool
freePTNode
(
pgtbl_t
);
public:
inline
PageTable
(
pgtbl_t
root
=
nullptr
){
if
(
root
==
nullptr
)
this
->
root
=
createPTNode
();
...
...
@@ -143,6 +168,10 @@ namespace vm
inline
void
createMapping
(
const
PageMapping
&
mapping
){
createMapping
(
mapping
.
vpn
,
mapping
.
ppn
(),
mapping
.
pages
(),
mapping
.
perm
);
}
void
removeMapping
(
pgtbl_t
table
,
PageNum
vpn
,
xlen_t
pages
,
int
level
=
2
);
inline
void
removeMapping
(
const
PageMapping
&
mapping
){
removeMapping
(
root
,
mapping
.
vpn
,
mapping
.
pages
());
}
PageNum
trans
(
PageNum
vpn
);
inline
xlen_t
transaddr
(
xlen_t
addr
){
return
pn2addr
(
trans
(
addr2pn
(
addr
)))
+
addr2offset
(
addr
);
...
...
@@ -177,6 +206,21 @@ namespace vm
}
inline
void
map
(
PageNum
vpn
,
PageNum
ppn
,
PageNum
pages
,
perm_t
perm
,
CloneType
ct
=
CloneType
::
clone
){
map
(
PageMapping
{
vpn
,
VMO
{
ppn
,
pages
,
ct
},
perm
});}
inline
void
unmap
();
inline
void
reset
(){
Log
(
debug
,
"before reset, VMAR:%s"
,
mappings
.
toString
().
c_str
());
tinystl
::
vector
<
PageMapping
>
toremove
;
for
(
auto
mapping
:
mappings
){
if
(
mapping
.
mapping
!=
PageMapping
::
MappingType
::
normal
){
Log
(
info
,
"unmap %s"
,
mapping
.
toString
().
c_str
());
toremove
.
push_back
(
mapping
);
pagetable
.
removeMapping
(
mapping
);
}
}
/// @todo better efficiency
for
(
auto
&
mapping
:
toremove
)
mappings
.
remove
(
mapping
);
Log
(
debug
,
"after reset, VMAR:%s"
,
mappings
.
toString
().
c_str
());
}
inline
xlen_t
satp
(){
return
PageTable
::
toSATP
(
pagetable
);}
// @todo @bug what if region is on border?
inline
klib
::
ByteArray
copyinstr
(
xlen_t
addr
,
size_t
len
)
{
...
...
This diff is collapsed.
Click to expand it.
kernel/ld.cc
+
1
−
1
View file @
a9dc4a9d
...
...
@@ -15,7 +15,7 @@ xlen_t ld::loadElf(const uint8_t *buff,vm::VMAR &vmar){
int
pages
=
vm
::
bytes2pages
(
entry
.
p_memsz
);
vm
::
PageNum
ppn
=
(
kGlobObjs
.
pageMgr
->
alloc
(
pages
));
Log
(
debug
,
"%x<=%x[%d pages@%x]"
,
vm
::
addr2pn
(
entry
.
p_vaddr
),
ppn
,
pages
,
ld
::
elf
::
flags2perm
(
entry
.
p_flags
));
vmar
.
map
(
vm
::
addr2pn
(
entry
.
p_vaddr
),
ppn
,
pages
,
ld
::
elf
::
flags2perm
(
entry
.
p_flags
));
vmar
.
map
(
vm
::
PageMapping
{
vm
::
addr2pn
(
entry
.
p_vaddr
),
vm
::
VMO
{
ppn
,
pages
}
,
ld
::
elf
::
flags2perm
(
entry
.
p_flags
)
,
vm
::
PageMapping
::
MappingType
::
file
}
);
memcpy
((
ptr_t
)
vm
::
pn2addr
(
ppn
),
buff
+
entry
.
p_offset
,
entry
.
p_filesz
);
}
return
elfHeader
->
e_entry
;
...
...
This diff is collapsed.
Click to expand it.
kernel/vm.cc
+
53
−
0
View file @
a9dc4a9d
...
...
@@ -85,6 +85,51 @@ void PageTable::createMapping(pgtbl_t table,PageNum vpn,PageNum ppn,xlen_t pages
createMapping
(
subTable
,
vpn
,
ppn
,
pages
,
perm
,
level
-
1
);
}
}
void
PageTable
::
removeMapping
(
pgtbl_t
table
,
PageNum
vpn
,
xlen_t
pages
,
int
level
){
xlen_t
bigPageSize
=
1l
<<
(
9
*
level
);
xlen_t
unaligned
=
vpn
&
(
bigPageSize
-
1
);
Log
(
debug
,
"removeMapping(table,vpn=0x%lx,pages=0x%lx,level=%d)
\n
"
,
vpn
,
pages
,
level
);
Log
(
debug
,
"bigPageSize=%lx,unaligned=%lx
\n
"
,
bigPageSize
,
unaligned
);
// align vpn to boundary
if
(
unaligned
){
auto
partial
=
klib
::
min
(
bigPageSize
-
unaligned
,
pages
);
PageTableEntry
&
entry
=
table
[(
vpn
/
bigPageSize
)
&
vpnMask
];
assert
(
entry
.
isValid
()
&&
!
entry
.
isLeaf
());
pgtbl_t
subTable
=
entry
.
child
();
DBG_ENTRY
Log
(
debug
,
"subtable=%lx
\n
"
,
subTable
);
removeMapping
(
subTable
,
vpn
,
partial
,
level
-
1
);
// actual create mapping
if
(
freePTNode
(
subTable
))
entry
.
setInvalid
();
vpn
+=
partial
,
pages
-=
partial
;
}
// unmap aligned whole pages
for
(
int
i
=
(
vpn
/
bigPageSize
)
&
vpnMask
;
pages
>=
bigPageSize
;
i
++
){
PageTableEntry
&
entry
=
table
[
i
];
assert
(
entry
.
isValid
());
// big page entry
if
(
entry
.
isLeaf
())
entry
.
setInvalid
();
else
{
// pushed down
removeMapping
(
entry
.
child
(),
vpn
,
pages
,
level
-
1
);
assert
(
freePTNode
(
entry
.
child
()));
entry
.
setInvalid
();
}
vpn
+=
bigPageSize
;
pages
-=
bigPageSize
;
}
// unmap rest pages
if
(
pages
){
assert
(
pages
>
0
);
PageTableEntry
&
entry
=
table
[(
vpn
/
bigPageSize
)
&
vpnMask
];
assert
(
entry
.
isValid
()
&&
!
entry
.
isLeaf
());
pgtbl_t
subTable
=
entry
.
child
();
DBG_ENTRY
Log
(
debug
,
"subtable=%lx
\n
"
,
subTable
);
removeMapping
(
subTable
,
vpn
,
pages
,
level
-
1
);
// actual create mapping
if
(
freePTNode
(
subTable
))
entry
.
setInvalid
();
}
}
klib
::
string
PageTable
::
toString
(
pgtbl_t
table
,
xlen_t
vpnBase
,
xlen_t
entrySize
){
assert
(
entrySize
>
0
);
klib
::
string
s
;
...
...
@@ -107,6 +152,14 @@ pgtbl_t PageTable::createPTNode(){
Log
(
debug
,
"createPTNode=0x%lx"
,
rt
);
return
rt
;
}
bool
PageTable
::
freePTNode
(
pgtbl_t
table
){
for
(
int
i
=
0
;
i
<
pageEntriesPerPage
;
i
++
){
auto
&
entry
=
table
[
i
];
if
(
entry
.
isValid
())
return
false
;
}
kGlobObjs
.
pageMgr
->
free
(
addr2pn
((
xlen_t
)
table
),
0
);
return
true
;
}
xlen_t
PageTable
::
toSATP
(
PageTable
&
table
){
csr
::
satp
satp
;
satp
.
mode
=
8
;
...
...
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