Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
redox-os
bootloader
Commits
5a9374fb
Verified
Commit
5a9374fb
authored
Feb 14, 2022
by
Jeremy Soller
Browse files
Pass memory areas as argument instead of writing to physical memory
parent
1dfe98ef
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/main.rs
View file @
5a9374fb
...
...
@@ -22,13 +22,14 @@ use alloc::{
use
core
::{
cmp
,
fmt
::{
self
,
Write
},
mem
,
slice
,
str
,
};
use
redoxfs
::
Disk
;
use
self
::
arch
::
paging_create
;
use
self
::
os
::{
Os
,
OsKey
,
OsMemoryEntry
,
OsVideoMode
};
use
self
::
os
::{
Os
,
OsKey
,
OsMemoryEntry
,
OsMemoryKind
,
OsVideoMode
};
#[macro_use]
mod
os
;
...
...
@@ -39,6 +40,13 @@ mod logger;
const
KIBI
:
usize
=
1024
;
const
MIBI
:
usize
=
KIBI
*
KIBI
;
//TODO: allocate this in a more reasonable manner
pub
static
mut
AREAS
:
[
OsMemoryEntry
;
512
]
=
[
OsMemoryEntry
{
base
:
0
,
size
:
0
,
kind
:
OsMemoryKind
::
Null
,
};
512
];
struct
SliceWriter
<
'a
>
{
slice
:
&
'a
mut
[
u8
],
i
:
usize
,
...
...
@@ -78,6 +86,9 @@ pub struct KernelArgs {
acpi_rsdps_base
:
u64
,
/// The size of the RSDPs region.
acpi_rsdps_size
:
u64
,
areas_base
:
u64
,
areas_size
:
u64
,
}
fn
select_mode
<
...
...
@@ -366,6 +377,12 @@ fn main<
env_size
:
env_size
as
u64
,
acpi_rsdps_base
:
0
,
acpi_rsdps_size
:
0
,
areas_base
:
unsafe
{
AREAS
.as_ptr
()
as
u64
},
areas_size
:
unsafe
{
(
AREAS
.len
()
*
mem
::
size_of
::
<
OsMemoryEntry
>
())
as
u64
},
}
)
}
src/os/bios/memory_map.rs
View file @
5a9374fb
...
...
@@ -52,6 +52,7 @@ impl Iterator for MemoryMapIter {
base
:
entry
.base
,
size
:
entry
.size
,
kind
:
match
entry
.kind
{
0
=>
OsMemoryKind
::
Null
,
1
=>
OsMemoryKind
::
Free
,
3
=>
OsMemoryKind
::
Reclaim
,
_
=>
OsMemoryKind
::
Reserved
,
...
...
@@ -62,23 +63,11 @@ impl Iterator for MemoryMapIter {
pub
unsafe
fn
memory_map
(
thunk15
:
extern
"C"
fn
())
->
Option
<
(
usize
,
usize
)
>
{
let
mut
heap_limits
=
None
;
let
mut
data
=
ThunkData
::
new
();
loop
{
data
.eax
=
0xE820
;
data
.ecx
=
mem
::
size_of
::
<
MemoryMapEntry
>
()
as
u32
;
data
.edx
=
0x534D4150
;
data
.edi
=
MEMORY_MAP_ADDR
as
u32
;
data
.with
(
thunk15
);
assert_eq!
({
data
.eax
},
0x534D4150
);
assert_eq!
({
data
.ecx
},
mem
::
size_of
::
<
MemoryMapEntry
>
()
as
u32
);
let
entry
=
ptr
::
read
(
MEMORY_MAP_ADDR
as
*
const
MemoryMapEntry
);
for
(
i
,
entry
)
in
MemoryMapIter
::
new
(
thunk15
)
.enumerate
()
{
//TODO: There is a problem with QEMU crashing if we write at about 8 MiB, so skip to 16
let
heap_start
=
16
*
1024
*
1024
;
if
entry
.kind
==
1
&&
{
entry
.kind
}
==
OsMemoryKind
::
Free
&&
entry
.base
<=
heap_start
as
u64
&&
(
entry
.base
+
entry
.size
)
>=
heap_start
as
u64
{
...
...
@@ -94,8 +83,7 @@ pub unsafe fn memory_map(thunk15: extern "C" fn()) -> Option<(usize, usize)> {
}
}
if
data
.ebx
==
0
{
return
heap_limits
;
}
crate
::
AREAS
[
i
]
=
entry
;
}
heap_limits
}
src/os/bios/mod.rs
View file @
5a9374fb
...
...
@@ -130,7 +130,7 @@ impl Os<
(
edid
[
0x3B
]
as
u32
)
|
(((
edid
[
0x3D
]
as
u32
)
&
0xF0
)
<<
4
),
))
}
else
{
log
::
warn!
(
"Failed to get VBE EDID: 0x{:X}"
,
data
.eax
);
log
::
warn!
(
"Failed to get VBE EDID: 0x{:X}"
,
{
data
.eax
}
);
None
}
}
...
...
src/os/mod.rs
View file @
5a9374fb
...
...
@@ -24,14 +24,17 @@ pub enum OsKey {
Other
,
}
#[derive(Clone,
Copy,
Debug)]
#[derive(Clone,
Copy,
Debug,
Eq,
PartialEq)]
#[repr(u64)]
pub
enum
OsMemoryKind
{
Free
,
Reclaim
,
Reserved
,
Null
=
0
,
Free
=
1
,
Reclaim
=
2
,
Reserved
=
3
,
}
#[derive(Clone,
Copy,
Debug)]
#[repr(packed)]
pub
struct
OsMemoryEntry
{
pub
base
:
u64
,
pub
size
:
u64
,
...
...
@@ -52,7 +55,7 @@ pub trait Os<
V
:
Iterator
<
Item
=
OsVideoMode
>
>
{
fn
name
(
&
self
)
->
&
str
;
fn
alloc_zeroed_page_aligned
(
&
self
,
size
:
usize
)
->
*
mut
u8
;
fn
page_size
(
&
self
)
->
usize
;
...
...
src/os/uefi/arch/aarch64/memory_map.rs
deleted
100644 → 0
View file @
1dfe98ef
use
uefi
::
memory
::
MemoryDescriptor
;
pub
unsafe
fn
memory_map
()
->
usize
{
let
uefi
=
std
::
system_table
();
let
mut
map
:
[
u8
;
65536
]
=
[
0
;
65536
];
let
mut
map_size
=
map
.len
();
let
mut
map_key
=
0
;
let
mut
descriptor_size
=
0
;
let
mut
descriptor_version
=
0
;
let
_
=
(
uefi
.BootServices.GetMemoryMap
)(
&
mut
map_size
,
map
.as_mut_ptr
()
as
*
mut
MemoryDescriptor
,
&
mut
map_key
,
&
mut
descriptor_size
,
&
mut
descriptor_version
);
map_key
}
src/os/uefi/arch/aarch64/mod.rs
View file @
5a9374fb
...
...
@@ -14,12 +14,11 @@ use super::super::{
RSDPS_AREA
,
find_acpi_table_pointers
,
},
memory_map
::
memory_map
,
};
use
self
::
memory_map
::
memory_map
;
use
self
::
paging
::
paging
;
mod
memory_map
;
mod
paging
;
static
PHYS_OFFSET
:
u64
=
0xFFFF800000000000
;
...
...
src/os/uefi/arch/x86_64/memory_map.rs
deleted
100644 → 0
View file @
1dfe98ef
use
core
::{
mem
,
ptr
};
use
uefi
::
memory
::{
MemoryDescriptor
,
MemoryType
};
static
MM_BASE
:
u64
=
0x500
;
static
MM_SIZE
:
u64
=
0x4B00
;
/// Memory does not exist
pub
const
MEMORY_AREA_NULL
:
u32
=
0
;
/// Memory is free to use
pub
const
MEMORY_AREA_FREE
:
u32
=
1
;
/// Memory is reserved
pub
const
MEMORY_AREA_RESERVED
:
u32
=
2
;
/// Memory is used by ACPI, and can be reclaimed
pub
const
MEMORY_AREA_ACPI
:
u32
=
3
;
/// A memory map area
#[derive(Copy,
Clone,
Debug,
Default)]
#[repr(packed)]
pub
struct
MemoryArea
{
pub
base_addr
:
u64
,
pub
length
:
u64
,
pub
_type
:
u32
,
pub
acpi
:
u32
}
pub
unsafe
fn
memory_map
()
->
usize
{
let
uefi
=
std
::
system_table
();
ptr
::
write_bytes
(
MM_BASE
as
*
mut
u8
,
0
,
MM_SIZE
as
usize
);
let
mut
map
:
[
u8
;
65536
]
=
[
0
;
65536
];
let
mut
map_size
=
map
.len
();
let
mut
map_key
=
0
;
let
mut
descriptor_size
=
0
;
let
mut
descriptor_version
=
0
;
let
_
=
(
uefi
.BootServices.GetMemoryMap
)(
&
mut
map_size
,
map
.as_mut_ptr
()
as
*
mut
MemoryDescriptor
,
&
mut
map_key
,
&
mut
descriptor_size
,
&
mut
descriptor_version
);
if
descriptor_size
>=
mem
::
size_of
::
<
MemoryDescriptor
>
()
{
for
i
in
0
..
map_size
/
descriptor_size
{
let
descriptor_ptr
=
map
.as_ptr
()
.offset
((
i
*
descriptor_size
)
as
isize
);
let
descriptor
=
&
*
(
descriptor_ptr
as
*
const
MemoryDescriptor
);
let
descriptor_type
:
MemoryType
=
mem
::
transmute
(
descriptor
.Type
);
let
bios_type
=
match
descriptor_type
{
MemoryType
::
EfiLoaderCode
|
MemoryType
::
EfiLoaderData
|
MemoryType
::
EfiBootServicesCode
|
MemoryType
::
EfiBootServicesData
|
MemoryType
::
EfiConventionalMemory
=>
{
MEMORY_AREA_FREE
},
_
=>
{
MEMORY_AREA_RESERVED
}
};
let
bios_area
=
MemoryArea
{
base_addr
:
descriptor
.PhysicalStart
.0
,
length
:
descriptor
.NumberOfPages
*
4096
,
_type
:
bios_type
,
acpi
:
0
,
};
ptr
::
write
((
MM_BASE
as
*
mut
MemoryArea
)
.offset
(
i
as
isize
),
bios_area
);
}
}
else
{
println!
(
"Unknown memory descriptor size: {}"
,
descriptor_size
);
}
map_key
}
src/os/uefi/arch/x86_64/mod.rs
View file @
5a9374fb
...
...
@@ -14,12 +14,11 @@ use super::super::{
RSDPS_AREA
,
find_acpi_table_pointers
,
},
memory_map
::
memory_map
,
};
use
self
::
memory_map
::
memory_map
;
use
self
::
paging
::
paging_enter
;
mod
memory_map
;
mod
paging
;
static
PHYS_OFFSET
:
u64
=
0xFFFF800000000000
;
...
...
src/os/uefi/memory_map.rs
View file @
5a9374fb
use
alloc
::
boxed
::
Box
;
use
core
::{
mem
,
ptr
};
use
log
::
error
;
use
uefi
::
memory
::{
MemoryDescriptor
,
MemoryType
};
use
crate
::
os
::{
OsMemoryEntry
,
OsMemoryKind
};
use
super
::
status_to_result
;
pub
struct
MemoryMapIter
{
map
:
[
u8
;
4096
]
,
map_
size
:
usize
,
map
:
Box
<
[
u8
]
>
,
map_
key
:
usize
,
descriptor_size
:
usize
,
i
:
usize
,
}
...
...
@@ -15,22 +18,23 @@ impl MemoryMapIter {
pub
fn
new
()
->
Self
{
let
uefi
=
std
::
system_table
();
let
mut
map
:
[
u8
;
4096
]
=
[
0
;
409
6
];
let
mut
map
=
vec!
[
0
;
6553
6
];
let
mut
map_size
=
map
.len
();
let
mut
map_key
=
0
;
let
mut
descriptor_size
=
0
;
let
mut
descriptor_version
=
0
;
let
_
=
(
uefi
.BootServices.GetMemoryMap
)(
status_to_result
(
(
uefi
.BootServices.GetMemoryMap
)(
&
mut
map_size
,
map
.as_mut_ptr
()
as
*
mut
MemoryDescriptor
,
&
mut
map_key
,
&
mut
descriptor_size
,
&
mut
descriptor_version
);
))
.expect
(
"Failed to get UEFI memory map"
);
map
.truncate
(
map_size
);
Self
{
map
,
map_
size
,
map
:
map
.into_boxed_slice
()
,
map_
key
,
descriptor_size
,
i
:
0
,
}
...
...
@@ -40,39 +44,49 @@ impl MemoryMapIter {
impl
Iterator
for
MemoryMapIter
{
type
Item
=
OsMemoryEntry
;
fn
next
(
&
mut
self
)
->
Option
<
Self
::
Item
>
{
if
self
.descriptor_size
>=
mem
::
size_of
::
<
MemoryDescriptor
>
()
&&
self
.i
<
self
.map_size
/
self
.descriptor_size
{
let
descriptor_ptr
=
unsafe
{
self
.map
.as_ptr
()
.add
(
self
.i
*
self
.descriptor_size
)
};
self
.i
+=
1
;
if
self
.descriptor_size
>=
mem
::
size_of
::
<
MemoryDescriptor
>
()
{
if
self
.i
<
self
.map
.len
()
/
self
.descriptor_size
{
let
descriptor_ptr
=
unsafe
{
self
.map
.as_ptr
()
.add
(
self
.i
*
self
.descriptor_size
)
};
self
.i
+=
1
;
let
descriptor
=
unsafe
{
ptr
::
read
(
descriptor_ptr
as
*
const
MemoryDescriptor
)
};
let
descriptor_type
:
MemoryType
=
unsafe
{
mem
::
transmute
(
descriptor
.Type
)
};
let
descriptor
=
unsafe
{
ptr
::
read
(
descriptor_ptr
as
*
const
MemoryDescriptor
)
};
let
descriptor_type
:
MemoryType
=
unsafe
{
mem
::
transmute
(
descriptor
.Type
)
};
Some
(
OsMemoryEntry
{
base
:
descriptor
.PhysicalStart
.0
,
//TODO: do not hard code page size
size
:
descriptor
.NumberOfPages
*
4096
,
kind
:
match
descriptor_type
{
MemoryType
::
EfiBootServicesCode
|
MemoryType
::
EfiBootServicesData
|
MemoryType
::
EfiConventionalMemory
=>
{
OsMemoryKind
::
Free
},
MemoryType
::
EfiLoaderCode
|
MemoryType
::
EfiLoaderData
|
MemoryType
::
EfiACPIReclaimMemory
=>
{
OsMemoryKind
::
Reclaim
},
_
=>
{
OsMemoryKind
::
Reserved
Some
(
OsMemoryEntry
{
base
:
descriptor
.PhysicalStart
.0
,
//TODO: do not hard code page size
size
:
descriptor
.NumberOfPages
*
4096
,
kind
:
match
descriptor_type
{
MemoryType
::
EfiLoaderCode
|
MemoryType
::
EfiLoaderData
|
MemoryType
::
EfiBootServicesCode
|
MemoryType
::
EfiBootServicesData
|
MemoryType
::
EfiConventionalMemory
=>
{
OsMemoryKind
::
Free
},
//TODO: mark ACPI memory as reclaim
_
=>
{
OsMemoryKind
::
Reserved
}
}
}
})
})
}
else
{
None
}
}
else
{
error!
(
"Unknown memory descriptor size: {}"
,
self
.descriptor_size
);
None
}
}
}
pub
unsafe
fn
memory_map
()
->
usize
{
let
iter
=
MemoryMapIter
::
new
();
let
map_key
=
iter
.map_key
;
for
(
i
,
entry
)
in
iter
.enumerate
()
{
crate
::
AREAS
[
i
]
=
entry
;
}
map_key
}
Write
Preview
Supports
Markdown
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