Skip to content

Commit 2b7818e

Browse files
authored
feat: 添加对内核引导协议的抽象 (#913)
* 添加multiboot header * head.S传参增加bootloader类型 * feat: 添加引导加载协议的抽象,并为multiboot2实现这个抽象. * 把framebuffer的映射地址改为从early ioremap和mmio pool分配 * riscv64能运行
1 parent cf7f801 commit 2b7818e

File tree

42 files changed

+828
-1329
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+828
-1329
lines changed

.vscode/settings.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@
129129
"assert.h": "c",
130130
"sys_version.h": "c",
131131
"cmd.h": "c",
132-
"sleep.h": "c",
133132
"net.h": "c",
134133
"cmd_test.h": "c",
135134
"cmpxchg.h": "c",

docs/kernel/boot/bootloader.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
# 引导加载程序
22

3-
## 原理
3+
## X86_64
44

5-
  目前,DragonOS支持Legacy BIOS以及UEFI两种方式,进行启动引导。
5+
- [x] multiboot2
66

7-
  `head.S`的头部包含了Multiboot2引导头,里面标志了一些Multiboot2相关的特定信息,以及一些配置命令。
7+
## RISC-V 64
88

9-
  在DragonOS的启动初期,会存储由GRUB2传来的magic number以及multiboot2_boot_info_addr。当系统进入`Start_Kernel`函数之后,将会把这两个信息保存到multiboot2驱动程序之中。信息的具体含义请参照Multiboot2 Specification进行理解,该部分难度不大,相信读者经过思考能理解其中的原理。
9+
DragonOS在RISC-V 64上,启动流程为:
10+
11+
opensbi --> uboot --> DragonStub --> kernel
12+
13+
这个启动流程,使得DragonOS内核与具体的硬件板卡解耦,能够以同一个二进制文件,在不同的硬件板卡上启动运行。
14+
15+
16+
## 内核启动回调
17+
18+
DragonOS对内核引导加载程序进行了抽象,体现为`BootCallbacks`这个trait。
19+
不同的引导加载程序,实现对应的callback,初始化内核bootParams或者是其他的一些数据结构。
20+
21+
内核启动时,自动根据引导加载程序的类型,注册回调。并且在适当的时候,会调用这些回调函数。
1022

1123
## 参考资料
1224

docs/kernel/boot/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@
88
:caption: 目录
99

1010
bootloader
11-
multiboot2

docs/kernel/boot/multiboot2.md

Lines changed: 0 additions & 46 deletions
This file was deleted.

kernel/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ fatfs-secure = ["fatfs"]
2727

2828
# 运行时依赖项
2929
[dependencies]
30-
acpi = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "fb69243dcf" }
30+
acpi = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "282df2af7b" }
3131
asm_macros = { path = "crates/asm_macros" }
3232
atomic_enum = "=0.2.0"
3333
bit_field = "=0.10"
3434
bitfield-struct = "=0.5.3"
3535
bitflags = "=1.3.2"
3636
bitmap = { path = "crates/bitmap" }
3737
driver_base_macros = { "path" = "crates/driver_base_macros" }
38-
# 一个no_std的hashmap、hashset
3938
elf = { version = "=0.7.2", default-features = false }
4039
fdt = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt", rev = "9862813020" }
40+
# 一个no_std的hashmap、hashset
4141
hashbrown = "=0.13.2"
4242
ida = { path = "src/libs/ida" }
4343
intertrait = { path = "crates/intertrait" }
@@ -63,6 +63,7 @@ lru = "0.12.3"
6363
# target为x86_64时,使用下面的依赖
6464
[target.'cfg(target_arch = "x86_64")'.dependencies]
6565
mini-backtrace = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/mini-backtrace.git", rev = "e0b1d90940" }
66+
multiboot2 = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/multiboot2", rev = "05739aab40" }
6667
raw-cpuid = "11.0.1"
6768
x86 = "=0.52.0"
6869
x86_64 = "=0.14.10"

kernel/src/arch/riscv64/driver/sbi.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use core::ptr::addr_of;
2+
13
/// 向控制台打印字符串。
24
///
35
/// 该函数接受一个字节切片 `s` 作为输入,并迭代切片中的每个字节 `c`。
@@ -75,7 +77,7 @@ impl SbiDriver {
7577

7678
/// 获取probe得到的SBI扩展信息。
7779
pub fn extensions() -> &'static SBIExtensions {
78-
unsafe { &EXTENSIONS }
80+
unsafe { addr_of!(EXTENSIONS).as_ref().unwrap() }
7981
}
8082

