Add `i8042.exist` to override ACPI flags
This commit is contained in:
parent
04a2290812
commit
13afca6441
|
|
@ -165,6 +165,16 @@ dependencies = [
|
|||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aster-cmdline"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"component",
|
||||
"log",
|
||||
"ostd",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aster-console"
|
||||
version = "0.1.0"
|
||||
|
|
@ -192,6 +202,7 @@ dependencies = [
|
|||
name = "aster-i8042"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aster-cmdline",
|
||||
"aster-input",
|
||||
"bitflags 2.9.1",
|
||||
"component",
|
||||
|
|
@ -263,6 +274,7 @@ dependencies = [
|
|||
"align_ext",
|
||||
"aster-bigtcp",
|
||||
"aster-block",
|
||||
"aster-cmdline",
|
||||
"aster-console",
|
||||
"aster-framebuffer",
|
||||
"aster-i8042",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ members = [
|
|||
"ostd/libs/ostd-test",
|
||||
"kernel",
|
||||
"kernel/comps/block",
|
||||
"kernel/comps/cmdline",
|
||||
"kernel/comps/console",
|
||||
"kernel/comps/framebuffer",
|
||||
"kernel/comps/input",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ mlsdisk = { name = "aster-mlsdisk" }
|
|||
systree = { name = "aster-systree" }
|
||||
i8042 = { name = "aster-i8042" }
|
||||
pci = { name = "aster-pci" }
|
||||
cmdline = { name = "aster-cmdline" }
|
||||
|
||||
[whitelist]
|
||||
[whitelist.nix.main]
|
||||
|
|
|
|||
1
Makefile
1
Makefile
|
|
@ -224,6 +224,7 @@ OSDK_CRATES := \
|
|||
ostd/libs/linux-bzimage/setup \
|
||||
kernel \
|
||||
kernel/comps/block \
|
||||
kernel/comps/cmdline \
|
||||
kernel/comps/console \
|
||||
kernel/comps/framebuffer \
|
||||
kernel/comps/input \
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ align_ext = { path = "../ostd/libs/align_ext" }
|
|||
aster-input = { path = "comps/input" }
|
||||
aster-block = { path = "comps/block" }
|
||||
aster-network = { path = "comps/network" }
|
||||
aster-cmdline = { path = "comps/cmdline" }
|
||||
aster-console = { path = "comps/console" }
|
||||
aster-framebuffer = { path = "comps/framebuffer" }
|
||||
aster-softirq = { path = "comps/softirq" }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "aster-cmdline"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
component = { path = "../../libs/comp-sys/component" }
|
||||
ostd = { path = "../../../ostd" }
|
||||
log = "0.4"
|
||||
spin = "0.9.4"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#![expect(unused_variables)]
|
||||
|
||||
//! The module to parse kernel command-line arguments.
|
||||
//!
|
||||
//! The format of the Asterinas command line string conforms
|
||||
|
|
@ -9,6 +7,10 @@
|
|||
//!
|
||||
//! <https://www.kernel.org/doc/html/v6.4/admin-guide/kernel-parameters.html>
|
||||
//!
|
||||
#![no_std]
|
||||
#![deny(unsafe_code)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::{
|
||||
collections::BTreeMap,
|
||||
|
|
@ -18,7 +20,7 @@ use alloc::{
|
|||
vec::Vec,
|
||||
};
|
||||
|
||||
use ostd::boot::boot_info;
|
||||
use component::{init_component, ComponentInitError};
|
||||
use spin::Once;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
|
|
@ -47,13 +49,6 @@ pub struct KCmdlineArg {
|
|||
|
||||
// Define get APIs.
|
||||
impl KCmdlineArg {
|
||||
/// Gets the singleton instance of `KCmdlineArg`.
|
||||
pub fn singleton() -> &'static KCmdlineArg {
|
||||
static INSTANCE: Once<KCmdlineArg> = Once::new();
|
||||
|
||||
INSTANCE.call_once(|| KCmdlineArg::from(boot_info().kernel_cmdline.as_str()))
|
||||
}
|
||||
|
||||
/// Gets the path of the init process.
|
||||
pub fn get_initproc_path(&self) -> Option<&str> {
|
||||
self.initproc.path.as_deref()
|
||||
|
|
@ -75,7 +70,6 @@ impl KCmdlineArg {
|
|||
}
|
||||
|
||||
/// Gets the argument vector of a kernel module.
|
||||
#[expect(dead_code)]
|
||||
pub fn get_module_args(&self, module: &str) -> Option<&Vec<ModuleArg>> {
|
||||
self.module_args.get(module)
|
||||
}
|
||||
|
|
@ -177,7 +171,7 @@ impl From<&str> for KCmdlineArg {
|
|||
// The option has a value.
|
||||
match option {
|
||||
"init" => {
|
||||
if let Some(v) = &result.initproc.path {
|
||||
if result.initproc.path.is_some() {
|
||||
panic!("[KCmdline] Init process specified twice");
|
||||
}
|
||||
result.initproc.path = Some(value.to_string());
|
||||
|
|
@ -205,3 +199,13 @@ impl From<&str> for KCmdlineArg {
|
|||
result
|
||||
}
|
||||
}
|
||||
|
||||
/// The [`KCmdlineArg`] singleton.
|
||||
pub static KCMDLINE: Once<KCmdlineArg> = Once::new();
|
||||
|
||||
#[init_component]
|
||||
fn init() -> Result<(), ComponentInitError> {
|
||||
KCMDLINE.call_once(|| KCmdlineArg::from(ostd::boot::boot_info().kernel_cmdline.as_str()));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ bitflags = "2.5"
|
|||
log = "0.4"
|
||||
spin = "0.9.4"
|
||||
aster-input = { path = "../input" }
|
||||
aster-cmdline = { path = "../cmdline" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
//! Reference: <https://wiki.osdev.org/I8042_PS/2_Controller>
|
||||
//!
|
||||
|
||||
use aster_cmdline::{ModuleArg, KCMDLINE};
|
||||
use bitflags::bitflags;
|
||||
use ostd::{
|
||||
arch::{device::io_port::ReadWriteAccess, kernel::ACPI_INFO},
|
||||
|
|
@ -129,15 +130,32 @@ impl I8042Controller {
|
|||
const DATA_PORT_ADDR: u16 = 0x60;
|
||||
const STATUS_OR_COMMAND_PORT_ADDR: u16 = 0x64;
|
||||
|
||||
if ACPI_INFO
|
||||
.get()
|
||||
.unwrap()
|
||||
.boot_flags
|
||||
.is_some_and(|flags| !flags.motherboard_implements_8042())
|
||||
{
|
||||
if !Self::is_present_acpi() {
|
||||
// The PS/2 controller does not exist. See:
|
||||
// <https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#ia-pc-boot-architecture-flags>.
|
||||
return Err(I8042ControllerError::NotPresent);
|
||||
//
|
||||
// However, it may actually be present and enumerable from other sources, such as PnP
|
||||
// devices. See:
|
||||
// <https://elixir.bootlin.com/linux/v6.18/source/drivers/input/serio/i8042-acpipnpio.h#L1578>.
|
||||
//
|
||||
// Currently, we lack the necessary support, so we allow the user to manually override
|
||||
// the ACPI flag by appending "i8042.exist" to the kernel command line.
|
||||
//
|
||||
// TODO: Add support for enumerating PnP devices and remove the command line option.
|
||||
if !Self::is_present_cmdline() {
|
||||
log::info!(
|
||||
"ACPI says i8042 controller is absent; \
|
||||
if it is incorrect, append 'i8042.exist' in cmdline to override it"
|
||||
);
|
||||
return Err(I8042ControllerError::NotPresent);
|
||||
} else {
|
||||
log::info!(
|
||||
"ACPI says i8042 controller is absent; \
|
||||
however, it is overridden by 'i8042.exist' in cmdline"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
log::info!("ACPI says i8042 controller is present");
|
||||
}
|
||||
|
||||
let controller = Self {
|
||||
|
|
@ -147,6 +165,26 @@ impl I8042Controller {
|
|||
Ok(controller)
|
||||
}
|
||||
|
||||
fn is_present_acpi() -> bool {
|
||||
ACPI_INFO
|
||||
.get()
|
||||
.unwrap()
|
||||
.boot_flags
|
||||
.is_some_and(|flags| !flags.motherboard_implements_8042())
|
||||
}
|
||||
|
||||
/// Checks if the kernel command line contains the "i8042.exist" option.
|
||||
fn is_present_cmdline() -> bool {
|
||||
!KCMDLINE
|
||||
.get()
|
||||
.unwrap()
|
||||
.get_module_args("i8042")
|
||||
.is_some_and(|args| {
|
||||
args.iter()
|
||||
.any(|arg| matches!(arg, ModuleArg::Arg(s) if s.as_bytes() == b"exist"))
|
||||
})
|
||||
}
|
||||
|
||||
fn read_configuration(&mut self) -> Result<Configuration, I8042ControllerError> {
|
||||
self.wait_and_send_command(Command::ReadConfiguration)?;
|
||||
self.wait_and_recv_data()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//!
|
||||
//! Reference: <https://www.kernel.org/doc/html/latest/admin-guide/devices.html>
|
||||
|
||||
use aster_cmdline::KCMDLINE;
|
||||
use device_id::{DeviceId, MajorId, MinorId};
|
||||
use spin::Once;
|
||||
|
||||
|
|
@ -22,7 +23,6 @@ use crate::{
|
|||
device::{Device, DeviceType},
|
||||
inode_handle::FileIo,
|
||||
},
|
||||
kcmdline::KCmdlineArg,
|
||||
prelude::*,
|
||||
process::{JobControl, Terminal},
|
||||
};
|
||||
|
|
@ -104,7 +104,9 @@ impl SystemConsole {
|
|||
|
||||
INSTANCE.call_once(|| {
|
||||
// TODO: Support specifying multiple TTY devices, e.g., "console=hvc0 console=tty0".
|
||||
let console_name = KCmdlineArg::singleton()
|
||||
let console_name = KCMDLINE
|
||||
.get()
|
||||
.unwrap()
|
||||
.get_console_names()
|
||||
.first()
|
||||
.map(String::as_str)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
//! Kernel initialization.
|
||||
|
||||
use aster_cmdline::KCMDLINE;
|
||||
use component::InitStage;
|
||||
use ostd::{
|
||||
arch::qemu::{exit_qemu, QemuExitCode},
|
||||
|
|
@ -12,7 +13,6 @@ use spin::once::Once;
|
|||
|
||||
use crate::{
|
||||
fs::{fs_resolver::FsResolver, path::MountNamespace},
|
||||
kcmdline::KCmdlineArg,
|
||||
prelude::*,
|
||||
process::{spawn_init_process, Process},
|
||||
sched::SchedPolicy,
|
||||
|
|
@ -144,7 +144,7 @@ fn first_kthread() {
|
|||
print_banner();
|
||||
|
||||
INIT_PROCESS.call_once(|| {
|
||||
let karg = KCmdlineArg::singleton();
|
||||
let karg = KCMDLINE.get().unwrap();
|
||||
spawn_init_process(
|
||||
karg.get_initproc_path().unwrap(),
|
||||
karg.get_initproc_argv().to_vec(),
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ mod events;
|
|||
mod fs;
|
||||
mod init;
|
||||
mod ipc;
|
||||
mod kcmdline;
|
||||
mod net;
|
||||
mod prelude;
|
||||
mod process;
|
||||
|
|
|
|||
Loading…
Reference in New Issue