Skip to content

Commit e02ead7

Browse files
committed
Merge branch 'main' into next
2 parents 29b9912 + 77c9525 commit e02ead7

File tree

4 files changed

+123
-28
lines changed

4 files changed

+123
-28
lines changed

Cargo.lock

Lines changed: 10 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/Cargo.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ rand = { version = "0.8.4", default-features = false }
2020
rand_hc = "0.3.1"
2121

2222
[dependencies.noto-sans-mono-bitmap]
23-
version = "0.1.2"
23+
version = "0.2.0"
2424
default-features = false
25-
features = ["regular", "size_14"]
25+
features = [
26+
"regular",
27+
"size_16",
28+
"unicode-basic-latin",
29+
# required for the fallback char '�'
30+
"unicode-specials",
31+
]

common/src/load_kernel.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ where
127127
}
128128
}
129129

130+
// Mark some memory regions as read-only after relocations have been
131+
// applied.
132+
for program_header in self.elf_file.program_iter() {
133+
if let Type::GnuRelro = program_header.get_type()? {
134+
self.inner.handle_relro_segment(program_header);
135+
}
136+
}
137+
130138
self.inner.remove_copied_flags(&self.elf_file).unwrap();
131139

132140
Ok(tls_template)
@@ -496,6 +504,44 @@ where
496504

497505
Ok(())
498506
}
507+
508+
/// Mark a region of memory indicated by a GNU_RELRO segment as read-only.
509+
///
510+
/// This is a security mitigation used to protect memory regions that
511+
/// need to be writable while applying relocations, but should never be
512+
/// written to after relocations have been applied.
513+
fn handle_relro_segment(&mut self, program_header: ProgramHeader) {
514+
let start = self.virtual_address_offset + program_header.virtual_addr();
515+
let end = start + program_header.mem_size();
516+
let start = VirtAddr::new(start);
517+
let end = VirtAddr::new(end);
518+
let start_page = Page::containing_address(start);
519+
let end_page = Page::containing_address(end - 1u64);
520+
for page in Page::<Size4KiB>::range_inclusive(start_page, end_page) {
521+
// Translate the page and get the flags.
522+
let res = self.page_table.translate(page.start_address());
523+
let flags = match res {
524+
TranslateResult::Mapped {
525+
frame: _,
526+
offset: _,
527+
flags,
528+
} => flags,
529+
TranslateResult::NotMapped | TranslateResult::InvalidFrameAddress(_) => {
530+
unreachable!("has the elf file not been mapped correctly?")
531+
}
532+
};
533+
534+
if flags.contains(Flags::WRITABLE) {
535+
// Remove the WRITABLE flag.
536+
unsafe {
537+
self.page_table
538+
.update_flags(page, flags & !Flags::WRITABLE)
539+
.unwrap()
540+
.ignore();
541+
}
542+
}
543+
}
544+
}
499545
}
500546

501547
/// Check that the virtual offset belongs to a load segment.

common/src/logger.rs

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use core::{
44
fmt::{self, Write},
55
ptr,
66
};
7-
use noto_sans_mono_bitmap::{get_bitmap, get_bitmap_width, BitmapChar, BitmapHeight, FontWeight};
7+
use font_constants::BACKUP_CHAR;
8+
use noto_sans_mono_bitmap::{
9+
get_raster, get_raster_width, FontWeight, RasterHeight, RasterizedChar,
10+
};
811
use spinning_top::Spinlock;
912

1013
/// The global logger instance used for the `log` crate.
@@ -14,9 +17,42 @@ pub static LOGGER: OnceCell<LockedLogger> = OnceCell::uninit();
1417
pub struct LockedLogger(Spinlock<Logger>);
1518

