Skip to content

Commit 16330cd

Browse files
rust-osdev#364: Use different configs for VMs vs real hardware
1 parent ccb8bb2 commit 16330cd

File tree

3 files changed

+67
-23
lines changed

3 files changed

+67
-23
lines changed

bios/stage-4/src/main.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! {
129129
};
130130

131131
#[allow(deprecated)]
132-
if config.frame_buffer.minimum_framebuffer_height.is_none() {
133-
config.frame_buffer.minimum_framebuffer_height =
132+
if config.frame_buffer_physical.minimum_framebuffer_height.is_none() {
133+
config.frame_buffer_physical.minimum_framebuffer_height =
134134
kernel.config.frame_buffer.minimum_framebuffer_height;
135135
}
136136
#[allow(deprecated)]
137-
if config.frame_buffer.minimum_framebuffer_width.is_none() {
138-
config.frame_buffer.minimum_framebuffer_width =
137+
if config.frame_buffer_physical.minimum_framebuffer_width.is_none() {
138+
config.frame_buffer_physical.minimum_framebuffer_width =
139139
kernel.config.frame_buffer.minimum_framebuffer_width;
140140
}
141141
let framebuffer_info = init_logger(

common/config/src/lib.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ use serde::{Deserialize, Serialize};
77
#[serde(default)]
88
#[non_exhaustive]
99
pub struct BootConfig {
10-
/// Configuration for the frame buffer setup.
11-
pub frame_buffer: FrameBuffer,
10+
/// Configuration for the frame buffer setup on physical hardware.
11+
pub frame_buffer_physical: FrameBuffer,
12+
13+
/// Configuration for the frame buffer setup in a virtual machine
14+
pub frame_buffer_virtual: FrameBuffer,
1215

1316
/// The minimum log level that is printed to the screen during boot.
1417
///
@@ -32,7 +35,8 @@ pub struct BootConfig {
3235
impl Default for BootConfig {
3336
fn default() -> Self {
3437
Self {
35-
frame_buffer: Default::default(),
38+
frame_buffer_virtual: Default::default(),
39+
frame_buffer_physical: Default::default(),
3640
log_level: Default::default(),
3741
frame_buffer_logging: true,
3842
serial_logging: true,

uefi/src/main.rs

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use core::{
1313
ops::{Deref, DerefMut},
1414
ptr, slice,
1515
};
16-
use raw_cpuid::CpuId;
16+
use raw_cpuid::{CpuId, Hypervisor};
1717
use uefi::{
1818
prelude::{entry, Boot, Handle, Status, SystemTable},
1919
proto::{
@@ -98,13 +98,13 @@ fn main_inner(image: Handle, mut st: SystemTable<Boot>) -> Status {
9898
};
9999

100100
#[allow(deprecated)]
101-
if config.frame_buffer.minimum_framebuffer_height.is_none() {
102-
config.frame_buffer.minimum_framebuffer_height =
101+
if config.frame_buffer_physical.minimum_framebuffer_height.is_none() {
102+
config.frame_buffer_physical.minimum_framebuffer_height =
103103
kernel.config.frame_buffer.minimum_framebuffer_height;
104104
}
105105
#[allow(deprecated)]
106-
if config.frame_buffer.minimum_framebuffer_width.is_none() {
107-
config.frame_buffer.minimum_framebuffer_width =
106+
if config.frame_buffer_physical.minimum_framebuffer_width.is_none() {
107+
config.frame_buffer_physical.minimum_framebuffer_width =
108108
kernel.config.frame_buffer.minimum_framebuffer_width;
109109
}
110110
let framebuffer = init_logger(image, &st, &config);
@@ -472,16 +472,62 @@ fn init_logger(
472472
};
473473

474474
let mode = {
475-
let mut modes = gop.modes();
476-
477-
if let Some(_) = CpuId::new().get_hypervisor_info() {
475+
let modes = gop.modes();
476+
477+
if let Some(hypervisor) = CpuId::new().get_hypervisor_info() {
478+
if let Hypervisor::Xen = hypervisor.identify() {
479+
// Use same rules as real hardware since Xen uses the whole screen
480+
match (
481+
config
482+
.frame_buffer_physical
483+
.minimum_framebuffer_height
484+
.map(|v| usize::try_from(v).unwrap()),
485+
config
486+
.frame_buffer_physical
487+
.minimum_framebuffer_width
488+
.map(|v| usize::try_from(v).unwrap()),
489+
) {
490+
(Some(height), Some(width)) => modes
491+
.filter(|m| {
492+
let res = m.info().resolution();
493+
res.1 >= height && res.0 >= width
494+
})
495+
.last(),
496+
(Some(height), None) => modes.filter(|m| m.info().resolution().1 >= height).last(),
497+
(None, Some(width)) => modes.filter(|m| m.info().resolution().0 >= width).last(),
498+
_ => None,
499+
}
500+
} else {
501+
match (
502+
config
503+
.frame_buffer_virtual
504+
.minimum_framebuffer_height
505+
.map(|v| usize::try_from(v).unwrap()),
506+
config
507+
.frame_buffer_virtual
508+
.minimum_framebuffer_width
509+
.map(|v| usize::try_from(v).unwrap()),
510+
) {
511+
(Some(height), Some(width)) => modes
512+
.filter(|m| {
513+
let res = m.info().resolution();
514+
res.1 >= height && res.0 >= width
515+
})
516+
.last(),
517+
(Some(height), None) => modes.filter(|m| m.info().resolution().1 >= height).last(),
518+
(None, Some(width)) => modes.filter(|m| m.info().resolution().0 >= width).last(),
519+
_ => None,
520+
}
521+
}
522+
} else {
523+
// On real hardware; set rules accordingly
478524
match (
479525
config
480-
.frame_buffer
526+
.frame_buffer_physical
481527
.minimum_framebuffer_height
482528
.map(|v| usize::try_from(v).unwrap()),
483529
config
484-
.frame_buffer
530+
.frame_buffer_physical
485531
.minimum_framebuffer_width
486532
.map(|v| usize::try_from(v).unwrap()),
487533
) {
@@ -495,12 +541,6 @@ fn init_logger(
495541
(None, Some(width)) => modes.filter(|m| m.info().resolution().0 >= width).last(),
496542
_ => None,
497543
}
498-
} else {
499-
// Default to using the highest resolution available on real hardware
500-
let x = gop.modes().map(|m| m.info().resolution().0).max().unwrap();
501-
let y = gop.modes().map(|m| m.info().resolution().1).max().unwrap();
502-
503-
modes.find(|m| m.info().resolution().0 == x && m.info().resolution().1 == y)
504544
}
505545
};
506546
if let Some(mode) = mode {

0 commit comments

Comments
 (0)