8183
fn probe_extensions() -> SBIExtensions {

kernel/src/arch/riscv64/init/boot.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use system_error::SystemError;
2+
3+
use super::dragonstub::early_dragonstub_init;
4+
5+
#[derive(Debug)]
6+
#[repr(u64)]
7+
pub(super) enum BootProtocol {
8+
DragonStub = 1,
9+
}
10+
11+
pub(super) fn early_boot_init(protocol: BootProtocol) -> Result<(), SystemError> {
12+
match protocol {
13+
BootProtocol::DragonStub => early_dragonstub_init(),
14+
}
15+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use alloc::string::String;
2+
use system_error::SystemError;
3+
4+
use crate::{
5+
driver::video::fbdev::base::BootTimeScreenInfo,
6+
init::boot::{register_boot_callbacks, BootCallbacks, BootloaderAcpiArg},
7+
};
8+
9+
pub(super) fn early_dragonstub_init() -> Result<(), SystemError> {
10+
register_boot_callbacks(&DragonStubCallBack);
11+
Ok(())
12+
}
13+
14+
struct DragonStubCallBack;
15+
16+
impl BootCallbacks for DragonStubCallBack {
17+
fn init_bootloader_name(&self) -> Result<Option<String>, SystemError> {
18+
Ok(format!("DragonStub").into())
19+
}
20+
21+
fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError> {
22+
Ok(BootloaderAcpiArg::NotProvided)
23+
}
24+
25+
fn init_kernel_cmdline(&self) -> Result<(), SystemError> {
26+
// parsed in `early_init_scan_chosen()`
27+
Ok(())
28+
}
29+
30+
fn early_init_framebuffer_info(
31+
&self,
32+
_scinfo: &mut BootTimeScreenInfo,
33+
) -> Result<(), SystemError> {
34+
unimplemented!("dragonstub early_init_framebuffer_info")
35+
}
36+
37+
fn early_init_memory_blocks(&self) -> Result<(), SystemError> {
38+
// parsed in `early_init_scan_memory()` and uefi driver
39+
Ok(())
40+
}
41+
}

kernel/src/arch/riscv64/init/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ use log::{debug, info};
33
use system_error::SystemError;
44

55
use crate::{
6-
arch::{driver::sbi::SbiDriver, mm::init::mm_early_init},
6+
arch::{
7+
driver::sbi::SbiDriver,
8+
init::boot::{early_boot_init, BootProtocol},
9+
mm::init::mm_early_init,
10+
},
711
driver::{firmware::efi::init::efi_init, open_firmware::fdt::open_firmware_fdt_driver},
812
init::{boot_params, init::start_kernel},
913
mm::{memblock::mem_block_manager, PhysAddr, VirtAddr},
@@ -13,6 +17,9 @@ use crate::{
1317

1418
use super::{cpu::init_local_context, interrupt::entry::handle_exception};
1519

20+
mod boot;
21+
mod dragonstub;
22+
1623
#[derive(Debug)]
1724
pub struct ArchBootParams {
1825
/// 启动时的fdt物理地址
@@ -119,6 +126,7 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
119126
"DragonOS kernel is running on hart {}, fdt address:{:?}",
120127
hartid, fdt_paddr
121128
);
129+
early_boot_init(BootProtocol::DragonStub).expect("Failed to init boot protocol!");
122130
mm_early_init();
123131

124132
print_node(fdt.find_node("/").unwrap(), 0);

kernel/src/arch/riscv64/rand.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
pub fn rand() -> usize {
2-
unimplemented!("RiscV64 rand");
2+
static mut SEED: u64 = 0xdead_beef_cafe_babe;
3+
let mut buf = [0u8; size_of::<usize>()];
4+
for x in buf.iter_mut() {
5+
unsafe {
6+
// from musl
7+
SEED = SEED.wrapping_mul(0x5851_f42d_4c95_7f2d);
8+
*x = (SEED >> 33) as u8;
9+
}
10+
}
11+
let x: usize = unsafe { core::mem::transmute(buf) };
12+
return x;
313
}

0 commit comments

Comments
 (0)