源码仓库:https://gitee.com/openeuler/sysmaster
Linux的启动流程大致如下:
MBR:MBR(Master Boot Record)是硬盘上一段重要的引导代码区域,位于硬盘的第一个扇区(通常是第0号扇区,即第512字节的位置)。这个扇区包含了引导加载程序(boot loader)以及分区表(partition table),用于告诉计算机操作系统的位置。
GRUB:GRUB(GNU GRand Unified Bootloader)是一种广泛使用的引导加载程序(boot loader),主要用于 Unix-like 操作系统,如 Linux 和 BSD。
Init是OS的初始化过程,最常见的就是systemd,但是其代码量大并且性能一般,所以有了sysMaster
sysMaster共有init、core、exts三个部分:
// main函数位于sysmaster/init/main.rs
fn main() -> std::io::Result<()> {
setup_mount_early();
log::init_log_to_kmsg_console("sysmaster-init", log::Level::Info);
prepare_init();
reset_all_signal_handlers();
install_crash_handler();
let mut rt = Runtime::new()?;
rt.set_state(InitState::Running);
rt.runloop()?;
if rt.is_reexec() {
rt.reexec();
}
shutdown_init();
Ok(())
}
setup_mount_early
init_log_to_kmsg_console
prepare_init
reset_all_signal_handlers
install_crash_handler
Runtime
core部分实现了很多核心功能,这里拿sctl(systemctl)为例:
// main函数位于sysmaster/core/sctl/src/main.rs
fn main() {
let args = parse_args();
let command_request = match generate_command_request(args) {
None => {
eprintln!("This command is currently not supported");
exit(nix::Error::ENOTSUP as i32);
}
Some(v) => v,
};
let stream = match UnixStream::connect(PRIVATE_SOCKET) {
Err(e) => {
eprintln!("Failed to connect to sysmaster: {}", e);
exit(e.raw_os_error().unwrap());
}
Ok(v) => v,
};
let mut client = ProstClientStream::new(stream);
let data = match client.execute(command_request) {
Err(e) => {
eprintln!("Failed to execute the given command: {}", e);
exit(1);
}
Ok(v) => v,
};
/* We should always print the error message if the returned error code is not 0. */
if data.message.is_empty() {
exit(0);
}
if data.error_code == 0 || (data.error_code & ERROR_CODE_MASK_PRINT_STDOUT != 0) {
/* Don't care if we fail to write the message out. */
let _ = writeln!(std::io::stdout(), "{}", data.message);
} else {
eprintln!("{}", data.message);
}
exit((data.error_code & !ERROR_CODE_MASK_PRINT_STDOUT) as i32);
}
exts下有devmaster(设备初始化和管理)、fstab(定义系统上的文件系统如何挂载)、getty-generator(生成getty配置或脚本的工具,getty用来初始化终端登录)、hostname_setup(配置主机名)、hwdb(硬件数据库)、libudev(设备管理器的库文件)、libudev_macro(支持libudev使用)、machine-id-setup(生成机器唯一标识符)、random_seed(随机数生成器)、rc-local-generator(Linux启动脚本)、run(存放运行时状态)、switch_root(与切换根文件系统相关)和sysmonitor(监控系统状态)
这里以random_seed为例:
// main函数位于sysmaster/exts/random_seed/src/main.rs
fn main() {
log::init_log_to_console_syslog("random-seed", log::Level::Debug);
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
log::error!("{}", "This program requires one argument.");
process::exit(1);
}
unsafe {
libc::umask(0o022);
}
if let Err(str) = run(&args[1]) {
log::error!("{}", str);
process::exit(1);
}
process::exit(0);
}