use kernutil::StaticCell;
static CMDLINE: StaticCell<[u8; 0x1000]> = StaticCell::new([0; 0x1000]);
const BUILDIN_CMDLINE: Option<&str> = option_env!("KERNEL_BUILTIN_CMDLINE");
pub fn set_cmdline(cmdline: &str) {
let bytes = cmdline.as_bytes();
let len = bytes.len().min(CMDLINE.len() - 1);
unsafe {
CMDLINE.update(|cmd| {
cmd[..len].copy_from_slice(&bytes[..len]);
cmd[len] = 0;
});
}
}
pub fn cmdline() -> Option<&'static str> {
if CMDLINE[0] == 0 {
return BUILDIN_CMDLINE;
}
let len = CMDLINE
.iter()
.position(|&c| c == 0)
.unwrap_or(CMDLINE.len());
Some(unsafe { core::str::from_utf8_unchecked(&CMDLINE[..len]) })
}
pub fn var(key: &str) -> Option<&'static str> {
let cmdline = cmdline()?;
for pair in cmdline.split_whitespace() {
if let Some(pos) = pair.find('=') {
let (k, v) = pair.split_at(pos);
if k == key {
return Some(&v[1..]);
}
}
}
None
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct EarlyconConfig {
pub uart_type: &'static str,
pub io_type: &'static str,
pub base_addr: Option<usize>,
pub options: Option<&'static str>,
}
fn parse_earlycon_argument(val: &'static str) -> Option<EarlyconConfig> {
let s: &'static str = val.trim();
if s.is_empty() {
return None;
}
let mut parts = s.split(',');
let first_raw = parts.next()?; let first = first_raw.trim();
let uart_type: &'static str = match first {
"uart" | "uart8250" | "8250" | "ns16550" | "ns16550a" => "ns16550",
_ => first,
};
#[cfg(not(target_arch = "x86_64"))]
let mut io_type = "mmio32";
#[cfg(target_arch = "x86_64")]
let mut io_type = "io";
let mut base_addr: Option<usize> = None;
let mut options: Option<&'static str> = None;
for part in parts {
let part = part.trim();
if part.is_empty() {
continue;
}
if part.contains("io") {
io_type = part;
continue;
}
if part.starts_with("0x") {
base_addr = parse_usize(part);
continue;
}
options = Some(part);
}
Some(EarlyconConfig {
uart_type,
io_type,
base_addr,
options,
})
}
pub fn earlycon() -> Option<EarlyconConfig> {
let val = crate::cmdline::var("earlycon")?;
let config = parse_earlycon_argument(val)?;
Some(config)
}
fn parse_usize(s: &str) -> Option<usize> {
let t = s.trim();
if let Some(hex) = t.strip_prefix("0x").or_else(|| t.strip_prefix("0X")) {
usize::from_str_radix(hex, 16).ok()
} else {
t.parse::<usize>().ok()
}
}