Uses clap builder to parse kernel arguments (#865)

This commit is contained in:
Putta Khunchalee 2024-05-19 18:47:10 +07:00 committed by GitHub
parent 4512e9cc24
commit c0ffb96b16
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 102 additions and 37 deletions

93
src/kernel/src/args.rs Normal file
View File

@ -0,0 +1,93 @@
use crate::idps::ConsoleId;
use clap::{command, value_parser, Arg, ArgAction};
use serde::Deserialize;
use std::io::Read;
use std::path::PathBuf;
/// Kernel arguments loaded from either `.kernel-debug` or command line arguments.
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Args {
pub system: PathBuf,
pub game: PathBuf,
pub debug_dump: Option<PathBuf>,
#[serde(default)]
pub clear_debug_dump: bool,
#[serde(default)]
pub pro: bool,
#[serde(default)]
pub idps: ConsoleId,
}
impl Args {
pub fn from_file(file: impl Read) -> Result<Self, serde_yaml::Error> {
serde_yaml::from_reader(file)
}
pub fn from_command_line() -> Self {
// Parse.
let args = command!()
.arg(
Arg::new("pro")
.help("Enable PS4 Pro mode (AKA Neo mode)")
.long("pro")
.alias("neo")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("idps")
.help("IDPS to use (AKA Console ID)")
.long("idps")
.value_name("IDPS")
.value_parser(value_parser!(ConsoleId)),
)
.arg(
Arg::new("debug_dump")
.help("Path to a directory to write debug information")
.long("debug-dump")
.value_name("PATH")
.value_parser(value_parser!(PathBuf)),
)
.arg(
Arg::new("clear_debug_dump")
.help("Clear all previous files in the debug dump directory")
.long("clear-debug-dump")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("system")
.help("Path to a directory contains PS4 firmware to use")
.value_name("SYSTEM")
.value_parser(value_parser!(PathBuf))
.required(true),
)
.arg(
Arg::new("game")
.help("Path to an installed PS4 game to use")
.value_name("GAME")
.value_parser(value_parser!(PathBuf))
.required(true),
)
.get_matches();
// Process.
let system = args.get_one::<PathBuf>("system").unwrap().clone();
let game = args.get_one::<PathBuf>("game").unwrap().clone();
let debug_dump = args.get_one("debug_dump").cloned();
let clear_debug_dump = args.get_flag("clear_debug_dump");
let pro = args.get_flag("pro");
let idps = args
.get_one::<ConsoleId>("idps")
.cloned()
.unwrap_or_default();
Self {
system,
game,
debug_dump,
clear_debug_dump,
pro,
idps,
}
}
}

View File

@ -1,9 +1,10 @@
use crate::arch::MachDep;
use crate::args::Args;
use crate::budget::{Budget, BudgetManager, ProcType};
use crate::dev::{
CameraInitError, CameraManager, DceManager, DebugManager, DebugManagerInitError,
DipswInitError, DipswManager, DmemContainer, GcInitError, GcManager, HmdManager, RngInitError,
RngManager, SblSrvManager, TtyManager, TtyManagerInitError,
CameraInitError, CameraManager, DceInitError, DceManager, DebugManager, DebugManagerInitError,
DipswInitError, DipswManager, DmemContainer, GcInitError, GcManager, HmdInitError, HmdManager,
RngInitError, RngManager, SblSrvInitError, SblSrvManager, TtyManager, TtyManagerInitError,
};
use crate::dmem::{DmemManager, DmemManagerInitError};
use crate::ee::native::NativeEngine;
@ -11,7 +12,6 @@ use crate::ee::EntryArg;
use crate::errno::EEXIST;
use crate::fs::{Fs, FsInitError, MkdirError, MountError, MountFlags, MountOpts, VPath, VPathBuf};
use crate::hv::Hypervisor;
use crate::idps::ConsoleId;
use crate::kqueue::KernelQueueManager;
use crate::log::{print, LOGGER};
use crate::namedobj::NamedObjManager;
@ -28,12 +28,9 @@ use crate::sysctl::Sysctl;
use crate::time::TimeManager;
use crate::ucred::{AuthAttrs, AuthCaps, AuthInfo, AuthPaid, Gid, Ucred, Uid};
use crate::umtx::UmtxManager;
use clap::Parser;
use dev::{DceInitError, HmdInitError, SblSrvInitError};
use llt::{OsThread, SpawnError};
use macros::vpath;
use param::Param;
use serde::Deserialize;
use std::error::Error;
use std::fs::{create_dir_all, remove_dir_all, File};
use std::io::Write;
@ -45,6 +42,7 @@ use sysinfo::{MemoryRefreshKind, System};
use thiserror::Error;
mod arch;
mod args;
mod arnd;
mod budget;
mod dev;
@ -87,7 +85,7 @@ fn main() -> ExitCode {
}
};
match serde_yaml::from_reader(file) {
match Args::from_file(file) {
Ok(v) => v,
Err(e) => {
eprintln!("Failed to parse {}: {}.", path.display(), e);
@ -95,7 +93,7 @@ fn main() -> ExitCode {
}
}
} else {
Args::parse()
Args::from_command_line()
};
// Run the kernel.
@ -581,32 +579,6 @@ fn join_thread(thr: OsThread) -> Result<(), std::io::Error> {
Ok(())
}
#[derive(Parser, Deserialize)]
#[command(about)]
#[serde(rename_all = "kebab-case")]
struct Args {
#[arg(long)]
system: PathBuf,
#[arg(long)]
game: PathBuf,
#[arg(long)]
debug_dump: Option<PathBuf>,
#[arg(long)]
#[serde(default)]
clear_debug_dump: bool,
#[arg(long)]
#[serde(default)]
pro: bool,
#[arg(long)]
#[serde(default)]
idps: ConsoleId,
}
#[derive(Debug, Error)]
enum DiscordPresenceError {
#[error("failed to create Discord IPC")]

View File

@ -392,10 +392,10 @@ void MainWindow::startGame(const QModelIndex &index)
// Setup kernel arguments.
QStringList args;
args << "--system" << readSystemDirectorySetting();
args << "--game" << game->directory();
args << "--debug-dump" << kernelDebugDump();
args << "--clear-debug-dump";
args << readSystemDirectorySetting();
args << game->directory();
// Setup environment variable.
auto env = QProcessEnvironment::systemEnvironment();