1619
/// Additional vertical space between lines
17-
const LINE_SPACING: usize = 0;
18-
/// Additional vertical space between separate log messages
19-
const LOG_SPACING: usize = 2;
20+
const LINE_SPACING: usize = 2;
21+
/// Additional horizontal space between characters.
22+
const LETTER_SPACING: usize = 0;
23+
24+
/// Padding from the border. Prevent that font is too close to border.
25+
const BORDER_PADDING: usize = 1;
26+
27+
/// Constants for the usage of the [`noto_sans_mono_bitmap`] crate.
28+
mod font_constants {
29+
use super::*;
30+
31+
/// Height of each char raster. The font size is ~0.84% of this. Thus, this is the line height that
32+
/// enables multiple characters to be side-by-side and appear optically in one line in a natural way.
33+
pub const CHAR_RASTER_HEIGHT: RasterHeight = RasterHeight::Size16;
34+
35+
/// The width of each single symbol of the mono space font.
36+
pub const CHAR_RASTER_WIDTH: usize = get_raster_width(FontWeight::Regular, CHAR_RASTER_HEIGHT);
37+
38+
/// Backup character if a desired symbol is not available by the font.
39+
/// The '�' character requires the feature "unicode-specials".
40+
pub const BACKUP_CHAR: char = '�';
41+
42+
pub const FONT_WEIGHT: FontWeight = FontWeight::Regular;
43+
}
44+
45+
/// Returns the raster of the given char or the raster of [`font_constants::BACKUP_CHAR`].
46+
fn get_char_raster(c: char) -> RasterizedChar {
47+
fn get(c: char) -> Option<RasterizedChar> {
48+
get_raster(
49+
c,
50+
font_constants::FONT_WEIGHT,
51+
font_constants::CHAR_RASTER_HEIGHT,
52+
)
53+
}
54+
get(c).unwrap_or(get(BACKUP_CHAR).expect("Should get raster of backup char."))
55+
}
2056

2157
impl LockedLogger {
2258
/// Create a new instance that logs to the given framebuffer.
@@ -39,8 +75,7 @@ impl log::Log for LockedLogger {
3975

4076
fn log(&self, record: &log::Record) {
4177
let mut logger = self.0.lock();
42-
writeln!(logger, "{}: {}", record.level(), record.args()).unwrap();
43-
logger.add_vspace(LOG_SPACING);
78+
writeln!(logger, "{:5}: {}", record.level(), record.args()).unwrap();
4479
}
4580

4681
fn flush(&self) {}
@@ -68,22 +103,18 @@ impl Logger {
68103
}
69104

70105
fn newline(&mut self) {
71-
self.y_pos += 14 + LINE_SPACING;
106+
self.y_pos += font_constants::CHAR_RASTER_HEIGHT.val() + LINE_SPACING;
72107
self.carriage_return()
73108
}
74109

75-
fn add_vspace(&mut self, space: usize) {
76-
self.y_pos += space;
77-
}
78-
79110
fn carriage_return(&mut self) {
80-
self.x_pos = 0;
111+
self.x_pos = BORDER_PADDING;
81112
}
82113

83-
/// Erases all text on the screen.
114+
/// Erases all text on the screen. Resets `self.x_pos` and `self.y_pos`.
84115
pub fn clear(&mut self) {
85-
self.x_pos = 0;
86-
self.y_pos = 0;
116+
self.x_pos = BORDER_PADDING;
117+
self.y_pos = BORDER_PADDING;
87118
self.framebuffer.fill(0);
88119
}
89120

@@ -95,30 +126,36 @@ impl Logger {
95126
self.info.height
96127
}
97128

129+
/// Writes a single char to the framebuffer. Takes care of special control characters, such as
130+
/// newlines and carriage returns.
98131
fn write_char(&mut self, c: char) {
99132
match c {
100133
'\n' => self.newline(),
101134
'\r' => self.carriage_return(),
102135
c => {
103-
let bitmap_char = get_bitmap(c, FontWeight::Regular, BitmapHeight::Size14).unwrap();
104-
if self.x_pos + bitmap_char.width() > self.width() {
136+
let new_xpos = self.x_pos + font_constants::CHAR_RASTER_WIDTH;
137+
if new_xpos >= self.width() {
105138
self.newline();
106139
}
107-
if self.y_pos + bitmap_char.height() > self.height() {
140+
let new_ypos =
141+
self.y_pos + font_constants::CHAR_RASTER_HEIGHT.val() + BORDER_PADDING;
142+
if new_ypos >= self.height() {
108143
self.clear();
109144
}
110-
self.write_rendered_char(bitmap_char);
145+
self.write_rendered_char(get_char_raster(c));
111146
}
112147
}
113148
}
114149

115-
fn write_rendered_char(&mut self, rendered_char: BitmapChar) {
116-
for (y, row) in rendered_char.bitmap().iter().enumerate() {
150+
/// Prints a rendered char into the framebuffer.
151+
/// Updates `self.x_pos`.
152+
fn write_rendered_char(&mut self, rendered_char: RasterizedChar) {
153+
for (y, row) in rendered_char.raster().iter().enumerate() {
117154
for (x, byte) in row.iter().enumerate() {
118155
self.write_pixel(self.x_pos + x, self.y_pos + y, *byte);
119156
}
120157
}
121-
self.x_pos += rendered_char.width();
158+
self.x_pos += rendered_char.width() + LETTER_SPACING;
122159
}
123160

124161
fn write_pixel(&mut self, x: usize, y: usize, intensity: u8) {

0 commit comments

Comments
 (0)