mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
refacotr: remove all c files (#1131)
* refacotr: remove all c files Use Rust to implement the symbol table generator. Delete unused header files and c files Adjust the makefile in the debug directory Signed-off-by: Godones <chenlinfeng25@outlook.com> * fix: remove extern "C" rs_* functions move gen_kallsyms.rs to build-scripts Signed-off-by: Godones <chenlinfeng25@outlook.com>
This commit is contained in:
parent
2d06264d79
commit
1485456bf3
139
.vscode/settings.json
vendored
139
.vscode/settings.json
vendored
@ -1,143 +1,6 @@
|
|||||||
{
|
{
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"stdbool.h": "c",
|
|
||||||
"printk.h": "c",
|
|
||||||
"stdarg.h": "c",
|
|
||||||
"process.h": "c",
|
|
||||||
"cpu.h": "c",
|
|
||||||
"mm.h": "c",
|
|
||||||
"glib.h": "c",
|
|
||||||
"asm.h": "c",
|
"asm.h": "c",
|
||||||
"memory.h": "c",
|
|
||||||
"kprint.h": "c",
|
|
||||||
"ptrace.h": "c",
|
|
||||||
"mouse.h": "c",
|
|
||||||
"algorithm": "c",
|
|
||||||
"array": "c",
|
|
||||||
"atomic": "c",
|
|
||||||
"*.tcc": "c",
|
|
||||||
"bitset": "c",
|
|
||||||
"cassert": "c",
|
|
||||||
"cctype": "c",
|
|
||||||
"cerrno": "c",
|
|
||||||
"chrono": "c",
|
|
||||||
"climits": "c",
|
|
||||||
"clocale": "c",
|
|
||||||
"cmath": "c",
|
|
||||||
"codecvt": "c",
|
|
||||||
"condition_variable": "c",
|
|
||||||
"cstdarg": "c",
|
|
||||||
"cstddef": "c",
|
|
||||||
"cstdint": "c",
|
|
||||||
"cstdio": "c",
|
|
||||||
"cstdlib": "c",
|
|
||||||
"cstring": "c",
|
|
||||||
"ctime": "c",
|
|
||||||
"cwchar": "c",
|
|
||||||
"cwctype": "c",
|
|
||||||
"deque": "c",
|
|
||||||
"exception": "c",
|
|
||||||
"forward_list": "c",
|
|
||||||
"functional": "c",
|
|
||||||
"iterator": "c",
|
|
||||||
"list": "c",
|
|
||||||
"map": "c",
|
|
||||||
"memory": "c",
|
|
||||||
"memory_resource": "c",
|
|
||||||
"numeric": "c",
|
|
||||||
"optional": "c",
|
|
||||||
"random": "c",
|
|
||||||
"ratio": "c",
|
|
||||||
"set": "c",
|
|
||||||
"string": "c",
|
|
||||||
"string_view": "c",
|
|
||||||
"system_error": "c",
|
|
||||||
"tuple": "c",
|
|
||||||
"type_traits": "c",
|
|
||||||
"unordered_map": "c",
|
|
||||||
"utility": "c",
|
|
||||||
"vector": "c",
|
|
||||||
"fstream": "c",
|
|
||||||
"initializer_list": "c",
|
|
||||||
"ios": "c",
|
|
||||||
"iosfwd": "c",
|
|
||||||
"istream": "c",
|
|
||||||
"limits": "c",
|
|
||||||
"locale": "c",
|
|
||||||
"mutex": "c",
|
|
||||||
"new": "c",
|
|
||||||
"ostream": "c",
|
|
||||||
"queue": "c",
|
|
||||||
"sstream": "c",
|
|
||||||
"stdexcept": "c",
|
|
||||||
"streambuf": "c",
|
|
||||||
"thread": "c",
|
|
||||||
"cinttypes": "c",
|
|
||||||
"cstdbool": "c",
|
|
||||||
"typeinfo": "c",
|
|
||||||
"unistd.h": "c",
|
|
||||||
"stdint.h": "c",
|
|
||||||
"syscall.h": "c",
|
|
||||||
"fcntl.h": "c",
|
|
||||||
"types.h": "c",
|
|
||||||
"string.h": "c",
|
|
||||||
"math.h": "c",
|
|
||||||
"arch.h": "c",
|
|
||||||
"stdio.h": "c",
|
|
||||||
"wait_queue.h": "c",
|
|
||||||
"stddef.h": "c",
|
|
||||||
"spinlock.h": "c",
|
|
||||||
"stat.h": "c",
|
|
||||||
"video.h": "c",
|
|
||||||
"ahci.h": "c",
|
|
||||||
"slab.h": "c",
|
|
||||||
"boot_info.h": "c",
|
|
||||||
"pci.h": "c",
|
|
||||||
"time.h": "c",
|
|
||||||
"errno.h": "c",
|
|
||||||
"bug.h": "c",
|
|
||||||
"sched.h": "c",
|
|
||||||
"preempt.h": "c",
|
|
||||||
"textui.h": "c",
|
|
||||||
"atomic.h": "c",
|
|
||||||
"semaphore.h": "c",
|
|
||||||
"mm-types.h": "c",
|
|
||||||
"current.h": "c",
|
|
||||||
"traceback.h": "c",
|
|
||||||
"bitcount.h": "c",
|
|
||||||
"limits.h": "c",
|
|
||||||
"mutex.h": "c",
|
|
||||||
"mount.h": "c",
|
|
||||||
"internal.h": "c",
|
|
||||||
"compiler_attributes.h": "c",
|
|
||||||
"timer.h": "c",
|
|
||||||
"hid.h": "c",
|
|
||||||
"compiler.h": "c",
|
|
||||||
"err.h": "c",
|
|
||||||
"list.h": "c",
|
|
||||||
"irqflags.h": "c",
|
|
||||||
"dirent.h": "c",
|
|
||||||
"cmd_help.h": "c",
|
|
||||||
"wait.h": "c",
|
|
||||||
"ctype.h": "c",
|
|
||||||
"stdint-gcc.h": "c",
|
|
||||||
"acpi.h": "c",
|
|
||||||
"assert.h": "c",
|
|
||||||
"sys_version.h": "c",
|
|
||||||
"cmd.h": "c",
|
|
||||||
"net.h": "c",
|
|
||||||
"cmd_test.h": "c",
|
|
||||||
"cmpxchg.h": "c",
|
|
||||||
"mman.h": "c",
|
|
||||||
"clocksource.h": "c",
|
|
||||||
"ata.h": "c",
|
|
||||||
"barrier": "c",
|
|
||||||
"charconv": "c",
|
|
||||||
"printf.h": "c",
|
|
||||||
"klog.h": "c",
|
|
||||||
"malloc.h": "c",
|
|
||||||
"*.o": "c",
|
|
||||||
"k_log.h": "c"
|
|
||||||
},
|
},
|
||||||
"C_Cpp.errorSquiggles": "enabled",
|
"C_Cpp.errorSquiggles": "enabled",
|
||||||
"esbonio.sphinx.confDir": "",
|
"esbonio.sphinx.confDir": "",
|
||||||
@ -145,14 +8,12 @@
|
|||||||
"rust-analyzer.linkedProjects": [
|
"rust-analyzer.linkedProjects": [
|
||||||
"./kernel/Cargo.toml",
|
"./kernel/Cargo.toml",
|
||||||
//"./tools/Cargo.toml",
|
//"./tools/Cargo.toml",
|
||||||
|
|
||||||
],
|
],
|
||||||
// "rust-analyzer.cargo.target": "riscv64gc-unknown-none-elf",
|
// "rust-analyzer.cargo.target": "riscv64gc-unknown-none-elf",
|
||||||
"rust-analyzer.cargo.target": "x86_64-unknown-none",
|
"rust-analyzer.cargo.target": "x86_64-unknown-none",
|
||||||
"rust-analyzer.check.overrideCommand": [
|
"rust-analyzer.check.overrideCommand": [
|
||||||
"make",
|
"make",
|
||||||
"check",
|
"check",
|
||||||
|
|
||||||
],
|
],
|
||||||
"makefile.configureOnOpen": false,
|
"makefile.configureOnOpen": false,
|
||||||
}
|
}
|
19
build-scripts/Cargo.lock
generated
19
build-scripts/Cargo.lock
generated
@ -1,6 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
@ -87,12 +87,6 @@ version = "1.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "elf"
|
|
||||||
version = "0.7.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@ -109,6 +103,10 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gen_kallsyms"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glob"
|
name = "glob"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -193,13 +191,6 @@ version = "0.4.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
|
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "linux_boot_helper"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"elf",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.20"
|
version = "0.4.20"
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = ["gen_kallsyms", "kernel_build"]
|
||||||
"kernel_build",
|
|
||||||
]
|
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
.PHONY: fmt
|
all:
|
||||||
|
@cargo +nightly-2024-11-05 build --release -p gen_kallsyms
|
||||||
fmt:
|
fmt:
|
||||||
cargo fmt --all $(FMT_CHECK)
|
cargo fmt --all $(FMT_CHECK)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@cargo clean
|
@cargo clean
|
||||||
check:
|
check:
|
||||||
@cargo +nightly-2024-11-05 check --workspace $(CARGO_ZBUILD) --message-format=json
|
@cargo +nightly-2024-11-05 check --workspace $(CARGO_ZBUILD) --message-format=json
|
||||||
|
.PHONY: fmt
|
6
build-scripts/gen_kallsyms/Cargo.toml
Normal file
6
build-scripts/gen_kallsyms/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "gen_kallsyms"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
122
build-scripts/gen_kallsyms/src/main.rs
Normal file
122
build-scripts/gen_kallsyms/src/main.rs
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
use std::str;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct KernelSymbolEntry {
|
||||||
|
vaddr: u64,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
symbol_type: char,
|
||||||
|
symbol: String,
|
||||||
|
symbol_length: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn symbol_to_write(vaddr: u64, text_vaddr: u64, etext_vaddr: u64) -> bool {
|
||||||
|
vaddr >= text_vaddr && vaddr <= etext_vaddr
|
||||||
|
}
|
||||||
|
fn read_symbol(line: &str) -> Option<KernelSymbolEntry> {
|
||||||
|
if line.len() > 512 {
|
||||||
|
return None;
|
||||||
|
} // skip line with length >= 512
|
||||||
|
let mut parts = line.split_whitespace();
|
||||||
|
let vaddr = u64::from_str_radix(parts.next()?, 16).ok()?;
|
||||||
|
let symbol_type = parts.next()?.chars().next()?;
|
||||||
|
let symbol = parts.collect::<Vec<_>>().join(" ");
|
||||||
|
if symbol_type != 'T' && symbol_type != 't' {
|
||||||
|
return None;
|
||||||
|
} // local symbol or global symbol in text section
|
||||||
|
if symbol == "$x" {
|
||||||
|
return None;
|
||||||
|
} // skip $x symbol
|
||||||
|
let symbol_length = symbol.len() + 1; // +1 for null terminator
|
||||||
|
Some(KernelSymbolEntry {
|
||||||
|
vaddr,
|
||||||
|
symbol_type,
|
||||||
|
symbol,
|
||||||
|
symbol_length,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_map() -> (Vec<KernelSymbolEntry>, u64, u64) {
|
||||||
|
let mut symbol_table = Vec::new();
|
||||||
|
let mut text_vaddr = 0;
|
||||||
|
let mut etext_vaddr = 0;
|
||||||
|
let mut line = String::new();
|
||||||
|
loop {
|
||||||
|
let size = std::io::stdin().read_line(&mut line).unwrap();
|
||||||
|
if size == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
line = line.trim().to_string();
|
||||||
|
if let Some(entry) = read_symbol(&line) {
|
||||||
|
if entry.symbol.starts_with("_text") {
|
||||||
|
text_vaddr = entry.vaddr;
|
||||||
|
} else if entry.symbol.starts_with("_etext") {
|
||||||
|
etext_vaddr = entry.vaddr;
|
||||||
|
}
|
||||||
|
symbol_table.push(entry);
|
||||||
|
}
|
||||||
|
line.clear();
|
||||||
|
}
|
||||||
|
(symbol_table, text_vaddr, etext_vaddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_result(symbol_table: &[KernelSymbolEntry], text_vaddr: u64, etext_vaddr: u64) {
|
||||||
|
println!(".section .rodata\n");
|
||||||
|
println!(".global kallsyms_address");
|
||||||
|
println!(".align 8\n");
|
||||||
|
println!("kallsyms_address:");
|
||||||
|
|
||||||
|
let mut last_vaddr = 0;
|
||||||
|
let mut total_syms_to_write = 0;
|
||||||
|
|
||||||
|
for entry in symbol_table {
|
||||||
|
if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\t.quad\t{:#x}", entry.vaddr);
|
||||||
|
total_syms_to_write += 1;
|
||||||
|
last_vaddr = entry.vaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\n.global kallsyms_num");
|
||||||
|
println!(".align 8");
|
||||||
|
println!("kallsyms_num:");
|
||||||
|
println!("\t.quad\t{}", total_syms_to_write);
|
||||||
|
|
||||||
|
println!("\n.global kallsyms_names_index");
|
||||||
|
println!(".align 8");
|
||||||
|
println!("kallsyms_names_index:");
|
||||||
|
|
||||||
|
let mut position = 0;
|
||||||
|
last_vaddr = 0;
|
||||||
|
|
||||||
|
for entry in symbol_table {
|
||||||
|
if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\t.quad\t{}", position);
|
||||||
|
position += entry.symbol_length;
|
||||||
|
last_vaddr = entry.vaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\n.global kallsyms_names");
|
||||||
|
println!(".align 8");
|
||||||
|
println!("kallsyms_names:");
|
||||||
|
|
||||||
|
last_vaddr = 0;
|
||||||
|
|
||||||
|
for entry in symbol_table {
|
||||||
|
if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\t.asciz\t\"{}\"", entry.symbol);
|
||||||
|
last_vaddr = entry.vaddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let (symbol_table, text_vaddr, etext_vaddr) = read_map();
|
||||||
|
generate_result(&symbol_table, text_vaddr, etext_vaddr);
|
||||||
|
}
|
@ -1,20 +0,0 @@
|
|||||||
use crate::utils::cargo_handler::{CargoHandler, TargetArch};
|
|
||||||
|
|
||||||
use self::x86_64::X86_64BindgenArch;
|
|
||||||
|
|
||||||
pub mod riscv64;
|
|
||||||
pub mod x86_64;
|
|
||||||
|
|
||||||
pub(super) trait BindgenArch {
|
|
||||||
fn generate_bindings(&self, builder: bindgen::Builder) -> bindgen::Builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 获取当前的bindgen架构;
|
|
||||||
pub(super) fn current_bindgenarch() -> &'static dyn BindgenArch {
|
|
||||||
let arch = CargoHandler::target_arch();
|
|
||||||
match arch {
|
|
||||||
TargetArch::X86_64 => &X86_64BindgenArch,
|
|
||||||
TargetArch::Riscv64 => &riscv64::RiscV64BindgenArch,
|
|
||||||
_ => panic!("Unsupported arch: {:?}", arch),
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
use super::BindgenArch;
|
|
||||||
|
|
||||||
pub struct RiscV64BindgenArch;
|
|
||||||
impl BindgenArch for RiscV64BindgenArch {
|
|
||||||
fn generate_bindings(&self, builder: bindgen::Builder) -> bindgen::Builder {
|
|
||||||
builder
|
|
||||||
.clang_arg("-I./src/arch/riscv64/include")
|
|
||||||
.clang_arg("--target=riscv64-none-none-elf")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
use super::BindgenArch;
|
|
||||||
|
|
||||||
pub struct X86_64BindgenArch;
|
|
||||||
|
|
||||||
impl BindgenArch for X86_64BindgenArch {
|
|
||||||
fn generate_bindings(&self, builder: bindgen::Builder) -> bindgen::Builder {
|
|
||||||
builder
|
|
||||||
.clang_arg("-I./src/arch/x86_64/include")
|
|
||||||
.clang_arg("--target=x86_64-none-none")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
use std::{path::PathBuf, str::FromStr};
|
|
||||||
|
|
||||||
use crate::{bindgen::arch::current_bindgenarch, utils::cargo_handler::CargoHandler};
|
|
||||||
|
|
||||||
mod arch;
|
|
||||||
|
|
||||||
/// 生成 C->Rust bindings
|
|
||||||
pub fn generate_bindings() {
|
|
||||||
let wrapper_h = PathBuf::from_str("src/include/bindings/wrapper.h")
|
|
||||||
.expect("Failed to parse 'wrapper.h' path");
|
|
||||||
CargoHandler::emit_rerun_if_files_changed(&[wrapper_h.clone()]);
|
|
||||||
|
|
||||||
let out_path = PathBuf::from(String::from("src/include/bindings/"));
|
|
||||||
|
|
||||||
// The bindgen::Builder is the main entry point
|
|
||||||
// to bindgen, and lets you build up options for
|
|
||||||
// the resulting bindings.
|
|
||||||
|
|
||||||
let builder = bindgen::Builder::default()
|
|
||||||
.clang_arg("-I./src")
|
|
||||||
.clang_arg("-I./src/include")
|
|
||||||
// The input header we would like to generate
|
|
||||||
// bindings for.
|
|
||||||
.header(wrapper_h.to_str().unwrap())
|
|
||||||
.blocklist_file("src/include/bindings/bindings.h")
|
|
||||||
.clang_arg("-v")
|
|
||||||
// 使用core,并将c语言的类型改为core::ffi,而不是使用std库。
|
|
||||||
.use_core()
|
|
||||||
.ctypes_prefix("::core::ffi")
|
|
||||||
.generate_inline_functions(true)
|
|
||||||
.raw_line("#![allow(dead_code)]")
|
|
||||||
.raw_line("#![allow(non_upper_case_globals)]")
|
|
||||||
.raw_line("#![allow(non_camel_case_types)]")
|
|
||||||
// Tell cargo to invalidate the built crate whenever any of the
|
|
||||||
// included header files changed.
|
|
||||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks));
|
|
||||||
|
|
||||||
// 处理架构相关的绑定
|
|
||||||
let builder = current_bindgenarch().generate_bindings(builder);
|
|
||||||
|
|
||||||
// Finish the builder and generate the bindings.
|
|
||||||
let bindings = builder
|
|
||||||
.generate()
|
|
||||||
// Unwrap the Result and panic on failure.
|
|
||||||
.expect("Unable to generate bindings");
|
|
||||||
|
|
||||||
bindings
|
|
||||||
.write_to_file(out_path.join("bindings.rs"))
|
|
||||||
.expect("Couldn't write bindings!");
|
|
||||||
}
|
|
@ -12,11 +12,8 @@ pub mod x86_64;
|
|||||||
pub(super) trait CFilesArch {
|
pub(super) trait CFilesArch {
|
||||||
/// 设置架构相关的宏定义
|
/// 设置架构相关的宏定义
|
||||||
fn setup_defines(&self, c: &mut Build);
|
fn setup_defines(&self, c: &mut Build);
|
||||||
/// 设置架构相关的全局包含目录
|
|
||||||
fn setup_global_include_dir(&self, c: &mut HashSet<PathBuf>);
|
|
||||||
/// 设置需要编译的架构相关的文件
|
/// 设置需要编译的架构相关的文件
|
||||||
fn setup_files(&self, c: &mut Build, files: &mut HashSet<PathBuf>);
|
fn setup_files(&self, c: &mut Build, files: &mut HashSet<PathBuf>);
|
||||||
|
|
||||||
/// 设置架构相关的全局编译标志
|
/// 设置架构相关的全局编译标志
|
||||||
fn setup_global_flags(&self, c: &mut Build);
|
fn setup_global_flags(&self, c: &mut Build);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use std::{collections::HashSet, path::PathBuf};
|
|
||||||
|
|
||||||
use crate::{constant::ARCH_DIR_RISCV64, utils::FileUtils};
|
|
||||||
|
|
||||||
use super::CFilesArch;
|
use super::CFilesArch;
|
||||||
|
use std::{collections::HashSet, path::PathBuf};
|
||||||
|
|
||||||
pub(super) struct RiscV64CFilesArch;
|
pub(super) struct RiscV64CFilesArch;
|
||||||
|
|
||||||
@ -12,18 +9,8 @@ impl CFilesArch for RiscV64CFilesArch {
|
|||||||
c.define("__riscv", None);
|
c.define("__riscv", None);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_global_include_dir(&self, include_dirs: &mut HashSet<PathBuf>) {
|
|
||||||
include_dirs.insert("src/arch/riscv64/include".into());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setup_files(&self, _c: &mut cc::Build, files: &mut HashSet<PathBuf>) {
|
fn setup_files(&self, _c: &mut cc::Build, files: &mut HashSet<PathBuf>) {
|
||||||
files.insert(PathBuf::from("src/arch/riscv64/asm/head.S"));
|
files.insert(PathBuf::from("src/arch/riscv64/asm/head.S"));
|
||||||
|
|
||||||
FileUtils::list_all_files(&arch_path("asm"), Some("c"), true)
|
|
||||||
.into_iter()
|
|
||||||
.for_each(|f| {
|
|
||||||
files.insert(f);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_global_flags(&self, c: &mut cc::Build) {
|
fn setup_global_flags(&self, c: &mut cc::Build) {
|
||||||
@ -37,7 +24,3 @@ impl CFilesArch for RiscV64CFilesArch {
|
|||||||
c.flag("-march=rv64gc");
|
c.flag("-march=rv64gc");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arch_path(relative_path: &str) -> PathBuf {
|
|
||||||
PathBuf::from(format!("{}/{}", ARCH_DIR_RISCV64, relative_path))
|
|
||||||
}
|
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
use std::{collections::HashSet, path::PathBuf};
|
|
||||||
|
|
||||||
use cc::Build;
|
|
||||||
|
|
||||||
use crate::{constant::ARCH_DIR_X86_64, utils::FileUtils};
|
|
||||||
|
|
||||||
use super::CFilesArch;
|
use super::CFilesArch;
|
||||||
|
use cc::Build;
|
||||||
|
use std::{collections::HashSet, path::PathBuf};
|
||||||
|
|
||||||
pub(super) struct X86_64CFilesArch;
|
pub(super) struct X86_64CFilesArch;
|
||||||
|
|
||||||
@ -13,20 +9,7 @@ impl CFilesArch for X86_64CFilesArch {
|
|||||||
c.define("__x86_64__", None);
|
c.define("__x86_64__", None);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_global_include_dir(&self, include_dirs: &mut HashSet<PathBuf>) {
|
|
||||||
include_dirs.insert("src/arch/x86_64/include".into());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setup_files(&self, _c: &mut Build, files: &mut HashSet<PathBuf>) {
|
fn setup_files(&self, _c: &mut Build, files: &mut HashSet<PathBuf>) {
|
||||||
const DIRS: [&str; 4] = ["driver/apic", "init", "asm", "interrupt"];
|
|
||||||
DIRS.iter().for_each(|dir| {
|
|
||||||
FileUtils::list_all_files(&arch_path(dir), Some("c"), true)
|
|
||||||
.into_iter()
|
|
||||||
.for_each(|f| {
|
|
||||||
files.insert(f);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// setup asm files
|
// setup asm files
|
||||||
files.insert(PathBuf::from("src/arch/x86_64/asm/head.S"));
|
files.insert(PathBuf::from("src/arch/x86_64/asm/head.S"));
|
||||||
files.insert(PathBuf::from("src/arch/x86_64/asm/entry.S"));
|
files.insert(PathBuf::from("src/arch/x86_64/asm/entry.S"));
|
||||||
@ -39,7 +22,3 @@ impl CFilesArch for X86_64CFilesArch {
|
|||||||
c.flag("-mcmodel=large").flag("-m64");
|
c.flag("-mcmodel=large").flag("-m64");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arch_path(relative_path: &str) -> PathBuf {
|
|
||||||
PathBuf::from(format!("{}/{}", ARCH_DIR_X86_64, relative_path))
|
|
||||||
}
|
|
||||||
|
@ -1,20 +1,7 @@
|
|||||||
use std::{collections::HashSet, path::PathBuf};
|
use std::{collections::HashSet, path::PathBuf};
|
||||||
|
|
||||||
use crate::utils::FileUtils;
|
|
||||||
|
|
||||||
pub(super) fn setup_common_files(files: &mut HashSet<PathBuf>) {
|
|
||||||
const DIRS: [&str; 3] = ["src/common", "src/debug/traceback", "src/libs"];
|
|
||||||
DIRS.iter().for_each(|dir| {
|
|
||||||
FileUtils::list_all_files(&dir.into(), Some("c"), true)
|
|
||||||
.into_iter()
|
|
||||||
.for_each(|f| {
|
|
||||||
files.insert(f);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn setup_common_include_dir(include_dirs: &mut HashSet<PathBuf>) {
|
pub(super) fn setup_common_include_dir(include_dirs: &mut HashSet<PathBuf>) {
|
||||||
const DIRS: [&str; 3] = ["src/include", "src/common", "src"];
|
const DIRS: [&str; 2] = ["src/common", "src"];
|
||||||
DIRS.iter().for_each(|dir| {
|
DIRS.iter().for_each(|dir| {
|
||||||
include_dirs.insert(dir.into());
|
include_dirs.insert(dir.into());
|
||||||
});
|
});
|
||||||
|
@ -53,8 +53,6 @@ impl CFilesBuilder {
|
|||||||
|
|
||||||
common::setup_common_include_dir(&mut include_dirs);
|
common::setup_common_include_dir(&mut include_dirs);
|
||||||
|
|
||||||
current_cfiles_arch().setup_global_include_dir(&mut include_dirs);
|
|
||||||
|
|
||||||
let include_dirs: Vec<PathBuf> = include_dirs.into_iter().collect();
|
let include_dirs: Vec<PathBuf> = include_dirs.into_iter().collect();
|
||||||
Self::set_rerun_if_files_changed(&include_dirs);
|
Self::set_rerun_if_files_changed(&include_dirs);
|
||||||
|
|
||||||
@ -67,7 +65,6 @@ impl CFilesBuilder {
|
|||||||
fn setup_files(c: &mut Build) {
|
fn setup_files(c: &mut Build) {
|
||||||
let mut files: HashSet<PathBuf> = HashSet::new();
|
let mut files: HashSet<PathBuf> = HashSet::new();
|
||||||
current_cfiles_arch().setup_files(c, &mut files);
|
current_cfiles_arch().setup_files(c, &mut files);
|
||||||
common::setup_common_files(&mut files);
|
|
||||||
// 去重
|
// 去重
|
||||||
let files: Vec<PathBuf> = files.into_iter().collect();
|
let files: Vec<PathBuf> = files.into_iter().collect();
|
||||||
Self::set_rerun_if_files_changed(&files);
|
Self::set_rerun_if_files_changed(&files);
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
pub const ARCH_DIR_X86_64: &str = "src/arch/x86_64";
|
|
||||||
pub const ARCH_DIR_RISCV64: &str = "src/arch/riscv64";
|
|
@ -2,9 +2,7 @@
|
|||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
extern crate cc;
|
extern crate cc;
|
||||||
|
|
||||||
mod bindgen;
|
|
||||||
mod cfiles;
|
mod cfiles;
|
||||||
mod constant;
|
|
||||||
mod kconfig;
|
mod kconfig;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
@ -12,7 +10,6 @@ mod utils;
|
|||||||
pub fn run() {
|
pub fn run() {
|
||||||
println!("cargo:rustc-link-search=src");
|
println!("cargo:rustc-link-search=src");
|
||||||
|
|
||||||
crate::bindgen::generate_bindings();
|
|
||||||
crate::cfiles::CFilesBuilder::build();
|
crate::cfiles::CFilesBuilder::build();
|
||||||
crate::kconfig::KConfigBuilder::build();
|
crate::kconfig::KConfigBuilder::build();
|
||||||
}
|
}
|
||||||
|
@ -1,49 +1 @@
|
|||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
pub mod cargo_handler;
|
pub mod cargo_handler;
|
||||||
|
|
||||||
pub struct FileUtils;
|
|
||||||
|
|
||||||
impl FileUtils {
|
|
||||||
/// 列出指定目录下的所有文件
|
|
||||||
///
|
|
||||||
/// ## 参数
|
|
||||||
///
|
|
||||||
/// - `path` - 指定的目录
|
|
||||||
/// - `ext_name` - 文件的扩展名,如果为None,则列出所有文件
|
|
||||||
/// - `recursive` - 是否递归列出所有文件
|
|
||||||
pub fn list_all_files(path: &PathBuf, ext_name: Option<&str>, recursive: bool) -> Vec<PathBuf> {
|
|
||||||
let mut queue: Vec<PathBuf> = Vec::new();
|
|
||||||
let mut result = Vec::new();
|
|
||||||
queue.push(path.clone());
|
|
||||||
|
|
||||||
while !queue.is_empty() {
|
|
||||||
let path = queue.pop().unwrap();
|
|
||||||
let d = std::fs::read_dir(path);
|
|
||||||
if d.is_err() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let d = d.unwrap();
|
|
||||||
|
|
||||||
d.for_each(|ent| {
|
|
||||||
if let Ok(ent) = ent {
|
|
||||||
if let Ok(file_type) = ent.file_type() {
|
|
||||||
if file_type.is_file() {
|
|
||||||
if let Some(e) = ext_name {
|
|
||||||
if let Some(ext) = ent.path().extension() {
|
|
||||||
if ext == e {
|
|
||||||
result.push(ent.path());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if file_type.is_dir() && recursive {
|
|
||||||
queue.push(ent.path());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -16,6 +16,7 @@ ECHO:
|
|||||||
@echo "$@"
|
@echo "$@"
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
$(MAKE) -C ../build-scripts all
|
||||||
$(MAKE) -C src all ARCH=$(ARCH) || (sh -c "echo 内核编译失败" && exit 1)
|
$(MAKE) -C src all ARCH=$(ARCH) || (sh -c "echo 内核编译失败" && exit 1)
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ kernel: $(kernel_subdirs) kernel_rust
|
|||||||
|
|
||||||
__link_riscv64_kernel:
|
__link_riscv64_kernel:
|
||||||
@echo "Linking kernel..."
|
@echo "Linking kernel..."
|
||||||
$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax
|
$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax
|
||||||
# 生成kallsyms
|
# 生成kallsyms
|
||||||
current_dir=$(pwd)
|
current_dir=$(pwd)
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ __link_riscv64_kernel:
|
|||||||
# 重新链接
|
# 重新链接
|
||||||
@echo "Re-Linking kernel..."
|
@echo "Re-Linking kernel..."
|
||||||
@echo $(shell find . -name "*.o")
|
@echo $(shell find . -name "*.o")
|
||||||
$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a ./debug/kallsyms.o -T arch/riscv64/link.ld --no-relax
|
$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a ./debug/kallsyms.o -T arch/riscv64/link.ld --no-relax
|
||||||
@echo "Generating kernel ELF file..."
|
@echo "Generating kernel ELF file..."
|
||||||
|
|
||||||
ifeq ($(UNWIND_ENABLE), yes)
|
ifeq ($(UNWIND_ENABLE), yes)
|
||||||
@ -90,7 +90,7 @@ endif
|
|||||||
|
|
||||||
__link_x86_64_kernel:
|
__link_x86_64_kernel:
|
||||||
@echo "Linking kernel..."
|
@echo "Linking kernel..."
|
||||||
$(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/x86_64-unknown-none/release/libdragonos_kernel.a -T arch/x86_64/link.lds --no-relax
|
$(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel ../target/x86_64-unknown-none/release/libdragonos_kernel.a -T arch/x86_64/link.lds --no-relax
|
||||||
# 生成kallsyms
|
# 生成kallsyms
|
||||||
current_dir=$(pwd)
|
current_dir=$(pwd)
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ __link_x86_64_kernel:
|
|||||||
# 重新链接
|
# 重新链接
|
||||||
@echo "Re-Linking kernel..."
|
@echo "Re-Linking kernel..."
|
||||||
@echo $(shell find . -name "*.o")
|
@echo $(shell find . -name "*.o")
|
||||||
$(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/x86_64-unknown-none/release/libdragonos_kernel.a ./debug/kallsyms.o -T arch/x86_64/link.lds --no-relax
|
$(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel ../target/x86_64-unknown-none/release/libdragonos_kernel.a ./debug/kallsyms.o -T arch/x86_64/link.lds --no-relax
|
||||||
@echo "Generating kernel ELF file..."
|
@echo "Generating kernel ELF file..."
|
||||||
# 生成内核文件
|
# 生成内核文件
|
||||||
ifeq ($(UNWIND_ENABLE), yes)
|
ifeq ($(UNWIND_ENABLE), yes)
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define ARCH(arch) (defined(AK_ARCH_##arch) && AK_ARCH_##arch)
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __i386__
|
|
||||||
# define AK_ARCH_I386 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
|
||||||
# define AK_ARCH_X86_64 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __riscv
|
|
||||||
# define AK_ARCH_riscv 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __riscv64
|
|
||||||
# define AK_ARCH_riscv64 1
|
|
||||||
#endif
|
|
@ -1,5 +1,29 @@
|
|||||||
#include "common/asm.h"
|
#include "common/asm.h"
|
||||||
#include "asm/csr.h"
|
|
||||||
|
#define CSR_SSTATUS 0x100
|
||||||
|
#define CSR_SIE 0x104
|
||||||
|
#define CSR_STVEC 0x105
|
||||||
|
#define CSR_SIP 0x144
|
||||||
|
#define CSR_SSCRATCH 0x140
|
||||||
|
|
||||||
|
#define CSR_TVEC CSR_STVEC
|
||||||
|
#define CSR_SCRATCH CSR_SSCRATCH
|
||||||
|
|
||||||
|
#define CSR_STATUS CSR_SSTATUS
|
||||||
|
#define CSR_IE CSR_SIE
|
||||||
|
#define CSR_IP CSR_SIP
|
||||||
|
|
||||||
|
#define SR_FS 0x00006000
|
||||||
|
#define SR_VS 0x00000600
|
||||||
|
#define SR_FS_VS (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
|
||||||
|
|
||||||
|
#define SATP_MODE_39 0x8000000000000000ULL
|
||||||
|
#define SATP_MODE_48 0x9000000000000000ULL
|
||||||
|
#define SATP_MODE_57 0xa000000000000000ULL
|
||||||
|
|
||||||
|
#define PAGE_OFFSET 0xffffffc000000000
|
||||||
|
#define KERNEL_LINK_OFFSET 0x1000000
|
||||||
|
#define KERNEL_VIRT_START (PAGE_OFFSET + KERNEL_LINK_OFFSET)
|
||||||
|
|
||||||
.section .bootstrap
|
.section .bootstrap
|
||||||
|
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <asm/asm.h>
|
|
||||||
// 保存当前rflags的值到变量x内并关闭中断
|
|
||||||
#define local_irq_save(x) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
} while (1)
|
|
||||||
// 恢复先前保存的rflags的值x
|
|
||||||
#define local_irq_restore(x) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
} while (1)
|
|
||||||
#define local_irq_disable() \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
} while (1)
|
|
||||||
#define local_irq_enable() \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
} while (1)
|
|
@ -1,35 +0,0 @@
|
|||||||
#include <common/spinlock.h>
|
|
||||||
#include <process/preempt.h>
|
|
||||||
|
|
||||||
void __arch_spin_lock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
while(1);
|
|
||||||
rs_preempt_disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __arch_spin_unlock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
while(1);
|
|
||||||
rs_preempt_enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __arch_spin_lock_no_preempt(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __arch_spin_unlock_no_preempt(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
long __arch_spin_trylock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
uint64_t tmp_val = 0;
|
|
||||||
rs_preempt_disable();
|
|
||||||
// 交换tmp_val和lock的值,若tmp_val==1则证明加锁成功
|
|
||||||
while(1);
|
|
||||||
if (!tmp_val)
|
|
||||||
rs_preempt_enable();
|
|
||||||
return tmp_val;
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "DragonOS/stdint.h"
|
|
||||||
#include <common/stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
// RISC-V 没有直接的开启/关闭中断的指令,你需要通过修改CSR寄存器来实现
|
|
||||||
// 你可能需要在你的中断处理程序中处理这些操作
|
|
||||||
|
|
||||||
#define nop() __asm__ __volatile__("nop\n\t")
|
|
||||||
|
|
||||||
// RISC-V 没有 hlt 指令,你可能需要使用 wfi 指令来等待中断
|
|
||||||
#define hlt() __asm__ __volatile__("wfi\n\t")
|
|
||||||
|
|
||||||
// RISC-V 没有 pause 指令,你可能需要使用其他方法来实现处理器等待
|
|
||||||
|
|
||||||
// RISC-V 使用 fence 指令来实现内存屏障
|
|
||||||
#define io_mfence() __asm__ __volatile__("fence rw,rw\n\t" ::: "memory")
|
|
||||||
#define io_sfence() __asm__ __volatile__("fence w,w\n\t" ::: "memory")
|
|
||||||
#define io_lfence() __asm__ __volatile__("fence r,r\n\t" ::: "memory")
|
|
||||||
|
|
||||||
// 开启中断
|
|
||||||
#define sti() __asm__ __volatile__("csrsi mstatus, 8\n\t" ::: "memory")
|
|
||||||
|
|
||||||
// 关闭中断
|
|
||||||
#define cli() __asm__ __volatile__("csrci mstatus, 8\n\t" ::: "memory")
|
|
||||||
|
|
||||||
// 从io口读入8个bit
|
|
||||||
unsigned char io_in8(unsigned short port) {
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 从io口读入32个bit
|
|
||||||
unsigned int io_in32(unsigned short port) {
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 输出8个bit到输出端口
|
|
||||||
void io_out8(unsigned short port, unsigned char value) {
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 输出32个bit到输出端口
|
|
||||||
void io_out32(unsigned short port, unsigned int value) {
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 验证地址空间是否为用户地址空间
|
|
||||||
*
|
|
||||||
* @param addr_start 地址起始值
|
|
||||||
* @param length 地址长度
|
|
||||||
* @return true
|
|
||||||
* @return false
|
|
||||||
*/
|
|
||||||
bool verify_area(uint64_t addr_start, uint64_t length) {
|
|
||||||
while (1)
|
|
||||||
;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define CSR_SSTATUS 0x100
|
|
||||||
#define CSR_SIE 0x104
|
|
||||||
#define CSR_STVEC 0x105
|
|
||||||
#define CSR_SIP 0x144
|
|
||||||
#define CSR_SSCRATCH 0x140
|
|
||||||
|
|
||||||
#define CSR_TVEC CSR_STVEC
|
|
||||||
#define CSR_SCRATCH CSR_SSCRATCH
|
|
||||||
|
|
||||||
#define CSR_STATUS CSR_SSTATUS
|
|
||||||
#define CSR_IE CSR_SIE
|
|
||||||
#define CSR_IP CSR_SIP
|
|
||||||
|
|
||||||
#define SR_FS 0x00006000
|
|
||||||
#define SR_VS 0x00000600
|
|
||||||
#define SR_FS_VS (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
|
|
||||||
|
|
||||||
#define SATP_MODE_39 0x8000000000000000ULL
|
|
||||||
#define SATP_MODE_48 0x9000000000000000ULL
|
|
||||||
#define SATP_MODE_57 0xa000000000000000ULL
|
|
||||||
|
|
||||||
#define PAGE_OFFSET 0xffffffc000000000
|
|
||||||
#define KERNEL_LINK_OFFSET 0x1000000
|
|
||||||
#define KERNEL_VIRT_START (PAGE_OFFSET + KERNEL_LINK_OFFSET)
|
|
@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// 保存当前rflags的值到变量x内并关闭中断
|
|
||||||
#define local_irq_save(x) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
} while (1)
|
|
||||||
// 恢复先前保存的rflags的值x
|
|
||||||
#define local_irq_restore(x) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
} while (1)
|
|
||||||
#define local_irq_disable() cli();
|
|
||||||
#define local_irq_enable() sti();
|
|
@ -1,5 +1,4 @@
|
|||||||
#include "../common/asm.h"
|
#include "../common/asm.h"
|
||||||
#include <asm/apu_boot.h>
|
|
||||||
|
|
||||||
|
|
||||||
.align 0x1000 // 按照4k对齐
|
.align 0x1000 // 按照4k对齐
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
#include <arch/x86_64/include/asm/cmpxchg.h>
|
|
||||||
|
|
||||||
bool __try_cmpxchg_q(uint64_t *ptr, uint64_t *old_ptr, uint64_t *new_ptr)
|
|
||||||
{
|
|
||||||
bool success = __raw_try_cmpxchg(ptr, old_ptr, *new_ptr, 8);
|
|
||||||
return success;
|
|
||||||
}
|
|
@ -3,7 +3,6 @@
|
|||||||
// 2022/01/20
|
// 2022/01/20
|
||||||
|
|
||||||
#include "common/asm.h"
|
#include "common/asm.h"
|
||||||
#include <asm/apu_boot.h>
|
|
||||||
|
|
||||||
// 以下是来自 multiboot2 规范的定义
|
// 以下是来自 multiboot2 规范的定义
|
||||||
// How many bytes from the start of the file we search for the header.
|
// How many bytes from the start of the file we search for the header.
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
#include <common/spinlock.h>
|
|
||||||
#include <process/preempt.h>
|
|
||||||
|
|
||||||
void __arch_spin_lock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__("1: \n\t"
|
|
||||||
"lock decb %0 \n\t" // 尝试-1
|
|
||||||
"jns 3f \n\t" // 加锁成功,跳转到步骤3
|
|
||||||
"2: \n\t" // 加锁失败,稍后再试
|
|
||||||
"pause \n\t"
|
|
||||||
"cmpb $0, %0 \n\t"
|
|
||||||
"jle 2b \n\t" // 若锁被占用,则继续重试
|
|
||||||
"jmp 1b \n\t" // 尝试加锁
|
|
||||||
"3:"
|
|
||||||
: "=m"(lock->lock)::"memory");
|
|
||||||
rs_preempt_disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __arch_spin_unlock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__("movb $1, %0 \n\t" : "=m"(lock->lock)::"memory");
|
|
||||||
rs_preempt_enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __arch_spin_lock_no_preempt(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__("1: \n\t"
|
|
||||||
"lock decb %0 \n\t" // 尝试-1
|
|
||||||
"jns 3f \n\t" // 加锁成功,跳转到步骤3
|
|
||||||
"2: \n\t" // 加锁失败,稍后再试
|
|
||||||
"pause \n\t"
|
|
||||||
"cmpb $0, %0 \n\t"
|
|
||||||
"jle 2b \n\t" // 若锁被占用,则继续重试
|
|
||||||
"jmp 1b \n\t" // 尝试加锁
|
|
||||||
"3:"
|
|
||||||
: "=m"(lock->lock)::"memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
void __arch_spin_unlock_no_preempt(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__("movb $1, %0 \n\t" : "=m"(lock->lock)::"memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
long __arch_spin_trylock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
uint64_t tmp_val = 0;
|
|
||||||
rs_preempt_disable();
|
|
||||||
// 交换tmp_val和lock的值,若tmp_val==1则证明加锁成功
|
|
||||||
asm volatile("lock xchg %%bx, %1 \n\t" // 确保只有1个进程能得到锁
|
|
||||||
: "=q"(tmp_val), "=m"(lock->lock)
|
|
||||||
: "b"(0)
|
|
||||||
: "memory");
|
|
||||||
if (!tmp_val)
|
|
||||||
rs_preempt_enable();
|
|
||||||
return tmp_val;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
use super::{CurrentApic, LocalAPIC};
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn rs_apic_init_ap() -> i32 {
|
|
||||||
if CurrentApic.init_current_cpu() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
@ -21,7 +21,6 @@ use self::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub mod apic_timer;
|
pub mod apic_timer;
|
||||||
mod c_adapter;
|
|
||||||
pub mod hw_irq;
|
pub mod hw_irq;
|
||||||
pub mod ioapic;
|
pub mod ioapic;
|
||||||
pub mod lapic_vector;
|
pub mod lapic_vector;
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#define APU_BOOT_TMP_STACK_SIZE 1024
|
|
@ -1,410 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <DragonOS/stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <common/stddef.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define sti() __asm__ __volatile__("sti\n\t" :: \
|
|
||||||
: "memory") // 开启外部中断
|
|
||||||
#define cli() __asm__ __volatile__("cli\n\t" :: \
|
|
||||||
: "memory") // 关闭外部中断
|
|
||||||
#define nop() __asm__ __volatile__("nop\n\t")
|
|
||||||
#define hlt() __asm__ __volatile__("hlt\n\t")
|
|
||||||
#define pause() asm volatile("pause\n\t"); // 处理器等待一段时间
|
|
||||||
|
|
||||||
// 内存屏障
|
|
||||||
#define io_mfence() __asm__ __volatile__("mfence\n\t" :: \
|
|
||||||
: "memory") // 在mfence指令前的读写操作必须在mfence指令后的读写操作前完成。
|
|
||||||
#define io_sfence() __asm__ __volatile__("sfence\n\t" :: \
|
|
||||||
: "memory") // 在sfence指令前的写操作必须在sfence指令后的写操作前完成
|
|
||||||
#define io_lfence() __asm__ __volatile__("lfence\n\t" :: \
|
|
||||||
: "memory") // 在lfence指令前的读操作必须在lfence指令后的读操作前完成。
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Macros to generate condition code outputs from inline assembly,
|
|
||||||
* The output operand must be type "bool".
|
|
||||||
*/
|
|
||||||
// 如果编译器支持输出标志寄存器值到变量的话,则会定义__GCC_ASM_FLAG_OUTPUTS__
|
|
||||||
#ifdef __GCC_ASM_FLAG_OUTPUTS__
|
|
||||||
// CC_SET(c)则是用于设置标志寄存器中的某一位
|
|
||||||
#define CC_SET(c) "\n\t/* output condition code " #c "*/\n"
|
|
||||||
// "=@cccond"的用法是,将标志寄存器中的cond(也就是指令集定义的标准条件)的值输出到变量中
|
|
||||||
#define CC_OUT(c) "=@cc" #c
|
|
||||||
#else
|
|
||||||
#define CC_SET(c) "\n\tset" #c " %[_cc_" #c "]\n"
|
|
||||||
#define CC_OUT(c) [_cc_##c] "=qm"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define rdtsc() ({ \
|
|
||||||
uint64_t tmp1 = 0, tmp2 = 0; \
|
|
||||||
asm volatile("rdtsc" \
|
|
||||||
: "=d"(tmp1), "=a"(tmp2)::"memory"); \
|
|
||||||
(tmp1 << 32 | tmp2); \
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取rsp寄存器的值(存储了页目录的基地址)
|
|
||||||
*
|
|
||||||
* @return unsigned* rsp的值的指针
|
|
||||||
*/
|
|
||||||
unsigned long *get_rsp()
|
|
||||||
{
|
|
||||||
uint64_t *tmp;
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"movq %%rsp, %0\n\t"
|
|
||||||
: "=r"(tmp)::"memory");
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 验证地址空间是否为用户地址空间
|
|
||||||
*
|
|
||||||
* @param addr_start 地址起始值
|
|
||||||
* @param length 地址长度
|
|
||||||
* @return true
|
|
||||||
* @return false
|
|
||||||
*/
|
|
||||||
bool verify_area(uint64_t addr_start, uint64_t length)
|
|
||||||
{
|
|
||||||
if ((addr_start + length) <= 0x00007fffffffffffUL) // 用户程序可用的的地址空间应<= 0x00007fffffffffffUL
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取rbp寄存器的值(存储了页目录的基地址)
|
|
||||||
*
|
|
||||||
* @return unsigned* rbp的值的指针
|
|
||||||
*/
|
|
||||||
unsigned long *get_rbp()
|
|
||||||
{
|
|
||||||
uint64_t *tmp;
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"movq %%rbp, %0\n\t"
|
|
||||||
: "=r"(tmp)::"memory");
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取ds寄存器的值(存储了页目录的基地址)
|
|
||||||
*
|
|
||||||
* @return unsigned* ds的值的指针
|
|
||||||
*/
|
|
||||||
unsigned long *get_ds()
|
|
||||||
{
|
|
||||||
uint64_t *tmp;
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"movq %%ds, %0\n\t"
|
|
||||||
: "=r"(tmp)::"memory");
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取rax寄存器的值(存储了页目录的基地址)
|
|
||||||
*
|
|
||||||
* @return unsigned* rax的值的指针
|
|
||||||
*/
|
|
||||||
unsigned long *get_rax()
|
|
||||||
{
|
|
||||||
uint64_t *tmp;
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"movq %%rax, %0\n\t"
|
|
||||||
: "=r"(tmp)::"memory");
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @brief 读取rbx寄存器的值(存储了页目录的基地址)
|
|
||||||
*
|
|
||||||
* @return unsigned* rbx的值的指针
|
|
||||||
*/
|
|
||||||
unsigned long *get_rbx()
|
|
||||||
{
|
|
||||||
uint64_t *tmp;
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"movq %%rbx, %0\n\t"
|
|
||||||
: "=r"(tmp)::"memory");
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t get_rflags()
|
|
||||||
{
|
|
||||||
unsigned long tmp = 0;
|
|
||||||
__asm__ __volatile__("pushfq \n\t"
|
|
||||||
"movq (%%rsp), %0 \n\t"
|
|
||||||
"popfq \n\t"
|
|
||||||
: "=r"(tmp)::"memory");
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *memset(void *dst, unsigned char C, ul size)
|
|
||||||
{
|
|
||||||
|
|
||||||
int d0, d1;
|
|
||||||
unsigned long tmp = C * 0x0101010101010101UL;
|
|
||||||
__asm__ __volatile__("cld \n\t"
|
|
||||||
"rep \n\t"
|
|
||||||
"stosq \n\t"
|
|
||||||
"testb $4, %b3 \n\t"
|
|
||||||
"je 1f \n\t"
|
|
||||||
"stosl \n\t"
|
|
||||||
"1:\ttestb $2, %b3 \n\t"
|
|
||||||
"je 2f\n\t"
|
|
||||||
"stosw \n\t"
|
|
||||||
"2:\ttestb $1, %b3 \n\t"
|
|
||||||
"je 3f \n\t"
|
|
||||||
"stosb \n\t"
|
|
||||||
"3: \n\t"
|
|
||||||
: "=&c"(d0), "=&D"(d1)
|
|
||||||
: "a"(tmp), "q"(size), "0"(size / 8), "1"(dst)
|
|
||||||
: "memory");
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *memset_c(void *dst, uint8_t c, size_t count)
|
|
||||||
{
|
|
||||||
uint8_t *xs = (uint8_t *)dst;
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
*xs++ = c;
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 内存拷贝函数
|
|
||||||
*
|
|
||||||
* @param dst 目标数组
|
|
||||||
* @param src 源数组
|
|
||||||
* @param Num 字节数
|
|
||||||
* @return void*
|
|
||||||
*/
|
|
||||||
static void *memcpy(void *dst, const void *src, long Num)
|
|
||||||
{
|
|
||||||
int d0 = 0, d1 = 0, d2 = 0;
|
|
||||||
__asm__ __volatile__("cld \n\t"
|
|
||||||
"rep \n\t"
|
|
||||||
"movsq \n\t"
|
|
||||||
"testb $4,%b4 \n\t"
|
|
||||||
"je 1f \n\t"
|
|
||||||
"movsl \n\t"
|
|
||||||
"1:\ttestb $2,%b4 \n\t"
|
|
||||||
"je 2f \n\t"
|
|
||||||
"movsw \n\t"
|
|
||||||
"2:\ttestb $1,%b4 \n\t"
|
|
||||||
"je 3f \n\t"
|
|
||||||
"movsb \n\t"
|
|
||||||
"3: \n\t"
|
|
||||||
: "=&c"(d0), "=&D"(d1), "=&S"(d2)
|
|
||||||
: "0"(Num / 8), "q"(Num), "1"(dst), "2"(src)
|
|
||||||
: "memory");
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 从io口读入8个bit
|
|
||||||
unsigned char io_in8(unsigned short port)
|
|
||||||
{
|
|
||||||
unsigned char ret = 0;
|
|
||||||
__asm__ __volatile__("inb %%dx, %0 \n\t"
|
|
||||||
"mfence \n\t"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "d"(port)
|
|
||||||
: "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 从io口读入32个bit
|
|
||||||
unsigned int io_in32(unsigned short port)
|
|
||||||
{
|
|
||||||
unsigned int ret = 0;
|
|
||||||
__asm__ __volatile__("inl %%dx, %0 \n\t"
|
|
||||||
"mfence \n\t"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "d"(port)
|
|
||||||
: "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 输出8个bit到输出端口
|
|
||||||
void io_out8(unsigned short port, unsigned char value)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__("outb %0, %%dx \n\t"
|
|
||||||
"mfence \n\t"
|
|
||||||
:
|
|
||||||
: "a"(value), "d"(port)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 输出32个bit到输出端口
|
|
||||||
void io_out32(unsigned short port, unsigned int value)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__("outl %0, %%dx \n\t"
|
|
||||||
"mfence \n\t"
|
|
||||||
:
|
|
||||||
: "a"(value), "d"(port)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从端口读入n个word到buffer
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define io_insw(port, buffer, nr) \
|
|
||||||
__asm__ __volatile__("cld;rep;insw;mfence;" ::"d"(port), "D"(buffer), "c"(nr) \
|
|
||||||
: "memory")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从输出buffer中的n个word到端口
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define io_outsw(port, buffer, nr) \
|
|
||||||
__asm__ __volatile__("cld;rep;outsw;mfence;" ::"d"(port), "S"(buffer), "c"(nr) \
|
|
||||||
: "memory")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从用户空间搬运数据到内核空间
|
|
||||||
*
|
|
||||||
* @param dst 目的地址
|
|
||||||
* @param src 源地址
|
|
||||||
* @param size 搬运的大小
|
|
||||||
* @return uint64_t
|
|
||||||
*/
|
|
||||||
static inline uint64_t copy_from_user(void *dst, void *src, uint64_t size)
|
|
||||||
{
|
|
||||||
uint64_t tmp0, tmp1;
|
|
||||||
if (!verify_area((uint64_t)src, size))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 先每次搬运8 bytes,剩余就直接一个个byte搬运
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
asm volatile("rep \n\t"
|
|
||||||
"movsq \n\t"
|
|
||||||
"movq %3, %0 \n\t"
|
|
||||||
"rep \n\t"
|
|
||||||
"movsb \n\t"
|
|
||||||
: "=&c"(size), "=&D"(tmp0), "=&S"(tmp1)
|
|
||||||
: "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src)
|
|
||||||
: "memory");
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从内核空间搬运数据到用户空间
|
|
||||||
*
|
|
||||||
* @param dst 目的地址
|
|
||||||
* @param src 源地址
|
|
||||||
* @param size 搬运的大小
|
|
||||||
* @return uint64_t
|
|
||||||
*/
|
|
||||||
static inline uint64_t copy_to_user(void *dst, void *src, uint64_t size)
|
|
||||||
{
|
|
||||||
if (verify_area((uint64_t)src, size))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 先每次搬运8 bytes,剩余就直接一个个byte搬运
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
// todo:编译有bug
|
|
||||||
// asm volatile("rep \n\t"
|
|
||||||
// "movsq \n\t"
|
|
||||||
// "movq %3, %0 \n\t"
|
|
||||||
// "rep \n\t"
|
|
||||||
// "movsb \n\t"
|
|
||||||
// : "=&c"(size), "=&D"(tmp0), "=&S"(tmp1)
|
|
||||||
// : "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src)
|
|
||||||
// : "memory");
|
|
||||||
memcpy(dst, src, size);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 往指定地址写入8字节
|
|
||||||
* 防止由于编译器优化导致不支持的内存访问类型(尤其是在mmio的时候)
|
|
||||||
*
|
|
||||||
* @param vaddr 虚拟地址
|
|
||||||
* @param value 要写入的值
|
|
||||||
*/
|
|
||||||
static __always_inline void __write8b(uint64_t vaddr, uint64_t value)
|
|
||||||
{
|
|
||||||
asm volatile("movq %%rdx, 0(%%rax)" ::"a"(vaddr), "d"(value)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 往指定地址写入4字节
|
|
||||||
* 防止由于编译器优化导致不支持的内存访问类型(尤其是在mmio的时候)
|
|
||||||
*
|
|
||||||
* @param vaddr 虚拟地址
|
|
||||||
* @param value 要写入的值
|
|
||||||
*/
|
|
||||||
static __always_inline void __write4b(uint64_t vaddr, uint32_t value)
|
|
||||||
{
|
|
||||||
asm volatile("movl %%edx, 0(%%rax)" ::"a"(vaddr), "d"(value)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从指定地址读取8字节
|
|
||||||
* 防止由于编译器优化导致不支持的内存访问类型(尤其是在mmio的时候)
|
|
||||||
*
|
|
||||||
* @param vaddr 虚拟地址
|
|
||||||
* @return uint64_t 读取到的值
|
|
||||||
*/
|
|
||||||
static __always_inline uint64_t __read8b(uint64_t vaddr)
|
|
||||||
{
|
|
||||||
uint64_t retval;
|
|
||||||
asm volatile("movq 0(%%rax), %0"
|
|
||||||
: "=r"(retval)
|
|
||||||
: "a"(vaddr)
|
|
||||||
: "memory");
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从指定地址读取4字节
|
|
||||||
* 防止由于编译器优化导致不支持的内存访问类型(尤其是在mmio的时候)
|
|
||||||
*
|
|
||||||
* @param vaddr 虚拟地址
|
|
||||||
* @return uint64_t 读取到的值
|
|
||||||
*/
|
|
||||||
static __always_inline uint32_t __read4b(uint64_t vaddr)
|
|
||||||
{
|
|
||||||
uint32_t retval;
|
|
||||||
asm volatile("movl 0(%%rax), %0"
|
|
||||||
: "=d"(retval)
|
|
||||||
: "a"(vaddr)
|
|
||||||
: "memory");
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 逐字节比较指定内存区域的值,并返回s1、s2的第一个不相等的字节i处的差值(s1[i]-s2[i])。
|
|
||||||
* 若两块内存区域的内容相同,则返回0
|
|
||||||
*
|
|
||||||
* @param s1 内存区域1
|
|
||||||
* @param s2 内存区域2
|
|
||||||
* @param len 要比较的内存区域长度
|
|
||||||
* @return int s1、s2的第一个不相等的字节i处的差值(s1[i]-s2[i])。若两块内存区域的内容相同,则返回0
|
|
||||||
*/
|
|
||||||
static inline int memcmp(const void *s1, const void *s2, size_t len)
|
|
||||||
{
|
|
||||||
int diff;
|
|
||||||
|
|
||||||
asm("cld \n\t" // 复位DF,确保s1、s2指针是自增的
|
|
||||||
"repz; cmpsb\n\t" CC_SET(nz)
|
|
||||||
: CC_OUT(nz)(diff), "+D"(s1), "+S"(s2)
|
|
||||||
: "c"(len)
|
|
||||||
: "memory");
|
|
||||||
|
|
||||||
if (diff)
|
|
||||||
diff = *(const unsigned char *)(s1 - 1) - *(const unsigned char *)(s2 - 1);
|
|
||||||
|
|
||||||
return diff;
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <common/compiler.h>
|
|
||||||
#include <asm/asm.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 通过extern不存在的函数,来让编译器报错。以防止不符合要求的代码的产生。
|
|
||||||
*/
|
|
||||||
extern void __cmpxchg_wrong_size(void) __compiletime_error("Bad argument size for cmpxchg");
|
|
||||||
|
|
||||||
// 定义常量:操作符涉及到的字节数
|
|
||||||
#define __X86_CASE_B 1
|
|
||||||
#define __X86_CASE_W 2
|
|
||||||
#define __X86_CASE_L 4
|
|
||||||
#define __X86_CASE_Q 8
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief lock cmpxchg指令的包装。
|
|
||||||
* 将_ptr指向的值与old_ptr指向的值做比较,如果相等,则将_new指向的值,加载到_ptr指向的值中。
|
|
||||||
*/
|
|
||||||
#define __raw_try_cmpxchg(_ptr, _old_ptr, _new, size) \
|
|
||||||
({ \
|
|
||||||
bool is_success = false; \
|
|
||||||
typeof(_ptr) _old = (typeof(_ptr))(_old_ptr); \
|
|
||||||
typeof(*(_ptr)) __old = *_old; \
|
|
||||||
typeof(*(_ptr)) __new = (_new); \
|
|
||||||
switch (size) \
|
|
||||||
{ \
|
|
||||||
case __X86_CASE_B: \
|
|
||||||
{ \
|
|
||||||
volatile uint8_t *__ptr = (volatile uint8_t *)(_ptr); \
|
|
||||||
asm volatile("lock cmpxchgb %[new], %[ptr]\n\t" \
|
|
||||||
: CC_OUT(z)(is_success), \
|
|
||||||
[ptr] "+m"(*__ptr), \
|
|
||||||
[old] "+a"(__old) \
|
|
||||||
: [new] "q"(__new) \
|
|
||||||
: "memory"); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
case __X86_CASE_W: \
|
|
||||||
{ \
|
|
||||||
volatile uint16_t *__ptr = (volatile uint16_t *)(_ptr); \
|
|
||||||
asm volatile("lock cmpxchgw %[new], %[ptr]\n\t" \
|
|
||||||
: CC_OUT(z)(is_success), \
|
|
||||||
[ptr] "+m"(*__ptr), \
|
|
||||||
[old] "+a"(__old) \
|
|
||||||
: [new] "q"(__new) \
|
|
||||||
: "memory"); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
case __X86_CASE_L: \
|
|
||||||
{ \
|
|
||||||
volatile uint32_t *__ptr = (volatile uint32_t *)(_ptr); \
|
|
||||||
asm volatile("lock cmpxchgl %[new], %[ptr]\n\t" \
|
|
||||||
: CC_OUT(z)(is_success), \
|
|
||||||
[ptr] "+m"(*__ptr), \
|
|
||||||
[old] "+a"(__old) \
|
|
||||||
: [new] "q"(__new) \
|
|
||||||
: "memory"); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
case __X86_CASE_Q: \
|
|
||||||
{ \
|
|
||||||
volatile uint64_t *__ptr = (volatile uint64_t *)(_ptr); \
|
|
||||||
asm volatile("lock cmpxchgq %[new], %[ptr]\n\t" \
|
|
||||||
: CC_OUT(z)(is_success), \
|
|
||||||
[ptr] "+m"(*__ptr), \
|
|
||||||
[old] "+a"(__old) \
|
|
||||||
: [new] "q"(__new) \
|
|
||||||
: "memory"); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
default: \
|
|
||||||
__cmpxchg_wrong_size(); \
|
|
||||||
} \
|
|
||||||
if (unlikely(is_success == false)) \
|
|
||||||
*_old = __old; \
|
|
||||||
likely(is_success); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define arch_try_cmpxchg(ptr, old_ptr, new) \
|
|
||||||
__raw_try_cmpxchg((ptr), (old_ptr), (new), sizeof(*ptr))
|
|
||||||
|
|
||||||
bool __try_cmpxchg_q(uint64_t *ptr, uint64_t *old_ptr, uint64_t *new_ptr);
|
|
@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <asm/asm.h>
|
|
||||||
// 保存当前rflags的值到变量x内并关闭中断
|
|
||||||
#define local_irq_save(x) __asm__ __volatile__("pushfq ; popq %0 ; cli" \
|
|
||||||
: "=g"(x)::"memory")
|
|
||||||
// 恢复先前保存的rflags的值x
|
|
||||||
#define local_irq_restore(x) __asm__ __volatile__("pushq %0 ; popfq" ::"g"(x) \
|
|
||||||
: "memory")
|
|
||||||
#define local_irq_disable() cli();
|
|
||||||
#define local_irq_enable() sti();
|
|
@ -1,69 +0,0 @@
|
|||||||
#include <common/stddef.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 统计二进制数的前导0
|
|
||||||
*
|
|
||||||
* @param x 待统计的数
|
|
||||||
* @return int 结果
|
|
||||||
*/
|
|
||||||
static __always_inline int __clz(uint32_t x)
|
|
||||||
{
|
|
||||||
asm volatile("bsr %%eax, %%eax\n\t"
|
|
||||||
"xor $0x1f, %%eax\n\t"
|
|
||||||
: "=a"(x)
|
|
||||||
: "a"(x)
|
|
||||||
: "memory");
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 统计二进制数的前导0 (宽度为unsigned long)
|
|
||||||
*
|
|
||||||
* @param x 待统计的数
|
|
||||||
* @return int 结果
|
|
||||||
*/
|
|
||||||
static __always_inline int __clzl(unsigned long x)
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
asm volatile("cltq\n\t"
|
|
||||||
"bsr %%rax, %%rax\n\t"
|
|
||||||
"xor $0x3f, %%rax\n\t"
|
|
||||||
"mov %%eax,%0\n\t"
|
|
||||||
: "=m"(res)
|
|
||||||
: "a"(x)
|
|
||||||
: "memory");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 统计二进制数的前导0(宽度为unsigned long long)
|
|
||||||
*
|
|
||||||
* @param x 待统计的数
|
|
||||||
* @return int 结果
|
|
||||||
*/
|
|
||||||
static __always_inline int __clzll(unsigned long long x)
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
asm volatile("cltq\n\t"
|
|
||||||
"bsr %%rax, %%rax\n\t"
|
|
||||||
"xor $0x3f, %%rax\n\t"
|
|
||||||
"mov %%eax,%0\n\t"
|
|
||||||
: "=m"(res)
|
|
||||||
: "a"(x)
|
|
||||||
: "memory");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __always_inline int __ctz(uint32_t x)
|
|
||||||
{
|
|
||||||
asm volatile("tzcnt %%eax, %%eax":"=a"(x):"a"(x):"memory");
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __always_inline int __ctzl(unsigned long x)
|
|
||||||
{
|
|
||||||
asm volatile("tzcnt %%rax, %%rax":"=a"(x):"a"(x):"memory");
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __ctzll __ctzl
|
|
@ -5,9 +5,7 @@ pub mod pkru;
|
|||||||
|
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use hashbrown::HashSet;
|
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use x86::time::rdtsc;
|
|
||||||
use x86_64::registers::model_specific::EferFlags;
|
use x86_64::registers::model_specific::EferFlags;
|
||||||
|
|
||||||
use crate::driver::serial::serial8250::send_to_default_serial8250_port;
|
use crate::driver::serial::serial8250::send_to_default_serial8250_port;
|
||||||
@ -553,11 +551,10 @@ unsafe fn allocator_init() {
|
|||||||
debug!("Successfully enabled new page table");
|
debug!("Successfully enabled new page table");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[cfg(test)]
|
||||||
pub extern "C" fn rs_test_buddy() {
|
|
||||||
test_buddy();
|
|
||||||
}
|
|
||||||
pub fn test_buddy() {
|
pub fn test_buddy() {
|
||||||
|
use hashbrown::HashSet;
|
||||||
|
use x86::time::rdtsc;
|
||||||
// 申请内存然后写入数据然后free掉
|
// 申请内存然后写入数据然后free掉
|
||||||
// 总共申请200MB内存
|
// 总共申请200MB内存
|
||||||
const TOTAL_SIZE: usize = 200 * 1024 * 1024;
|
const TOTAL_SIZE: usize = 200 * 1024 * 1024;
|
||||||
|
@ -2,22 +2,16 @@
|
|||||||
|
|
||||||
#ifndef __ASM__
|
#ifndef __ASM__
|
||||||
#define __ASM__
|
#define __ASM__
|
||||||
|
#define APU_BOOT_TMP_STACK_SIZE 1024
|
||||||
// 符号名
|
// 符号名
|
||||||
#define SYMBOL_NAME(X) X
|
#define SYMBOL_NAME(X) X
|
||||||
// 符号名字符串
|
// 符号名字符串
|
||||||
#define SYMBOL_NAME_STR(X) #X
|
#define SYMBOL_NAME_STR(X) #X
|
||||||
// 符号名label
|
// 符号名label
|
||||||
#define SYMBOL_NAME_LABEL(X) X##:
|
#define SYMBOL_NAME_LABEL(X) X##:
|
||||||
|
|
||||||
#define L1_CACHE_BYTES 32
|
#define ENTRY(name) \
|
||||||
|
.global SYMBOL_NAME(name); \
|
||||||
#define asmlinkage __attribute__((regparm(0)))
|
SYMBOL_NAME_LABEL(name)
|
||||||
|
|
||||||
#define ____cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
|
|
||||||
|
|
||||||
#define ENTRY(name) \
|
|
||||||
.global SYMBOL_NAME(name); \
|
|
||||||
SYMBOL_NAME_LABEL(name)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,110 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file atomic.h
|
|
||||||
* @author fslongjin (longjin@RinGoTek.cn)
|
|
||||||
* @brief 原子变量
|
|
||||||
* @version 0.1
|
|
||||||
* @date 2022-04-12
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#if ARCH(I386) || ARCH(X86_64)
|
|
||||||
|
|
||||||
#include <arch/x86_64/include/asm/cmpxchg.h>
|
|
||||||
|
|
||||||
#define atomic_read(atomic) ((atomic)->value) // 读取原子变量
|
|
||||||
#define atomic_set(atomic, val) (((atomic)->value) = (val)) // 设置原子变量的初始值
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
volatile long value;
|
|
||||||
} atomic_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 原子变量增加值
|
|
||||||
*
|
|
||||||
* @param ato 原子变量对象
|
|
||||||
* @param val 要增加的值
|
|
||||||
*/
|
|
||||||
inline void atomic_add(atomic_t *ato, long val)
|
|
||||||
{
|
|
||||||
asm volatile("lock addq %1, %0 \n\t"
|
|
||||||
: "=m"(ato->value)
|
|
||||||
: "m"(val)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 原子变量减少值
|
|
||||||
*
|
|
||||||
* @param ato 原子变量对象
|
|
||||||
* @param val 要减少的值
|
|
||||||
*/
|
|
||||||
inline void atomic_sub(atomic_t *ato, long val)
|
|
||||||
{
|
|
||||||
asm volatile("lock subq %1, %0 \n\t"
|
|
||||||
: "=m"(ato->value)
|
|
||||||
: "m"(val)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 原子变量自增
|
|
||||||
*
|
|
||||||
* @param ato 原子变量对象
|
|
||||||
*/
|
|
||||||
void atomic_inc(atomic_t *ato)
|
|
||||||
{
|
|
||||||
asm volatile("lock incq %0 \n\t"
|
|
||||||
: "=m"(ato->value)
|
|
||||||
: "m"(ato->value)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 原子变量自减
|
|
||||||
*
|
|
||||||
* @param ato 原子变量对象
|
|
||||||
*/
|
|
||||||
void atomic_dec(atomic_t *ato)
|
|
||||||
{
|
|
||||||
asm volatile("lock decq %0 \n\t"
|
|
||||||
: "=m"(ato->value)
|
|
||||||
: "m"(ato->value)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 设置原子变量的mask
|
|
||||||
*
|
|
||||||
* @param ato 原子变量对象
|
|
||||||
*/
|
|
||||||
inline void atomic_set_mask(atomic_t *ato, long mask)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__("lock orq %1, %0 \n\t"
|
|
||||||
: "=m"(ato->value)
|
|
||||||
: "r"(mask)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 清除原子变量的mask
|
|
||||||
*
|
|
||||||
* @param ato 原子变量对象
|
|
||||||
*/
|
|
||||||
inline void atomic_clear_mask(atomic_t *ato, long mask)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__("lock andq %1, %0 \n\t"
|
|
||||||
: "=m"(ato->value)
|
|
||||||
: "r"(mask)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
// cmpxchgq 比较并交换
|
|
||||||
inline long atomic_cmpxchg(atomic_t *ato, long oldval, long newval)
|
|
||||||
{
|
|
||||||
bool success = arch_try_cmpxchg(&ato->value, &oldval, newval);
|
|
||||||
return success ? oldval : newval;
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,145 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <common/compiler_attributes.h>
|
|
||||||
|
|
||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
|
||||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
|
||||||
|
|
||||||
#ifndef barrier
|
|
||||||
// 内存屏障
|
|
||||||
#define barrier() __asm__ __volatile__("" :: \
|
|
||||||
: "memory");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 编译时断言,如果condition不为1,则输出msg
|
|
||||||
*
|
|
||||||
* @param prefix 一个“不存在的函数名”的前缀
|
|
||||||
* @param suffix 一个“不存在的函数名”的后缀
|
|
||||||
*/
|
|
||||||
#define __compiletime_assert(condition, msg, prefix, suffix) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
/** \
|
|
||||||
* 声明一个不存在的函数的extern,如果assert失败,就调用它,从而导致 \
|
|
||||||
* 链接时出错,进而达到“编译时断言”的功能。 \
|
|
||||||
*/ \
|
|
||||||
__noreturn extern void prefix##suffix(void) \
|
|
||||||
__compiletime_error(msg); \
|
|
||||||
if (!(condition)) \
|
|
||||||
prefix##suffix(); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 当condition是false时,中断编译,并输出指定的错误信息
|
|
||||||
*
|
|
||||||
* @param condition assert的情况
|
|
||||||
* @param msg condition为false时输出的错误信息
|
|
||||||
*/
|
|
||||||
#define complietime_assert(condition, msg) \
|
|
||||||
__compiletime_assert(condition, msg, __compiletime_assert__, __COUNTER__)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从src读取数据到dst,该过程避免编译器优化。
|
|
||||||
*
|
|
||||||
* @param dst 目标地址指针
|
|
||||||
* @param src 源地址指针
|
|
||||||
* @param size 要读取的数据大小(建议1、2、4、8字节,若不满足要求,则采用memcpy读取。)
|
|
||||||
*/
|
|
||||||
static __always_inline void __read_once_size(void *dst, const volatile void *src, int size)
|
|
||||||
{
|
|
||||||
switch (size)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
*(__u8_alias_t *)dst = *(volatile __u8_alias_t *)src;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*(__u16_alias_t *)dst = *(volatile __u16_alias_t *)src;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
*(__u32_alias_t *)dst = *(volatile __u32_alias_t *)src;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
*(__u64_alias_t *)dst = *(volatile __u64_alias_t *)src;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
barrier();
|
|
||||||
__builtin_memcpy((void *)dst, (const void *)src, size);
|
|
||||||
barrier();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 把src处的数据到dst,该过程避免编译器优化。
|
|
||||||
*
|
|
||||||
* @param dst 目标地址指针
|
|
||||||
* @param src 源地址指针
|
|
||||||
* @param size 要写入的数据大小(建议1、2、4、8字节,若不满足要求,则采用memcpy传输。)
|
|
||||||
*/
|
|
||||||
static __always_inline void __write_once_size(volatile void *dst, void *src, int size)
|
|
||||||
{
|
|
||||||
switch (size)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
*(volatile __u8_alias_t *)dst = *(__u8_alias_t *)src;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*(volatile __u16_alias_t *)dst = *(__u16_alias_t *)src;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
*(volatile __u32_alias_t *)dst = *(__u32_alias_t *)src;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
*(volatile __u64_alias_t *)dst = *(__u64_alias_t *)src;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
barrier();
|
|
||||||
__builtin_memcpy((void *)dst, (const void *)src, size);
|
|
||||||
barrier();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 这两个宏能够避免编译器重排序、合并涉及到的读写操作,从而避免由于编译器优化导致的多线程读写顺序错误。
|
|
||||||
* 通过将有顺序要求的两个读/写操作放置在READ_ONCE()和WRITE_ONCE()之中,能够让编译器知道这些操作具有顺序要求。
|
|
||||||
*
|
|
||||||
* 这两个宏同样适用于Union或struct。如果要访问的数据大小不是1、2、4、8字节,则会使用memcpy来处理。
|
|
||||||
*
|
|
||||||
* 这两个宏的主要使用场景:
|
|
||||||
* 1.两个进程或者中断处理函数之间的信息交流与沟通
|
|
||||||
* 2.确保编译器不会折叠、旋转或以其他方式对代码进行优化,从而破坏数据访问顺序。
|
|
||||||
*
|
|
||||||
* 这两个宏的union __u内的__c用作这个union的地址的指针
|
|
||||||
*
|
|
||||||
* 关于READ_ONCE和WRITE_ONCE的简单说明,请转到:https://bbs.dragonos.org/forum.php?mod=viewthread&tid=24
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取变量x (避免编译器优化)
|
|
||||||
*/
|
|
||||||
#define READ_ONCE(x) \
|
|
||||||
({ \
|
|
||||||
union \
|
|
||||||
{ \
|
|
||||||
typeof(x) __val; \
|
|
||||||
char __c[1]; \
|
|
||||||
} __u = {.__c = {0}}; \
|
|
||||||
__read_once_size(__u.__c, &(x), sizeof(x)); \
|
|
||||||
__u.__val; \
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 将val写入变量x (避免编译器优化)
|
|
||||||
*/
|
|
||||||
#define WRITE_ONCE(x, val) \
|
|
||||||
({ \
|
|
||||||
union \
|
|
||||||
{ \
|
|
||||||
typeof(x) __val; \
|
|
||||||
char __c[1]; \
|
|
||||||
} __u = {.val = (val)}; \
|
|
||||||
__write_once_size(&(x), __u.__c, sizeof(x)); \
|
|
||||||
__u.__val; \
|
|
||||||
})
|
|
@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <common/stddef.h>
|
|
||||||
|
|
||||||
// 当函数的返回值未被使用时,编译器抛出警告信息
|
|
||||||
#define __must_check __attribute__((__warn_unused_result__))
|
|
||||||
#define __force __attribute__((force))
|
|
||||||
// 无返回值的属性
|
|
||||||
#define __noreturn __attribute__((__noreturn__))
|
|
||||||
/*
|
|
||||||
* Optional: only supported since clang >= 14.0
|
|
||||||
*
|
|
||||||
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-error-function-attribute
|
|
||||||
*/
|
|
||||||
#if __has_attribute(__error__)
|
|
||||||
#define __compiletime_error(msg) __attribute__((__error__(msg)))
|
|
||||||
#else
|
|
||||||
#define __compiletime_error(msg)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef uint8_t __attribute__((__may_alias__)) __u8_alias_t;
|
|
||||||
typedef uint16_t __attribute__((__may_alias__)) __u16_alias_t;
|
|
||||||
typedef uint32_t __attribute__((__may_alias__)) __u32_alias_t;
|
|
||||||
typedef uint64_t __attribute__((__may_alias__)) __u64_alias_t;
|
|
@ -1,11 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <common/sys/types.h>
|
|
||||||
struct dirent
|
|
||||||
{
|
|
||||||
ino_t d_ino; // 文件序列号
|
|
||||||
off_t d_off; // dir偏移量
|
|
||||||
unsigned short d_reclen; // 目录下的记录数
|
|
||||||
unsigned char d_type; // entry的类型
|
|
||||||
char d_name[]; // 文件entry的名字(是一个零长度的数组)
|
|
||||||
};
|
|
@ -1,46 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <common/compiler.h>
|
|
||||||
#include <DragonOS/stdint.h>
|
|
||||||
#define MAX_ERRNO 4095
|
|
||||||
|
|
||||||
#define IS_ERR_VALUE(x) unlikely((x) >= (uint64_t)-MAX_ERRNO)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 判断返回的指针是否为errno
|
|
||||||
*
|
|
||||||
* @param ptr 待校验的指针
|
|
||||||
* @return long 1 => 是错误码
|
|
||||||
* 0 => 不是错误码
|
|
||||||
*/
|
|
||||||
static inline long __must_check IS_ERR(const void* ptr)
|
|
||||||
{
|
|
||||||
return IS_ERR_VALUE((uint64_t)ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 判断返回的指针是否为errno或者为空
|
|
||||||
*
|
|
||||||
* @param ptr 待校验的指针
|
|
||||||
* @return long 1 => 是错误码或NULL
|
|
||||||
* 0 => 不是错误码或NULL
|
|
||||||
*/
|
|
||||||
static inline long __must_check IS_ERR_OR_NULL(const void* ptr)
|
|
||||||
{
|
|
||||||
return !ptr || IS_ERR_VALUE((uint64_t)ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 将错误码转换为指针
|
|
||||||
*
|
|
||||||
* @param error 错误码
|
|
||||||
* @return void* 转换后的指针
|
|
||||||
*/
|
|
||||||
static inline void* __must_check ERR_PTR(long error)
|
|
||||||
{
|
|
||||||
return (void*)(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline long __must_check PTR_ERR(void * ptr)
|
|
||||||
{
|
|
||||||
return (long)ptr;
|
|
||||||
}
|
|
@ -1,145 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file errno.h
|
|
||||||
* @author fslongjin (longjin@RinGoTek.cn)
|
|
||||||
* @brief
|
|
||||||
* @version 0.1
|
|
||||||
* @date 2022-04-22
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#define EPERM 1 /* 操作不被允许 Operation not permitted. */
|
|
||||||
#define ENOENT 2 /* 没有指定的文件或目录 No such file or directory. */
|
|
||||||
#define ESRCH 3 /* 没有这样的进程 No such process. */
|
|
||||||
#define EINTR 4 /* 被中断的函数 Interrupted function. */
|
|
||||||
#define EIO 5 /* I/O错误 I/O error. */
|
|
||||||
#define ENXIO 6 /* 没有这样的设备或地址 No such device or address. */
|
|
||||||
#define E2BIG 7 /* 参数列表过长,或者在输出buffer中缺少空间 或者参数比系统内建的最大值要大 Argument list too long. */
|
|
||||||
#define ENOEXEC 8 /* 可执行文件格式错误 Executable file format error */
|
|
||||||
#define EBADF 9 /* 错误的文件描述符 Bad file descriptor. */
|
|
||||||
#define ECHILD 10 /* 没有子进程 No child processes. */
|
|
||||||
#define EAGAIN 11 /* 资源不可用,请重试。 Resource unavailable try again.(may be the same value as [EWOULDBLOCK]) */
|
|
||||||
#define EWOULDBLOCK 11 /* 操作将被禁止 Operation would block.(may be the same value as [EAGAIN]). */
|
|
||||||
#define ENOMEM 12 /* 没有足够的空间 Not enough space. */
|
|
||||||
#define EACCES 13 /* 访问被拒绝 Permission denied */
|
|
||||||
#define EFAULT 14 /* 错误的地址 Bad address */
|
|
||||||
#define ENOTBLK 15 /* 需要块设备 Block device required */
|
|
||||||
#define EBUSY 16 /* 设备或资源忙 Device or resource busy. */
|
|
||||||
#define EEXIST 17 /* 文件已存在 File exists. */
|
|
||||||
#define EXDEV 18 /* 跨设备连接 Cross-device link. */
|
|
||||||
#define ENODEV 19 /* 没有指定的设备 No such device. */
|
|
||||||
#define ENOTDIR 20 /* 不是目录 Not a directory. */
|
|
||||||
#define EISDIR 21 /* 是一个目录 Is a directory */
|
|
||||||
#define EINVAL 22 /* 不可用的参数 Invalid argument. */
|
|
||||||
#define ENFILE 23 /* 系统中打开的文件过多 Too many files open in system. */
|
|
||||||
#define EMFILE 24 /* 文件描述符的值过大 File descriptor value too large. */
|
|
||||||
#define ENOTTY 25 /* 不正确的I/O控制操作 Inappropriate I/O control operation. */
|
|
||||||
#define ETXTBSY 26 /* 文本文件忙 Text file busy. */
|
|
||||||
#define EFBIG 27 /* 文件太大 File too large. */
|
|
||||||
#define ENOSPC 28 /* 设备上没有空间 No space left on device. */
|
|
||||||
#define ESPIPE 29 /* 错误的寻道.当前文件是pipe,不允许seek请求 Invalid seek. */
|
|
||||||
#define EROFS 30 /* 只读的文件系统 Read-only file system. */
|
|
||||||
#define EMLINK 31 /* 链接数过多 Too many links. */
|
|
||||||
#define EPIPE 32 /* 断开的管道 Broken pipe. */
|
|
||||||
#define EDOM 33 /* 数学参数超出作用域 Mathematics argument out of domain of function. */
|
|
||||||
#define ERANGE 34 /* 结果过大 Result too large. */
|
|
||||||
#define EDEADLK 35 /* 资源死锁将要发生 Resource deadlock would occur. */
|
|
||||||
#define ENAMETOOLONG 36 /* 文件名过长 Filename too long. */
|
|
||||||
#define ENOLCK 37 /* 没有可用的锁 No locks available. */
|
|
||||||
#define ENOSYS 38 /* 功能不支持 Function not supported. */
|
|
||||||
#define ENOTEMPTY 39 /* 目录非空 Directory not empty. */
|
|
||||||
#define ELOOP 40 /* 符号链接级别过多 Too many levels of symbolic links. */
|
|
||||||
#define ENOMSG 42 /* 没有期待类型的消息 No message of the desired type. */
|
|
||||||
#define EIDRM 43 /* 标志符被移除 Identifier removed. */
|
|
||||||
#define ECHRNG 44 /* 通道号超出范围 Channel number out of range */
|
|
||||||
#define EL2NSYNC 45 /* 二级不同步 Level 2 not synchronized */
|
|
||||||
#define EL3HLT 46 /* 三级暂停 Level 3 halted */
|
|
||||||
#define EL3RST 47 /* 三级重置 Level 3 reset */
|
|
||||||
#define ELNRNG 48 /* 链接号超出范围 Link number out of range */
|
|
||||||
#define EUNATCH 49 /* 未连接协议驱动程序 Protocol driver not attached */
|
|
||||||
#define ENOCSI 50 /* 没有可用的CSI结构 No CSI structure available */
|
|
||||||
#define EL2HLT 51 /* 二级暂停 Level 2 halted */
|
|
||||||
#define EBADE 52 /* 无效交换 Invalid exchange */
|
|
||||||
#define EBADR 53 /* 无效的请求描述符 Invalid request descriptor */
|
|
||||||
#define EXFULL 54 /* 交换满 Exchange full */
|
|
||||||
#define ENOANO 55 /* 无阳极 No anode */
|
|
||||||
#define EBADRQC 56 /* 请求码无效 Invalid request code */
|
|
||||||
#define EBADSLT 57 /* 无效插槽 Invalid slot */
|
|
||||||
#define EDEADLOCK EDEADLK /* 资源死锁 Resource deadlock would occur */
|
|
||||||
#define EBFONT 59 /* 错误的字体文件格式 Bad font file format */
|
|
||||||
#define ENOSTR 60 /* 不是STREAM Not a STREAM */
|
|
||||||
#define ENODATA 61 /* 队列头没有可读取的消息 No message is available on the STREAM head read queue. */
|
|
||||||
#define ETIME 62 /* 流式ioctl()超时 Stream ioctl() timeout */
|
|
||||||
#define ENOSR 63 /* 没有STREAM资源 No STREAM resources. */
|
|
||||||
#define ENONET 64 /* 机器不在网络上 Machine is not on the network */
|
|
||||||
#define ENOPKG 65 /* 未安装软件包 Package not installed */
|
|
||||||
#define EREMOTE 66 /* 远程对象 Object is remote */
|
|
||||||
#define ENOLINK 67 /* 保留 Reserved. */
|
|
||||||
#define EADV 68 /* 外设错误 Advertise error. */
|
|
||||||
#define ESRMNT 69 /* 安装错误 Srmount error */
|
|
||||||
#define ECOMM 70 /* 发送时发生通信错误 Communication error on send */
|
|
||||||
#define EPROTO 71 /* 协议错误 Protocol error. */
|
|
||||||
#define EMULTIHOP 72 /* 保留使用 Reserved. */
|
|
||||||
#define EDOTDOT 73 /* RFS特定错误 RFS specific error */
|
|
||||||
#define EBADMSG 74 /* 错误的消息 Bad message. */
|
|
||||||
#define EOVERFLOW 75 /* 数值过大,产生溢出 Value too large to be stored in data type. */
|
|
||||||
#define ENOTUNIQ 76 /* 名称在网络上不是唯一的 Name not unique on network */
|
|
||||||
#define EBADFD 77 /* 处于不良状态的文件描述符 File descriptor in bad state */
|
|
||||||
#define EREMCHG 78 /* 远程地址已更改 Remote address changed */
|
|
||||||
#define ELIBACC 79 /* 无法访问所需的共享库 Can not access a needed shared library */
|
|
||||||
#define ELIBBAD 80 /* 访问损坏的共享库 Accessing a corrupted shared library */
|
|
||||||
#define ELIBSCN 81 /* a. out中的.lib部分已损坏 .lib section in a.out corrupted */
|
|
||||||
#define ELIBMAX 82 /* 尝试链接太多共享库 Attempting to link in too many shared libraries */
|
|
||||||
#define ELIBEXEC 83 /* 无法直接执行共享库 Cannot exec a shared library directly */
|
|
||||||
#define EILSEQ 84 /* 不合法的字符序列 Illegal byte sequence. */
|
|
||||||
#define ERESTART 85 /* 中断的系统调用应该重新启动 Interrupted system call should be restarted */
|
|
||||||
#define ESTRPIPE 86 /* 流管道错误 Streams pipe error */
|
|
||||||
#define EUSERS 87 /* 用户太多 Too many users */
|
|
||||||
#define ENOTSOCK 88 /* 不是一个套接字 Not a socket. */
|
|
||||||
#define EDESTADDRREQ 89 /* 需要目标地址 Destination address required. */
|
|
||||||
#define EMSGSIZE 90 /* 消息过大 Message too large. */
|
|
||||||
#define EPROTOTYPE 91 /* 对于套接字而言,错误的协议 Protocol wrong type for socket. */
|
|
||||||
#define ENOPROTOOPT 92 /* 协议不可用 Protocol not available. */
|
|
||||||
#define EPROTONOSUPPORT 93 /* 协议不被支持 Protocol not supported. */
|
|
||||||
#define ESOCKTNOSUPPORT 94 /* 不支持套接字类型 Socket type not supported */
|
|
||||||
#define EOPNOTSUPP 95 /* 套接字不支持该操作 Operation not supported on socket (may be the same value as [ENOTSUP]). */
|
|
||||||
#define ENOTSUP EOPNOTSUPP /* 不被支持 Not supported (may be the same value as [EOPNOTSUPP]). */
|
|
||||||
#define EPFNOSUPPORT 96 /* 不支持协议系列 Protocol family not supported */
|
|
||||||
#define EAFNOSUPPORT 97 /* 地址family不支持 Address family not supported. */
|
|
||||||
#define EADDRINUSE 98 /* 地址正在被使用 Address in use. */
|
|
||||||
#define EADDRNOTAVAIL 99 /* 地址不可用 Address not available. */
|
|
||||||
#define ENETDOWN 100 /* 网络已关闭 Network is down. */
|
|
||||||
#define ENETUNREACH 101 /* 网络不可达 Network unreachable. */
|
|
||||||
#define ENETRESET 102 /* 网络连接已断开 Connection aborted by network. */
|
|
||||||
#define ECONNABORTED 103 /* 连接已断开 Connection aborted. */
|
|
||||||
#define ECONNRESET 104 /* 连接被重置 Connection reset. */
|
|
||||||
#define ENOBUFS 105 /* 缓冲区空间不足 No buffer space available. */
|
|
||||||
#define EISCONN 106 /* 套接字已连接 Socket is connected. */
|
|
||||||
#define ENOTCONN 107 /* 套接字未连接 The socket is not connected. */
|
|
||||||
#define ESHUTDOWN 108 /* 传输端点关闭后无法发送 Cannot send after transport endpoint shutdown */
|
|
||||||
#define ETOOMANYREFS 109 /* 引用太多:无法拼接 Too many references: cannot splice */
|
|
||||||
#define ETIMEDOUT 110 /* 连接超时 Connection timed out. */
|
|
||||||
#define ECONNREFUSED 111 /* 连接被拒绝 Connection refused. */
|
|
||||||
#define EHOSTDOWN 112 /* 主机已关闭 Host is down */
|
|
||||||
#define EHOSTUNREACH 113 /* 主机不可达 Host is unreachable. */
|
|
||||||
#define EALREADY 114 /* 连接已经在处理 Connection already in progress. */
|
|
||||||
#define EINPROGRESS 115 /* 操作正在处理 Operation in progress. */
|
|
||||||
#define ESTALE 116 /* 保留 Reserved. */
|
|
||||||
#define EUCLEAN 117 /* 结构需要清理 Structure needs cleaning */
|
|
||||||
#define ENOTNAM 118 /* 不是XENIX命名类型文件 Not a XENIX named type file */
|
|
||||||
#define ENAVAIL 119 /* 没有可用的XENIX信号量 No XENIX semaphores available */
|
|
||||||
#define EISNAM 120 /* 是命名类型文件 Is a named type file */
|
|
||||||
#define EREMOTEIO 121 /* 远程I/O错误 Remote I/O error */
|
|
||||||
#define EDQUOT 122 /* 保留使用 Reserved */
|
|
||||||
#define ENOMEDIUM 123 /* 没有找到媒介 No medium found */
|
|
||||||
#define EMEDIUMTYPE 124 /* 介质类型错误 Wrong medium type */
|
|
||||||
#define ECANCELED 125 /* 操作被取消 Operation canceled. */
|
|
||||||
#define ENOKEY 126 /* 所需的密钥不可用 Required key not available */
|
|
||||||
#define EKEYEXPIRED 127 /* 密钥已过期 Key has expired */
|
|
||||||
#define EKEYREVOKED 128 /* 密钥已被撤销 Key has been revoked */
|
|
||||||
#define EKEYREJECTED 129 /* 密钥被服务拒绝 Key has been revoked */
|
|
||||||
#define EOWNERDEAD 130 /* 之前的拥有者挂了 Previous owner died. */
|
|
||||||
#define ENOTRECOVERABLE 131 /* 状态不可恢复 State not recoverable. */
|
|
||||||
#define ERFKILL 132 /* 由于射频终止,无法操作 Operation not possible due to RF-kill */
|
|
||||||
#define EHWPOISON 132 /* 内存页面有硬件错误 Memory page has hardware error */
|
|
@ -1,59 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file fcntl.h
|
|
||||||
* @author fslongjin (longjin@RinGoTek.cn)
|
|
||||||
* @brief
|
|
||||||
* @version 0.1
|
|
||||||
* @date 2022-04-26
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define O_RDONLY 00000000 // Open Read-only
|
|
||||||
#define O_WRONLY 00000001 // Open Write-only
|
|
||||||
#define O_RDWR 00000002 // Open read/write
|
|
||||||
#define O_ACCMODE 00000003 // Mask for file access modes
|
|
||||||
|
|
||||||
#define O_CREAT 00000100 // Create file if it does not exist
|
|
||||||
#define O_EXCL 00000200 // Fail if file already exists
|
|
||||||
#define O_NOCTTY 00000400 // Do not assign controlling terminal
|
|
||||||
|
|
||||||
#define O_TRUNC 00001000 // 文件存在且是普通文件,并以O_RDWR或O_WRONLY打开,则它会被清空
|
|
||||||
|
|
||||||
#define O_APPEND 00002000 // 文件指针会被移动到文件末尾
|
|
||||||
|
|
||||||
#define O_NONBLOCK 00004000 // 非阻塞式IO模式
|
|
||||||
|
|
||||||
#define O_DSYNC 00010000 // used to be O_SYNC, see below
|
|
||||||
#define FASYNC 00020000 // fcntl, for BSD compatibility
|
|
||||||
#define O_DIRECT 00040000 // direct disk access hint
|
|
||||||
#define O_LARGEFILE 00100000
|
|
||||||
#define O_DIRECTORY 00200000 // 打开的必须是一个目录
|
|
||||||
#define O_NOFOLLOW 00400000 // Do not follow symbolic links
|
|
||||||
#define O_NOATIME 01000000
|
|
||||||
#define O_CLOEXEC 02000000 // set close_on_exec
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The constants AT_REMOVEDIR and AT_EACCESS have the same value. AT_EACCESS is
|
|
||||||
* meaningful only to faccessat, while AT_REMOVEDIR is meaningful only to
|
|
||||||
* unlinkat. The two functions do completely different things and therefore,
|
|
||||||
* the flags can be allowed to overlap. For example, passing AT_REMOVEDIR to
|
|
||||||
* faccessat would be undefined behavior and thus treating it equivalent to
|
|
||||||
* AT_EACCESS is valid undefined behavior.
|
|
||||||
*/
|
|
||||||
// 作为当前工作目录的文件描述符(用于指代cwd)
|
|
||||||
#define AT_FDCWD -100
|
|
||||||
#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */
|
|
||||||
#define AT_EACCESS 0x200 /* Test access permitted for effective IDs, not real IDs. */
|
|
||||||
#define AT_REMOVEDIR 0x200 /* Remove directory instead of unlinking file. */
|
|
||||||
#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */
|
|
||||||
#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */
|
|
||||||
#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
|
|
||||||
|
|
||||||
#define AT_STATX_SYNC_TYPE 0x6000 /* Type of synchronisation required from statx() */
|
|
||||||
#define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */
|
|
||||||
#define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd with the server */
|
|
||||||
#define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the server */
|
|
||||||
|
|
||||||
#define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */
|
|
@ -1,51 +0,0 @@
|
|||||||
//
|
|
||||||
// 内核全局通用库
|
|
||||||
// Created by longjin on 2022/1/22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// 引入对bool类型的支持
|
|
||||||
#include <DragonOS/stdint.h>
|
|
||||||
#include <arch/arch.h>
|
|
||||||
#include <common/compiler.h>
|
|
||||||
#include <common/stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include <asm/asm.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 根据结构体变量内某个成员变量member的基地址,计算出该结构体变量的基地址
|
|
||||||
* @param ptr 指向结构体变量内的成员变量member的指针
|
|
||||||
* @param type 成员变量所在的结构体
|
|
||||||
* @param member 成员变量名
|
|
||||||
*
|
|
||||||
* 方法:使用ptr减去结构体内的偏移,得到结构体变量的基地址
|
|
||||||
*/
|
|
||||||
#define container_of(ptr, type, member) \
|
|
||||||
({ \
|
|
||||||
typeof(((type *)0)->member) *p = (ptr); \
|
|
||||||
(type *)((unsigned long)p - (unsigned long)&(((type *)0)->member)); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define ABS(x) ((x) > 0 ? (x) : -(x)) // 绝对值
|
|
||||||
// 最大最小值
|
|
||||||
#define max(x, y) ((x > y) ? (x) : (y))
|
|
||||||
#define min(x, y) ((x < y) ? (x) : (y))
|
|
||||||
|
|
||||||
// 遮罩高32bit
|
|
||||||
#define MASK_HIGH_32bit(x) (x & (0x00000000ffffffffUL))
|
|
||||||
|
|
||||||
// 四舍五入成整数
|
|
||||||
ul round(double x) { return (ul)(x + 0.5); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 地址按照align进行对齐
|
|
||||||
*
|
|
||||||
* @param addr
|
|
||||||
* @param _align
|
|
||||||
* @return ul 对齐后的地址
|
|
||||||
*/
|
|
||||||
static __always_inline ul ALIGN(const ul addr, const ul _align) {
|
|
||||||
return (ul)((addr + _align - 1) & (~(_align - 1)));
|
|
||||||
}
|
|
@ -1,166 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <common/stddef.h>
|
|
||||||
|
|
||||||
#define __HID_USAGE_TABLE_SIZE 64 // usage stack的大小
|
|
||||||
#define HID_MAX_REPORT 300 // 最大允许的hid report数目(包括feature、input、output)
|
|
||||||
#define HID_MAX_PATH_SIZE 16 // maximum depth for path
|
|
||||||
|
|
||||||
// 这部分请参考hid_1_11.pdf Section 6.2.2.4
|
|
||||||
|
|
||||||
#define HID_ITEM_COLLECTION 0xA0
|
|
||||||
#define HID_ITEM_END_COLLECTION 0xC0
|
|
||||||
#define HID_ITEM_FEATURE 0xB0
|
|
||||||
#define HID_ITEM_INPUT 0x80
|
|
||||||
#define HID_ITEM_OUTPUT 0x90
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 枚举hid的usage page列表。
|
|
||||||
* 原始数据请见<HID Usage Tables FOR Universal Serial Bus (USB)>。
|
|
||||||
* 该文件可从usb.org下载
|
|
||||||
*/
|
|
||||||
enum HID_USAGE_PAGE_TYPES
|
|
||||||
{
|
|
||||||
HID_USAGE_PAGE_GEN_DESKTOP = 0x1,
|
|
||||||
HID_USAGE_PAGE_SIMU_CTRL, // simulation controls
|
|
||||||
HID_USAGE_PAGE_VR_CTRL, // vr controls page
|
|
||||||
HID_USAGE_PAGE_SPORT_CTRL, // sport controls
|
|
||||||
HID_USAGE_PAGE_GAME_CTRL, // game controls
|
|
||||||
HID_USAGE_PAGE_GEN_DEVICE_CTRL, // general device controls
|
|
||||||
HID_USAGE_PAGE_KBD_KPD, // keyboard/ keypad page
|
|
||||||
HID_USAGE_PAGE_LED, // LED
|
|
||||||
HID_USAGE_PAGE_BUTTON, // button page
|
|
||||||
HID_USAGE_PAGE_ORDINAL, // ordinal page
|
|
||||||
HID_USAGE_PAGE_TEL_DEVICE, // telephony device
|
|
||||||
HID_USAGE_PAGE_CONSUMER, // consumer page
|
|
||||||
HID_USAGE_PAGE_DIGITIZER, // digitizers page
|
|
||||||
HID_USAGE_PAGE_HAPTICS, // haptics page
|
|
||||||
HID_USAGE_PAGE_PHY_INPUT_DEVICE, // physical input device page
|
|
||||||
HID_USAGE_PAGE_UNICODE = 0x10, // unicode page
|
|
||||||
HID_USAGE_PAGE_EYE_HEAD_TRACKER = 0x12, // eye and head trackers page
|
|
||||||
HID_USAGE_PAGE_AUX_DISPLAY = 0x14, // auxiliary display page
|
|
||||||
HID_USAGE_PAGE_SENSORS = 0x20, // sensors page
|
|
||||||
HID_USAGE_PAGE_MEDICAL = 0x40, // medical instruments
|
|
||||||
HID_USAGE_PAGE_BRAILLE_DISPLAY, // barille display
|
|
||||||
HID_USAGE_PAGE_LIGHTNING_ILLU = 0x59, // lighting and illumination page
|
|
||||||
HID_USAGE_PAGE_MONITOR = 0x80, // monitor page
|
|
||||||
HID_USAGE_PAGE_MONITOR_ENUMERATED, // monitor enumerated page
|
|
||||||
HID_USAGE_PAGE_VESA_VIRT_CTRL, // VESA virtual controls page
|
|
||||||
HID_USAGE_PAGE_POWER = 0x84, // power page
|
|
||||||
HID_USAGE_PAGE_BATTERY_SYSTEM, // battery system page
|
|
||||||
HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, // barcode scanner page
|
|
||||||
HID_USAGE_PAGE_SCALES, // scales page
|
|
||||||
HID_USAGE_PAGE_MAGNET_STRIPE_READER, // magnetic stript reader page
|
|
||||||
HID_USAGE_PAGE_CAMERA_CONTROL = 0x90, // camera control page
|
|
||||||
HID_USAGE_PAGE_ARCADE, // arcade page
|
|
||||||
HID_USAGE_PAGE_GAMING_DEVICE, // gaming device page
|
|
||||||
HID_USAGE_PAGE_FIDO_ALLIANCE = 0xf1d0, // FIDO alliance page
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief usage type for HID_USAGE_PAGE_GEN_DESKTOP page
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
enum USAGE_TYPE_GENDESK
|
|
||||||
{
|
|
||||||
HID_USAGE_GENDESK_UNDEF = 0, // undefined
|
|
||||||
HID_USAGE_GENDESK_POINTER,
|
|
||||||
HID_USAGE_GENDESK_MOUSE,
|
|
||||||
HID_USAGE_GENDESK_KEYBOARD = 0x6,
|
|
||||||
HID_USAGE_GENDESK_POINTER_X = 0x30,
|
|
||||||
HID_USAGE_GENDESK_POINTER_Y,
|
|
||||||
HID_USAGE_GENDESK_WHEEL = 0x38,
|
|
||||||
HID_USAGE_GENDESK_NOTHING = 0xff,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 描述hid path中的一个节点
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct hid_node_t
|
|
||||||
{
|
|
||||||
int u_page;
|
|
||||||
int usage;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 描述一条hid path
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct hid_path_t
|
|
||||||
{
|
|
||||||
int size; // 路径中的节点数目
|
|
||||||
struct hid_node_t node[HID_MAX_PATH_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Describe a HID Data with its location in report
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct hid_data_t
|
|
||||||
{
|
|
||||||
int value; // hid对象的值
|
|
||||||
struct hid_path_t path; // hid path
|
|
||||||
|
|
||||||
int report_count; // count of reports for this usage type
|
|
||||||
int offset; // offset of data in report
|
|
||||||
int size; // size of data in bits
|
|
||||||
|
|
||||||
uint8_t report_id; // report id(from incoming report)
|
|
||||||
uint8_t type; // 数据类型:FEATURE / INPUT / OUTPUT
|
|
||||||
uint8_t attribute; // report field attribute. (2 = (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position))
|
|
||||||
// (6 = (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position))
|
|
||||||
int8_t unit_exp; // unit exponent;
|
|
||||||
|
|
||||||
uint32_t unit; // HID unit
|
|
||||||
|
|
||||||
int logical_min; // Logical min
|
|
||||||
int logical_max; // Logical max
|
|
||||||
int phys_min; // Physical min
|
|
||||||
int phys_max; // Physical max
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief hid解析器
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct hid_parser
|
|
||||||
{
|
|
||||||
const uint8_t *report_desc; // 指向report descriptor的指针
|
|
||||||
int report_desc_size; // report descriptor的大小(字节)
|
|
||||||
int pos; // report_desc中,当前正在处理的位置
|
|
||||||
uint8_t item; // 暂存当前的item
|
|
||||||
uint32_t value; // 暂存当前的值
|
|
||||||
|
|
||||||
struct hid_data_t data; // 存储当前的环境
|
|
||||||
|
|
||||||
int offset_table[HID_MAX_REPORT][3]; // 存储 hid report的ID、type、offset
|
|
||||||
int report_count; // hid report的数量
|
|
||||||
int count; // local items的计数
|
|
||||||
|
|
||||||
uint32_t u_page;
|
|
||||||
struct hid_node_t usage_table[__HID_USAGE_TABLE_SIZE]; // Usage stack
|
|
||||||
int usage_size; // usage的数量
|
|
||||||
int usage_min;
|
|
||||||
int usage_max;
|
|
||||||
|
|
||||||
int cnt_objects; // report descriptor中的对象数目
|
|
||||||
|
|
||||||
int cnt_report; // report desc中的report数目
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hid_usage_types_string
|
|
||||||
{
|
|
||||||
int value;
|
|
||||||
const char *string;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hid_usage_pages_string
|
|
||||||
{
|
|
||||||
int value;
|
|
||||||
struct hid_usage_types_string *types;
|
|
||||||
const char *string;
|
|
||||||
};
|
|
||||||
|
|
||||||
int hid_parse_report(const void *report_data, const int len);
|
|
||||||
|
|
||||||
bool hid_parse_find_object(const void *hid_report, const int report_size, struct hid_data_t *data);
|
|
@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file kprint.h
|
|
||||||
* @author longjin
|
|
||||||
* @brief 内核日志打印程序
|
|
||||||
* @date 2022-01-28
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022 longjin
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "printk.h"
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "stddef.h"
|
|
||||||
#include <arch/arch.h>
|
|
||||||
#if ARCH(I386) || ARCH(X86_64)
|
|
||||||
|
|
||||||
#if ARCH(I386) || ARCH(X86_64)
|
|
||||||
#include <arch/x86_64/math/bitcount.h>
|
|
||||||
#else
|
|
||||||
#error Arch not supported.
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int64_t pow(int64_t x, int y);
|
|
@ -1,75 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <common/sys/types.h>
|
|
||||||
|
|
||||||
// ===== 描述long double 的数据比特结构
|
|
||||||
#if __LDBL_MANT_DIG__ == 53 && __LDBL_MAX_EXP__ == 1024
|
|
||||||
#elif __LDBL_MANT_DIG__ == 64 && __LDBL_MAX_EXP__ == 16384 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
||||||
union ldshape
|
|
||||||
{
|
|
||||||
long double f;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint64_t m;
|
|
||||||
uint16_t se;
|
|
||||||
} i;
|
|
||||||
};
|
|
||||||
#elif __LDBL_MANT_DIG__ == 113 && __LDBL_MAX_EXP__ == 16384 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
||||||
union ldshape
|
|
||||||
{
|
|
||||||
long double f;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint64_t lo;
|
|
||||||
uint32_t mid;
|
|
||||||
uint16_t top;
|
|
||||||
uint16_t se;
|
|
||||||
} i;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint64_t lo;
|
|
||||||
uint64_t hi;
|
|
||||||
} i2;
|
|
||||||
};
|
|
||||||
#elif __LDBL_MANT_DIG__ == 113 && __LDBL_MAX_EXP__ == 16384 && __BYTE_ORDER__ == __BIG_ENDIAN
|
|
||||||
union ldshape
|
|
||||||
{
|
|
||||||
long double f;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16_t se;
|
|
||||||
uint16_t top;
|
|
||||||
uint32_t mid;
|
|
||||||
uint64_t lo;
|
|
||||||
} i;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint64_t hi;
|
|
||||||
uint64_t lo;
|
|
||||||
} i2;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
#error Unsupported long double representation
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define FORCE_EVAL(x) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (sizeof(x) == sizeof(float)) \
|
|
||||||
{ \
|
|
||||||
volatile float __x; \
|
|
||||||
__x = (x); \
|
|
||||||
(void)__x; \
|
|
||||||
} \
|
|
||||||
else if (sizeof(x) == sizeof(double)) \
|
|
||||||
{ \
|
|
||||||
volatile double __x; \
|
|
||||||
__x = (x); \
|
|
||||||
(void)__x; \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
{ \
|
|
||||||
volatile long double __x; \
|
|
||||||
__x = (x); \
|
|
||||||
(void)__x; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
@ -1,21 +0,0 @@
|
|||||||
#include <common/math.h>
|
|
||||||
#include <common/stddef.h>
|
|
||||||
|
|
||||||
int64_t pow(int64_t x, int y)
|
|
||||||
{
|
|
||||||
if (y == 0)
|
|
||||||
return 1;
|
|
||||||
if (y == 1)
|
|
||||||
return x;
|
|
||||||
if (y == 2)
|
|
||||||
return x * x;
|
|
||||||
int64_t res = 1;
|
|
||||||
while (y != 0)
|
|
||||||
{
|
|
||||||
if (y & 1)
|
|
||||||
res *= x;
|
|
||||||
y >>= 1;
|
|
||||||
x *= x;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "libm.h"
|
|
||||||
|
|
||||||
#if __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1
|
|
||||||
#define EPS __DBL_EPSILON__
|
|
||||||
#elif __FLT_EVAL_METHOD__ == 2
|
|
||||||
#define EPS __LDBL_EPSILON__
|
|
||||||
#endif
|
|
||||||
static const double toint = 1 / EPS;
|
|
||||||
|
|
||||||
double round(double x)
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
double f;
|
|
||||||
uint64_t i;
|
|
||||||
} u = {x};
|
|
||||||
|
|
||||||
int e = u.i >> 52 & 0x7ff;
|
|
||||||
double y;
|
|
||||||
|
|
||||||
if (e >= 0x3ff + 52)
|
|
||||||
return x;
|
|
||||||
if (u.i >> 63)
|
|
||||||
x = -x;
|
|
||||||
if (e < 0x3ff - 1)
|
|
||||||
{
|
|
||||||
/* raise inexact if x!=0 */
|
|
||||||
FORCE_EVAL(x + toint);
|
|
||||||
return 0 * u.f;
|
|
||||||
}
|
|
||||||
y = x + toint - toint - x;
|
|
||||||
if (y > 0.5)
|
|
||||||
y = y + x - 1;
|
|
||||||
else if (y <= -0.5)
|
|
||||||
y = y + x + 1;
|
|
||||||
else
|
|
||||||
y = y + x;
|
|
||||||
if (u.i >> 63)
|
|
||||||
y = -y;
|
|
||||||
return y;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by longjin on 2022/1/21.
|
|
||||||
//
|
|
||||||
#pragma once
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC optimize("O0")
|
|
||||||
#define PAD_ZERO 1 // 0填充
|
|
||||||
#define LEFT 2 // 靠左对齐
|
|
||||||
#define RIGHT 4 // 靠右对齐
|
|
||||||
#define PLUS 8 // 在正数前面显示加号
|
|
||||||
#define SPACE 16
|
|
||||||
#define SPECIAL 32 // 在八进制数前面显示 '0o',在十六进制数前面显示 '0x' 或 '0X'
|
|
||||||
#define SMALL 64 // 十进制以上数字显示小写字母
|
|
||||||
#define SIGN 128 // 显示符号位
|
|
||||||
|
|
||||||
#define is_digit(c) ((c) >= '0' && (c) <= '9') // 用来判断是否是数字的宏
|
|
||||||
|
|
||||||
// 字体颜色的宏定义
|
|
||||||
#define WHITE 0x00ffffff // 白
|
|
||||||
#define BLACK 0x00000000 // 黑
|
|
||||||
#define RED 0x00ff0000 // 红
|
|
||||||
#define ORANGE 0x00ff8000 // 橙
|
|
||||||
#define YELLOW 0x00ffff00 // 黄
|
|
||||||
#define GREEN 0x0000ff00 // 绿
|
|
||||||
#define BLUE 0x000000ff // 蓝
|
|
||||||
#define INDIGO 0x0000ffff // 靛
|
|
||||||
#define PURPLE 0x008000ff // 紫
|
|
||||||
|
|
||||||
// 异常的宏定义
|
|
||||||
#define EPOS_OVERFLOW 1 // 坐标溢出
|
|
||||||
#define EFB_MISMATCH 2 // 帧缓冲区与指定的屏幕大小不匹配
|
|
||||||
#define EUNSUPPORTED 3 // 当前操作暂不被支持
|
|
||||||
|
|
||||||
#include "glib.h"
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
@ -1,153 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file spinlock.h
|
|
||||||
* @author fslongjin (longjin@RinGoTek.cn)
|
|
||||||
* @brief 自旋锁
|
|
||||||
* @version 0.1
|
|
||||||
* @date 2022-04-07
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <asm/irqflags.h>
|
|
||||||
#include <common/glib.h>
|
|
||||||
#include <debug/bug.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 定义自旋锁结构体
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int8_t lock; // 1:unlocked 0:locked
|
|
||||||
} spinlock_t;
|
|
||||||
|
|
||||||
extern void __arch_spin_lock(spinlock_t *lock);
|
|
||||||
extern void __arch_spin_unlock(spinlock_t *lock);
|
|
||||||
|
|
||||||
extern void __arch_spin_lock_no_preempt(spinlock_t *lock);
|
|
||||||
extern void __arch_spin_unlock_no_preempt(spinlock_t *lock);
|
|
||||||
|
|
||||||
extern long __arch_spin_trylock(spinlock_t *lock);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 自旋锁加锁
|
|
||||||
*
|
|
||||||
* @param lock
|
|
||||||
*/
|
|
||||||
void spin_lock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
__arch_spin_lock(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 自旋锁解锁
|
|
||||||
*
|
|
||||||
* @param lock
|
|
||||||
*/
|
|
||||||
void spin_unlock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
__arch_spin_unlock(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 初始化自旋锁
|
|
||||||
*
|
|
||||||
* @param lock
|
|
||||||
*/
|
|
||||||
void spin_init(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
barrier();
|
|
||||||
lock->lock = 1;
|
|
||||||
barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 自旋锁加锁(不改变自旋锁持有计数)
|
|
||||||
*
|
|
||||||
* @warning 慎用此函数,除非你有十足的把握不会产生自旋锁计数错误
|
|
||||||
*/
|
|
||||||
void spin_lock_no_preempt(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
__arch_spin_lock_no_preempt(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 自旋锁解锁(不改变自旋锁持有计数)
|
|
||||||
*
|
|
||||||
* @warning 慎用此函数,除非你有十足的把握不会产生自旋锁计数错误
|
|
||||||
*/
|
|
||||||
void spin_unlock_no_preempt(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
__arch_spin_unlock_no_preempt(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 尝试加锁
|
|
||||||
*
|
|
||||||
* @param lock
|
|
||||||
* @return long 锁变量的值(1为成功加锁,0为加锁失败)
|
|
||||||
*/
|
|
||||||
long spin_trylock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
return __arch_spin_trylock(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 保存中断状态,关闭中断,并自旋锁加锁
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define spin_lock_irqsave(lock, flags) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
local_irq_save(flags); \
|
|
||||||
spin_lock(lock); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 恢复rflags以及中断状态并解锁自旋锁
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define spin_unlock_irqrestore(lock, flags) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
spin_unlock(lock); \
|
|
||||||
local_irq_restore(flags); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 关闭中断并加锁
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define spin_lock_irq(lock) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
local_irq_disable(); \
|
|
||||||
spin_lock(lock); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 解锁并开启中断
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define spin_unlock_irq(lock) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
spin_unlock(lock); \
|
|
||||||
local_irq_enable(); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 判断自旋锁是否已经加锁
|
|
||||||
*
|
|
||||||
* @param lock 待判断的自旋锁
|
|
||||||
* @return true 已经加锁
|
|
||||||
* @return false 尚未加锁
|
|
||||||
*/
|
|
||||||
static inline bool spin_is_locked(const spinlock_t *lock)
|
|
||||||
{
|
|
||||||
int x = READ_ONCE(lock->lock);
|
|
||||||
return (x == 0) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define assert_spin_locked(lock) BUG_ON(!spin_is_locked(lock))
|
|
@ -1,19 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "./sys/types.h"
|
|
||||||
|
|
||||||
#define NULL (void*)0
|
|
||||||
|
|
||||||
typedef __PTRDIFF_TYPE__ ptrdiff_t; // Signed integer type of the result of subtracting two pointers.
|
|
||||||
|
|
||||||
#ifndef __always_inline
|
|
||||||
#define __always_inline __inline__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 定义类型的缩写
|
|
||||||
typedef unsigned char uchar;
|
|
||||||
typedef unsigned short ushort;
|
|
||||||
typedef unsigned int uint;
|
|
||||||
typedef unsigned long ul;
|
|
||||||
typedef unsigned long long int ull;
|
|
||||||
typedef long long int ll;
|
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <common/printk.h>
|
|
||||||
|
|
||||||
#define SEEK_SET 0 /* Seek relative to start-of-file */
|
|
||||||
#define SEEK_CUR 1 /* Seek relative to current position */
|
|
||||||
#define SEEK_END 2 /* Seek relative to end-of-file */
|
|
||||||
|
|
||||||
#define SEEK_MAX 3
|
|
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "glib.h"
|
|
||||||
|
|
||||||
// 计算字符串的长度(经过测试,该版本比采用repne/scasb汇编的运行速度快16.8%左右)
|
|
||||||
static inline int strlen(const char *s) {
|
|
||||||
if (s == NULL)
|
|
||||||
return 0;
|
|
||||||
register int __res = 0;
|
|
||||||
while (s[__res] != '\0') {
|
|
||||||
++__res;
|
|
||||||
}
|
|
||||||
return __res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline int strcmp(const char *s1, const char *s2) {
|
|
||||||
while (*s1 && *s2 && *s1 == *s2) {
|
|
||||||
++s1;
|
|
||||||
++s2;
|
|
||||||
}
|
|
||||||
return *s1 - *s2;
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "DragonOS/stdint.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
typedef unsigned char u_char;
|
|
||||||
typedef unsigned short u_short;
|
|
||||||
typedef unsigned int u_int;
|
|
||||||
typedef unsigned long u_long;
|
|
||||||
|
|
||||||
typedef uint32_t uid_t;
|
|
||||||
typedef uint32_t gid_t;
|
|
||||||
typedef long long ssize_t;
|
|
||||||
|
|
||||||
typedef int64_t pid_t;
|
|
||||||
typedef __SIZE_TYPE__ size_t;
|
|
||||||
|
|
||||||
typedef char *caddr_t;
|
|
||||||
|
|
||||||
typedef int id_t;
|
|
||||||
|
|
||||||
typedef uint64_t ino_t;
|
|
||||||
typedef int64_t off_t;
|
|
||||||
|
|
||||||
typedef uint32_t blkcnt_t;
|
|
||||||
typedef uint32_t blksize_t;
|
|
||||||
typedef uint32_t dev_t;
|
|
||||||
typedef uint16_t mode_t;
|
|
||||||
typedef uint32_t nlink_t;
|
|
||||||
|
|
||||||
typedef int64_t time_t;
|
|
||||||
typedef uint32_t useconds_t;
|
|
||||||
typedef int32_t suseconds_t;
|
|
||||||
typedef uint32_t clock_t;
|
|
||||||
|
|
||||||
typedef uint64_t fsblkcnt_t;
|
|
||||||
typedef uint64_t fsfilcnt_t;
|
|
||||||
|
|
||||||
typedef uint64_t sector_t;
|
|
||||||
|
|
||||||
#define __socklen_t_defined
|
|
||||||
#define __socklen_t uint32_t
|
|
||||||
typedef __socklen_t socklen_t;
|
|
||||||
|
|
||||||
#define pgoff_t unsigned long
|
|
||||||
|
|
||||||
struct utimbuf
|
|
||||||
{
|
|
||||||
time_t actime;
|
|
||||||
time_t modtime;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef int pthread_t;
|
|
||||||
typedef int pthread_key_t;
|
|
||||||
typedef uint32_t pthread_once_t;
|
|
||||||
|
|
||||||
typedef struct __pthread_mutex_t
|
|
||||||
{
|
|
||||||
uint32_t lock;
|
|
||||||
pthread_t owner;
|
|
||||||
int level;
|
|
||||||
int type;
|
|
||||||
} pthread_mutex_t;
|
|
||||||
|
|
||||||
typedef void *pthread_attr_t;
|
|
||||||
typedef struct __pthread_mutexattr_t
|
|
||||||
{
|
|
||||||
int type;
|
|
||||||
} pthread_mutexattr_t;
|
|
||||||
|
|
||||||
typedef struct __pthread_cond_t
|
|
||||||
{
|
|
||||||
pthread_mutex_t *mutex;
|
|
||||||
uint32_t value;
|
|
||||||
int clockid; // clockid_t
|
|
||||||
} pthread_cond_t;
|
|
||||||
|
|
||||||
typedef uint64_t pthread_rwlock_t;
|
|
||||||
typedef void *pthread_rwlockattr_t;
|
|
||||||
typedef struct __pthread_spinlock_t
|
|
||||||
{
|
|
||||||
int m_lock;
|
|
||||||
} pthread_spinlock_t;
|
|
||||||
typedef struct __pthread_condattr_t
|
|
||||||
{
|
|
||||||
int clockid; // clockid_t
|
|
||||||
} pthread_condattr_t;
|
|
||||||
|
|
||||||
typedef uint64_t gfp_t;
|
|
||||||
|
|
||||||
// 定义8字节对齐变量属性
|
|
||||||
#ifndef __aligned_u64
|
|
||||||
#define __aligned_u64 uint64_t __attribute__((aligned(8)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define aligned_u64 __aligned_u64
|
|
@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "stddef.h"
|
|
||||||
|
|
||||||
// 操作系统定义时间以ns为单位
|
|
||||||
#define CLOCKS_PER_SEC 1000000
|
|
2
kernel/src/debug/.gitignore
vendored
2
kernel/src/debug/.gitignore
vendored
@ -1,2 +1,2 @@
|
|||||||
kallsyms
|
gen_kallsyms
|
||||||
kallsyms.S
|
kallsyms.S
|
@ -4,19 +4,14 @@ all:
|
|||||||
|
|
||||||
CFLAGS += -I .
|
CFLAGS += -I .
|
||||||
|
|
||||||
# 请注意,这个不能使用raw的gcc来编译。
|
|
||||||
kallsyms.o: kallsyms.c
|
|
||||||
gcc -o kallsyms kallsyms.c
|
|
||||||
rm -rf kallsyms.o
|
|
||||||
|
|
||||||
# 生成内核栈符号表的汇编文件
|
# 生成内核栈符号表的汇编文件
|
||||||
generate_kallsyms: kallsyms.o
|
generate_kallsyms:
|
||||||
echo "Generating kallsyms..."
|
@echo "Generating kallsyms..."
|
||||||
# 请注意,这个不能使用raw的nm来处理
|
# 请注意,这个不能使用raw的nm来处理
|
||||||
nm -n -C $(kernel_root_path)/kernel | ./kallsyms > kallsyms.S
|
nm -n -C $(kernel_root_path)/kernel | $(kernel_root_path)/../../build-scripts/target/release/gen_kallsyms > kallsyms.S
|
||||||
$(CC) -c kallsyms.S -o kallsyms.o
|
$(CC) -c kallsyms.S -o kallsyms.o
|
||||||
@echo "Kallsyms generated."
|
@echo "Kallsyms generated."
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf kallsyms
|
rm -rf gen_kallsyms
|
@ -1,68 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <common/compiler.h>
|
|
||||||
#include <common/kprint.h>
|
|
||||||
|
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC optimize("O0")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 当condition为true时,认为产生了bug
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define BUG_ON(condition) ({ \
|
|
||||||
int __ret_bug_on = !!(condition); \
|
|
||||||
if (unlikely(__ret_bug_on)) \
|
|
||||||
kBUG("BUG at %s:%d", __FILE__, __LINE__); \
|
|
||||||
unlikely(__ret_bug_on); \
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 当condition为true时输出警告信息
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define WARN_ON(condition) ({ \
|
|
||||||
int __ret_warn_on = !!(condition); \
|
|
||||||
if (unlikely(__ret_warn_on)) \
|
|
||||||
kwarn("Assertion failed at %s:%d", __FILE__, __LINE__); \
|
|
||||||
unlikely(__ret_warn_on); \
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 当condition不为0时输出警告信息,且只会输出一次警告信息
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define WARN_ON_ONCE(condition) ({ \
|
|
||||||
static int __warned; \
|
|
||||||
int __ret_warn_once = !!(condition); \
|
|
||||||
\
|
|
||||||
if (unlikely(__ret_warn_once && !__warned)) \
|
|
||||||
{ \
|
|
||||||
__warned = true; \
|
|
||||||
WARN_ON(1); \
|
|
||||||
} \
|
|
||||||
unlikely(__ret_warn_once); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define FAIL_ON_TO(condition, to) ({ \
|
|
||||||
int __ret_warn_on = !!(condition); \
|
|
||||||
if (unlikely(__ret_warn_on)) \
|
|
||||||
goto to; \
|
|
||||||
unlikely(__ret_warn_on); \
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 当condition为true时,中断编译,并输出错误信息msg
|
|
||||||
*
|
|
||||||
* 如果你的代码依赖于一些能够在编译期间计算出来的值,那么请使用这个宏以防止其他人错误的修改了这些值,从而导致程序运行错误
|
|
||||||
*/
|
|
||||||
#define BUILD_BUG_ON_MSG(condition, msg) complietime_assert(!(condition), msg)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 当condition为true时,中断编译。
|
|
||||||
*
|
|
||||||
* 如果你的代码依赖于一些能够在编译期间计算出来的值,那么请使用这个宏以防止其他人错误的修改了这些值,从而导致程序运行错误
|
|
||||||
*/
|
|
||||||
#define BUILD_BUG_ON(condition) \
|
|
||||||
BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
|
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
122
kernel/src/debug/gen_kallsyms.rs
Normal file
122
kernel/src/debug/gen_kallsyms.rs
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
use std::str;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct KernelSymbolEntry {
|
||||||
|
vaddr: u64,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
symbol_type: char,
|
||||||
|
symbol: String,
|
||||||
|
symbol_length: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn symbol_to_write(vaddr: u64, text_vaddr: u64, etext_vaddr: u64) -> bool {
|
||||||
|
vaddr >= text_vaddr && vaddr <= etext_vaddr
|
||||||
|
}
|
||||||
|
fn read_symbol(line: &str) -> Option<KernelSymbolEntry> {
|
||||||
|
if line.len() > 512 {
|
||||||
|
return None;
|
||||||
|
} // skip line with length >= 512
|
||||||
|
let mut parts = line.split_whitespace();
|
||||||
|
let vaddr = u64::from_str_radix(parts.next()?, 16).ok()?;
|
||||||
|
let symbol_type = parts.next()?.chars().next()?;
|
||||||
|
let symbol = parts.collect::<Vec<_>>().join(" ");
|
||||||
|
if symbol_type != 'T' && symbol_type != 't' {
|
||||||
|
return None;
|
||||||
|
} // local symbol or global symbol in text section
|
||||||
|
if symbol == "$x" {
|
||||||
|
return None;
|
||||||
|
} // skip $x symbol
|
||||||
|
let symbol_length = symbol.len() + 1; // +1 for null terminator
|
||||||
|
Some(KernelSymbolEntry {
|
||||||
|
vaddr,
|
||||||
|
symbol_type,
|
||||||
|
symbol,
|
||||||
|
symbol_length,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_map() -> (Vec<KernelSymbolEntry>, u64, u64) {
|
||||||
|
let mut symbol_table = Vec::new();
|
||||||
|
let mut text_vaddr = 0;
|
||||||
|
let mut etext_vaddr = 0;
|
||||||
|
let mut line = String::new();
|
||||||
|
loop {
|
||||||
|
let size = std::io::stdin().read_line(&mut line).unwrap();
|
||||||
|
if size == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
line = line.trim().to_string();
|
||||||
|
if let Some(entry) = read_symbol(&line) {
|
||||||
|
if entry.symbol.starts_with("_text") {
|
||||||
|
text_vaddr = entry.vaddr;
|
||||||
|
} else if entry.symbol.starts_with("_etext") {
|
||||||
|
etext_vaddr = entry.vaddr;
|
||||||
|
}
|
||||||
|
symbol_table.push(entry);
|
||||||
|
}
|
||||||
|
line.clear();
|
||||||
|
}
|
||||||
|
(symbol_table, text_vaddr, etext_vaddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_result(symbol_table: &[KernelSymbolEntry], text_vaddr: u64, etext_vaddr: u64) {
|
||||||
|
println!(".section .rodata\n");
|
||||||
|
println!(".global kallsyms_address");
|
||||||
|
println!(".align 8\n");
|
||||||
|
println!("kallsyms_address:");
|
||||||
|
|
||||||
|
let mut last_vaddr = 0;
|
||||||
|
let mut total_syms_to_write = 0;
|
||||||
|
|
||||||
|
for entry in symbol_table {
|
||||||
|
if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\t.quad\t{:#x}", entry.vaddr);
|
||||||
|
total_syms_to_write += 1;
|
||||||
|
last_vaddr = entry.vaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\n.global kallsyms_num");
|
||||||
|
println!(".align 8");
|
||||||
|
println!("kallsyms_num:");
|
||||||
|
println!("\t.quad\t{}", total_syms_to_write);
|
||||||
|
|
||||||
|
println!("\n.global kallsyms_names_index");
|
||||||
|
println!(".align 8");
|
||||||
|
println!("kallsyms_names_index:");
|
||||||
|
|
||||||
|
let mut position = 0;
|
||||||
|
last_vaddr = 0;
|
||||||
|
|
||||||
|
for entry in symbol_table {
|
||||||
|
if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\t.quad\t{}", position);
|
||||||
|
position += entry.symbol_length;
|
||||||
|
last_vaddr = entry.vaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\n.global kallsyms_names");
|
||||||
|
println!(".align 8");
|
||||||
|
println!("kallsyms_names:");
|
||||||
|
|
||||||
|
last_vaddr = 0;
|
||||||
|
|
||||||
|
for entry in symbol_table {
|
||||||
|
if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\t.asciz\t\"{}\"", entry.symbol);
|
||||||
|
last_vaddr = entry.vaddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let (symbol_table, text_vaddr, etext_vaddr) = read_map();
|
||||||
|
generate_result(&symbol_table, text_vaddr, etext_vaddr);
|
||||||
|
}
|
@ -1,220 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file kallsyms.c
|
|
||||||
* @author longjin (longjin@RinGoTek.cn)
|
|
||||||
* @brief 内核栈跟踪
|
|
||||||
* @version 0.1
|
|
||||||
* @date 2022-06-22
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 判断符号是否需要被输出(只输出text段内的符号)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define symbol_to_write(vaddr, tv, etv) \
|
|
||||||
((vaddr < tv || vaddr > etv) ? 0 : 1)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 使用nm命令提取出来的信息存到这个结构体之中
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct kernel_symbol_entry_t
|
|
||||||
{
|
|
||||||
uint64_t vaddr;
|
|
||||||
char type;
|
|
||||||
char *symbol;
|
|
||||||
int symbol_length;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kernel_symbol_entry_t *symbol_table;
|
|
||||||
// 符号表最大能容纳的entry数量
|
|
||||||
uint64_t table_size = 0;
|
|
||||||
// 符号表当前的entry数量
|
|
||||||
uint64_t entry_count = 0;
|
|
||||||
// 符号表中,text和etext的下标
|
|
||||||
uint64_t text_vaddr, etext_vaddr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取一个符号到entry之中
|
|
||||||
*
|
|
||||||
* @param filp stdin的文件指针
|
|
||||||
* @param entry 待填写的entry
|
|
||||||
* @return int 返回码
|
|
||||||
*/
|
|
||||||
int read_symbol(FILE *filp, struct kernel_symbol_entry_t *entry)
|
|
||||||
{
|
|
||||||
// 本函数假设nm命令输出的结果中,每行最大512字节
|
|
||||||
char str[512] = {0};
|
|
||||||
char *s = fgets(str, sizeof(str), filp);
|
|
||||||
if (s != str)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char symbol_name[512] = {0};
|
|
||||||
int retval = sscanf(str, "%llx %c %512c", &entry->vaddr, &entry->type, symbol_name);
|
|
||||||
|
|
||||||
// 如果当前行不符合要求
|
|
||||||
if (retval != 3 || entry->type != 'T')
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// malloc一块内存,然后把str的内容拷贝进去,接着修改symbol指针
|
|
||||||
size_t len = strlen(symbol_name);
|
|
||||||
if (len >= 1 && symbol_name[len - 1] == '\n')
|
|
||||||
{
|
|
||||||
symbol_name[len - 1] = '\0';
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
// 转义双引号
|
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
if (symbol_name[i] == '"')
|
|
||||||
{
|
|
||||||
char temp[len - i];
|
|
||||||
memcpy(temp, symbol_name + i, len - i);
|
|
||||||
symbol_name[i] = '\\';
|
|
||||||
memcpy(symbol_name + i + 1, temp, len - i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry->symbol = strdup(symbol_name);
|
|
||||||
entry->symbol_length = len + 1; // +1的原因是.asciz指令会在字符串末尾自动添加结束符\0
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 接收标准输入流的数据,解析nm命令输出的内容
|
|
||||||
*
|
|
||||||
* @param filp
|
|
||||||
*/
|
|
||||||
void read_map(FILE *filp)
|
|
||||||
{
|
|
||||||
// 循环读入数据直到输入流结束
|
|
||||||
while (!feof(filp))
|
|
||||||
{
|
|
||||||
// 给符号表扩容
|
|
||||||
if (entry_count >= table_size)
|
|
||||||
{
|
|
||||||
table_size += 100;
|
|
||||||
// 由于使用了realloc,因此符号表原有的内容会被自动的copy过去
|
|
||||||
symbol_table = (struct kernel_symbol_entry_t *)realloc(symbol_table, sizeof(struct kernel_symbol_entry_t) * table_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 若成功读取符号表的内容,则将计数器+1
|
|
||||||
if (read_symbol(filp, &symbol_table[entry_count]) == 0)
|
|
||||||
++entry_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查找符号表中的text和etext标签
|
|
||||||
for (uint64_t i = 0; i < entry_count; ++i)
|
|
||||||
{
|
|
||||||
if (text_vaddr == 0ULL && strcmp(symbol_table[i].symbol, "_text") == 0)
|
|
||||||
text_vaddr = symbol_table[i].vaddr;
|
|
||||||
if (etext_vaddr == 0ULL && strcmp(symbol_table[i].symbol, "_etext") == 0)
|
|
||||||
etext_vaddr = symbol_table[i].vaddr;
|
|
||||||
if (text_vaddr != 0ULL && etext_vaddr != 0ULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 输出最终的kallsyms汇编代码文件
|
|
||||||
* 直接输出到stdout,通过命令行的 > 命令,写入文件
|
|
||||||
*/
|
|
||||||
void generate_result()
|
|
||||||
{
|
|
||||||
printf(".section .rodata\n\n");
|
|
||||||
printf(".global kallsyms_address\n");
|
|
||||||
printf(".align 8\n\n");
|
|
||||||
|
|
||||||
printf("kallsyms_address:\n"); // 地址数组
|
|
||||||
|
|
||||||
uint64_t last_vaddr = 0;
|
|
||||||
uint64_t total_syms_to_write = 0; // 真正输出的符号的数量
|
|
||||||
|
|
||||||
// 循环写入地址数组
|
|
||||||
for (uint64_t i = 0; i < entry_count; ++i)
|
|
||||||
{
|
|
||||||
// 判断是否为text段的符号
|
|
||||||
if (!symbol_to_write(symbol_table[i].vaddr, text_vaddr, etext_vaddr))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (symbol_table[i].vaddr == last_vaddr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// 输出符号地址
|
|
||||||
printf("\t.quad\t%#llx\n", symbol_table[i].vaddr);
|
|
||||||
++total_syms_to_write;
|
|
||||||
|
|
||||||
last_vaddr = symbol_table[i].vaddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
putchar('\n');
|
|
||||||
|
|
||||||
// 写入符号表的表项数量
|
|
||||||
printf(".global kallsyms_num\n");
|
|
||||||
printf(".align 8\n");
|
|
||||||
printf("kallsyms_num:\n");
|
|
||||||
printf("\t.quad\t%lld\n", total_syms_to_write);
|
|
||||||
|
|
||||||
putchar('\n');
|
|
||||||
|
|
||||||
// 循环写入符号名称的下标索引
|
|
||||||
printf(".global kallsyms_names_index\n");
|
|
||||||
printf(".align 8\n");
|
|
||||||
printf("kallsyms_names_index:\n");
|
|
||||||
uint64_t position = 0;
|
|
||||||
last_vaddr = 0;
|
|
||||||
for (uint64_t i = 0; i < entry_count; ++i)
|
|
||||||
{
|
|
||||||
// 判断是否为text段的符号
|
|
||||||
if (!symbol_to_write(symbol_table[i].vaddr, text_vaddr, etext_vaddr))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (symbol_table[i].vaddr == last_vaddr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// 输出符号名称的偏移量
|
|
||||||
printf("\t.quad\t%lld\n", position);
|
|
||||||
position += symbol_table[i].symbol_length;
|
|
||||||
last_vaddr = symbol_table[i].vaddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
putchar('\n');
|
|
||||||
|
|
||||||
// 输出符号名
|
|
||||||
printf(".global kallsyms_names\n");
|
|
||||||
printf(".align 8\n");
|
|
||||||
printf("kallsyms_names:\n");
|
|
||||||
|
|
||||||
last_vaddr = 0;
|
|
||||||
for (uint64_t i = 0; i < entry_count; ++i)
|
|
||||||
{
|
|
||||||
// 判断是否为text段的符号
|
|
||||||
if (!symbol_to_write(symbol_table[i].vaddr, text_vaddr, etext_vaddr))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (symbol_table[i].vaddr == last_vaddr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// 输出符号名称
|
|
||||||
printf("\t.asciz\t\"%s\"\n", symbol_table[i].symbol);
|
|
||||||
|
|
||||||
last_vaddr = symbol_table[i].vaddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
read_map(stdin);
|
|
||||||
|
|
||||||
generate_result();
|
|
||||||
}
|
|
@ -1,345 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <common/glib.h>
|
|
||||||
|
|
||||||
// ======== PIO端口定义 ========
|
|
||||||
#define PORT_DISK0_DATA 0x1f0 // 数据
|
|
||||||
#define PORT_DISK0_ERR_STATUS 0x1f1 // 错误状态
|
|
||||||
#define PORT_DISK0_SECTOR_CNT 0x1f2 // 操作扇区数
|
|
||||||
#define PORT_DISK0_LBA_7_0 0x1f3 // 扇区号 / LBA[7:0]
|
|
||||||
#define PORT_DISK0_LBA_15_8 0x1f4 // 柱面号[7:0] / LBA[15:8]
|
|
||||||
#define PORT_DISK0_LBA_23_16 0x1f5 // 柱面号[15:8] / LBA[23:16]
|
|
||||||
#define PORT_DISK0_DEVICE_CONFIGURE_REG 0x1f6 // 设备配置寄存器
|
|
||||||
#define PORT_DISK0_CONTROLLER_STATUS_CMD 0x1f7 // 控制器状态端口 / 控制器命令端口
|
|
||||||
#define PORT_DISK0_STATUS_CTRL_REG 0x3f6 // 状态寄存器 / 控制寄存器
|
|
||||||
|
|
||||||
#define PORT_DISK1_DATA 0x170 // 数据
|
|
||||||
#define PORT_DISK1_ERR_STATUS 0x171 // 错误状态
|
|
||||||
#define PORT_DISK1_SECTOR_CNT 0x172 // 操作扇区数
|
|
||||||
#define PORT_DISK1_LBA_7_0 0x173 // 扇区号 / LBA[7:0]
|
|
||||||
#define PORT_DISK1_LBA_15_8 0x174 // 柱面号[7:0] / LBA[15:8]
|
|
||||||
#define PORT_DISK1_LBA_23_16 0x175 // 柱面号[15:8] / LBA[23:16]
|
|
||||||
#define PORT_DISK1_DEVICE_CONFIGURE_REG 0x176 // 设备配置寄存器
|
|
||||||
#define PORT_DISK1_CONTROLLER_STATUS_CMD 0x177 // 控制器状态端口 / 控制器命令端口
|
|
||||||
#define PORT_DISK1_STATUS_CTRL_REG 0x376 // 状态寄存器 / 控制寄存器
|
|
||||||
|
|
||||||
// ======= 状态寄存器的状态位 ==========
|
|
||||||
#define DISK_STATUS_BUSY (1 << 7) // 控制器忙
|
|
||||||
#define DISK_STATUS_READY (1 << 6) // 驱动器准备就绪
|
|
||||||
#define DISK_STATUS_SEEK (1 << 4) // 驱动器寻道
|
|
||||||
#define DISK_STATUS_DATA_REQ (1 << 3) // 数据请求
|
|
||||||
#define DISK_STATUS_DATA_ERROR (1 << 0) // 命令执行错误
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 执行0xec指令返回的512bytes的硬件设备识别信息
|
|
||||||
* 位于ATA8-ACS中 Table-22
|
|
||||||
*/
|
|
||||||
struct ata_identify_device_data
|
|
||||||
{
|
|
||||||
// 0 General configuration bit-significant information
|
|
||||||
unsigned short General_Config;
|
|
||||||
|
|
||||||
// 1 Obsolete
|
|
||||||
unsigned short Obsolete0;
|
|
||||||
|
|
||||||
// 2 Specific configuration
|
|
||||||
unsigned short Specific_Coinfig;
|
|
||||||
|
|
||||||
// 3 Obsolete
|
|
||||||
unsigned short Obsolete1;
|
|
||||||
|
|
||||||
// 4-5 Retired
|
|
||||||
unsigned short Retired0[2];
|
|
||||||
|
|
||||||
// 6 Obsolete
|
|
||||||
unsigned short Obsolete2;
|
|
||||||
|
|
||||||
// 7-8 Reserved for the CompactFlash Association
|
|
||||||
unsigned short CompactFlash[2];
|
|
||||||
|
|
||||||
// 9 Retired
|
|
||||||
unsigned short Retired1;
|
|
||||||
|
|
||||||
// 10-19 Serial number (20 ASCII characters)
|
|
||||||
unsigned short Serial_Number[10];
|
|
||||||
|
|
||||||
// 20-21 Retired
|
|
||||||
unsigned short Retired2[2];
|
|
||||||
|
|
||||||
// 22 Obsolete
|
|
||||||
unsigned short Obsolete3;
|
|
||||||
|
|
||||||
// 23-26 Firmware revision(8 ASCII characters)
|
|
||||||
unsigned short Firmware_Version[4];
|
|
||||||
|
|
||||||
// 27-46 Model number (40 ASCII characters)
|
|
||||||
unsigned short Model_Number[20];
|
|
||||||
|
|
||||||
// 47 15:8 80h
|
|
||||||
// 7:0 00h=Reserved
|
|
||||||
// 01h-FFh = Maximumnumber of logical sectors that shall be transferred per DRQ data block on READ/WRITE MULTIPLE commands
|
|
||||||
unsigned short Max_logical_transferred_per_DRQ;
|
|
||||||
|
|
||||||
// 48 Trusted Computing feature set options
|
|
||||||
unsigned short Trusted_Computing_feature_set_options;
|
|
||||||
|
|
||||||
// 49 Capabilities
|
|
||||||
unsigned short Capabilities0;
|
|
||||||
|
|
||||||
// 50 Capabilities
|
|
||||||
unsigned short Capabilities1;
|
|
||||||
|
|
||||||
// 51-52 Obsolete
|
|
||||||
unsigned short Obsolete4[2];
|
|
||||||
|
|
||||||
// 53 15:8 Free-fall Control Sensitivity
|
|
||||||
// 7:3 Reserved
|
|
||||||
// 2 the fields reported in word 88 are valid
|
|
||||||
// 1 the fields reported in words (70:64) are valid
|
|
||||||
unsigned short Report_88_70to64_valid;
|
|
||||||
|
|
||||||
// 54-58 Obsolete
|
|
||||||
unsigned short Obsolete5[5];
|
|
||||||
|
|
||||||
// 59 15:9 Reserved
|
|
||||||
// 8 Multiple sector setting is valid
|
|
||||||
// 7:0 xxh current setting for number of logical sectors that shall be transferred per DRQ data block on READ/WRITE Multiple commands
|
|
||||||
unsigned short Mul_Sec_Setting_Valid;
|
|
||||||
|
|
||||||
// 60-61 Total number of user addresssable logical sectors for 28bit CMD
|
|
||||||
unsigned short Addressable_Logical_Sectors_for_28[2];
|
|
||||||
|
|
||||||
// 62 Obsolete
|
|
||||||
unsigned short Obsolete6;
|
|
||||||
|
|
||||||
// 63 15:11 Reserved
|
|
||||||
// 10:8=1 Multiword DMA mode 210 is selected
|
|
||||||
// 7:3 Reserved
|
|
||||||
// 2:0=1 Multiword DMA mode 210 and below are supported
|
|
||||||
unsigned short MultWord_DMA_Select;
|
|
||||||
|
|
||||||
// 64 15:8 Reserved
|
|
||||||
// 7:0 PIO mdoes supported
|
|
||||||
unsigned short PIO_mode_supported;
|
|
||||||
|
|
||||||
// 65 Minimum Multiword DMA transfer cycle time per word
|
|
||||||
unsigned short Min_MulWord_DMA_cycle_time_per_word;
|
|
||||||
|
|
||||||
// 66 Manufacturer`s recommended Multiword DMA transfer cycle time
|
|
||||||
unsigned short Manufacture_Recommend_MulWord_DMA_cycle_time;
|
|
||||||
|
|
||||||
// 67 Minimum PIO transfer cycle time without flow control
|
|
||||||
unsigned short Min_PIO_cycle_time_Flow_Control;
|
|
||||||
|
|
||||||
// 68 Minimum PIO transfer cycle time with IORDY flow control
|
|
||||||
unsigned short Min_PIO_cycle_time_IOREDY_Flow_Control;
|
|
||||||
|
|
||||||
// 69-70 Reserved
|
|
||||||
unsigned short Reserved1[2];
|
|
||||||
|
|
||||||
// 71-74 Reserved for the IDENTIFY PACKET DEVICE command
|
|
||||||
unsigned short Reserved2[4];
|
|
||||||
|
|
||||||
// 75 Queue depth
|
|
||||||
unsigned short Queue_depth;
|
|
||||||
|
|
||||||
// 76 Serial ATA Capabilities
|
|
||||||
unsigned short SATA_Capabilities;
|
|
||||||
|
|
||||||
// 77 Reserved for Serial ATA
|
|
||||||
unsigned short Reserved3;
|
|
||||||
|
|
||||||
// 78 Serial ATA features Supported
|
|
||||||
unsigned short SATA_features_Supported;
|
|
||||||
|
|
||||||
// 79 Serial ATA features enabled
|
|
||||||
unsigned short SATA_features_enabled;
|
|
||||||
|
|
||||||
// 80 Major Version number
|
|
||||||
unsigned short Major_Version;
|
|
||||||
|
|
||||||
// 81 Minor version number
|
|
||||||
unsigned short Minor_Version;
|
|
||||||
|
|
||||||
// 82 Commands and feature sets supported
|
|
||||||
unsigned short Cmd_feature_sets_supported0;
|
|
||||||
|
|
||||||
// 83 Commands and feature sets supported
|
|
||||||
unsigned short Cmd_feature_sets_supported1;
|
|
||||||
|
|
||||||
// 84 Commands and feature sets supported
|
|
||||||
unsigned short Cmd_feature_sets_supported2;
|
|
||||||
|
|
||||||
// 85 Commands and feature sets supported or enabled
|
|
||||||
unsigned short Cmd_feature_sets_supported3;
|
|
||||||
|
|
||||||
// 86 Commands and feature sets supported or enabled
|
|
||||||
unsigned short Cmd_feature_sets_supported4;
|
|
||||||
|
|
||||||
// 87 Commands and feature sets supported or enabled
|
|
||||||
unsigned short Cmd_feature_sets_supported5;
|
|
||||||
|
|
||||||
// 88 15 Reserved
|
|
||||||
// 14:8=1 Ultra DMA mode 6543210 is selected
|
|
||||||
// 7 Reserved
|
|
||||||
// 6:0=1 Ultra DMA mode 6543210 and below are suported
|
|
||||||
unsigned short Ultra_DMA_modes;
|
|
||||||
|
|
||||||
// 89 Time required for Normal Erase mode SECURITY ERASE UNIT command
|
|
||||||
unsigned short Time_required_Erase_CMD;
|
|
||||||
|
|
||||||
// 90 Time required for an Enhanced Erase mode SECURITY ERASE UNIT command
|
|
||||||
unsigned short Time_required_Enhanced_CMD;
|
|
||||||
|
|
||||||
// 91 Current APM level value
|
|
||||||
unsigned short Current_APM_level_Value;
|
|
||||||
|
|
||||||
// 92 Master Password Identifier
|
|
||||||
unsigned short Master_Password_Identifier;
|
|
||||||
|
|
||||||
// 93 Hardware resset result.The contents of bits (12:0) of this word shall change only during the execution of a hardware reset.
|
|
||||||
unsigned short HardWare_Reset_Result;
|
|
||||||
|
|
||||||
// 94 Current AAM value
|
|
||||||
// 15:8 Vendor’s recommended AAM value
|
|
||||||
// 7:0 Current AAM value
|
|
||||||
unsigned short Current_AAM_value;
|
|
||||||
|
|
||||||
// 95 Stream Minimum Request Size
|
|
||||||
unsigned short Stream_Min_Request_Size;
|
|
||||||
|
|
||||||
// 96 Streaming Transger Time-DMA
|
|
||||||
unsigned short Streaming_Transger_time_DMA;
|
|
||||||
|
|
||||||
// 97 Streaming Access Latency-DMA and PIO
|
|
||||||
unsigned short Streaming_Access_Latency_DMA_PIO;
|
|
||||||
|
|
||||||
// 98-99 Streaming Performance Granularity (DWord)
|
|
||||||
unsigned short Streaming_Performance_Granularity[2];
|
|
||||||
|
|
||||||
// 100-103 Total Number of User Addressable Logical Sectors for 48-bit commands (QWord)
|
|
||||||
unsigned short Total_user_LBA_for_48_Address_Feature_set[4];
|
|
||||||
|
|
||||||
// 104 Streaming Transger Time-PIO
|
|
||||||
unsigned short Streaming_Transfer_Time_PIO;
|
|
||||||
|
|
||||||
// 105 Reserved
|
|
||||||
unsigned short Reserved4;
|
|
||||||
|
|
||||||
// 106 Physical Sector size/Logical Sector Size
|
|
||||||
unsigned short Physical_Logical_Sector_Size;
|
|
||||||
|
|
||||||
// 107 Inter-seek delay for ISO-7779 acoustic testing in microseconds
|
|
||||||
unsigned short Inter_seek_delay;
|
|
||||||
|
|
||||||
// 108-111 World wide name
|
|
||||||
unsigned short World_wide_name[4];
|
|
||||||
|
|
||||||
// 112-115 Reserved
|
|
||||||
unsigned short Reserved5[4];
|
|
||||||
|
|
||||||
// 116 Reserved for TLC
|
|
||||||
unsigned short Reserved6;
|
|
||||||
|
|
||||||
// 117-118 Logical sector size (DWord)
|
|
||||||
unsigned short Words_per_Logical_Sector[2];
|
|
||||||
|
|
||||||
// 119 Commands and feature sets supported (Continued from words 84:82)
|
|
||||||
unsigned short CMD_feature_Supported;
|
|
||||||
|
|
||||||
// 120 Commands and feature sets supported or enabled (Continued from words 87:85)
|
|
||||||
unsigned short CMD_feature_Supported_enabled;
|
|
||||||
|
|
||||||
// 121-126 Reserved for expanded supported and enabled settings
|
|
||||||
unsigned short Reserved7[6];
|
|
||||||
|
|
||||||
// 127 Obsolete
|
|
||||||
unsigned short Obsolete7;
|
|
||||||
|
|
||||||
// 128 Security status
|
|
||||||
unsigned short Security_Status;
|
|
||||||
|
|
||||||
// 129-159 Vendor specific
|
|
||||||
unsigned short Vendor_Specific[31];
|
|
||||||
|
|
||||||
// 160 CFA power mode
|
|
||||||
unsigned short CFA_Power_mode;
|
|
||||||
|
|
||||||
// 161-167 Reserved for the CompactFlash Association
|
|
||||||
unsigned short Reserved8[7];
|
|
||||||
|
|
||||||
// 168 Device Nominal Form Factor
|
|
||||||
unsigned short Dev_from_Factor;
|
|
||||||
|
|
||||||
// 169-175 Reserved
|
|
||||||
unsigned short Reserved9[7];
|
|
||||||
|
|
||||||
// 176-205 Current media serial number (ATA string)
|
|
||||||
unsigned short Current_Media_Serial_Number[30];
|
|
||||||
|
|
||||||
// 206 SCT Command Transport
|
|
||||||
unsigned short SCT_Cmd_Transport;
|
|
||||||
|
|
||||||
// 207-208 Reserved for CE-ATA
|
|
||||||
unsigned short Reserved10[2];
|
|
||||||
|
|
||||||
// 209 Alignment of logical blocks within a physical block
|
|
||||||
unsigned short Alignment_Logical_blocks_within_a_physical_block;
|
|
||||||
|
|
||||||
// 210-211 Write-Read-Verify Sector Count Mode 3 (DWord)
|
|
||||||
unsigned short Write_Read_Verify_Sector_Count_Mode_3[2];
|
|
||||||
|
|
||||||
// 212-213 Write-Read-Verify Sector Count Mode 2 (DWord)
|
|
||||||
unsigned short Write_Read_Verify_Sector_Count_Mode_2[2];
|
|
||||||
|
|
||||||
// 214 NV Cache Capabilities
|
|
||||||
unsigned short NV_Cache_Capabilities;
|
|
||||||
|
|
||||||
// 215-216 NV Cache Size in Logical Blocks (DWord)
|
|
||||||
unsigned short NV_Cache_Size[2];
|
|
||||||
|
|
||||||
// 217 Nominal media rotation rate
|
|
||||||
unsigned short Nominal_media_rotation_rate;
|
|
||||||
|
|
||||||
// 218 Reserved
|
|
||||||
unsigned short Reserved11;
|
|
||||||
|
|
||||||
// 219 NV Cache Options
|
|
||||||
unsigned short NV_Cache_Options;
|
|
||||||
|
|
||||||
// 220 Write-Read-Verify feature set current mode
|
|
||||||
unsigned short Write_Read_Verify_feature_set_current_mode;
|
|
||||||
|
|
||||||
// 221 Reserved
|
|
||||||
unsigned short Reserved12;
|
|
||||||
|
|
||||||
// 222 Transport major version number.
|
|
||||||
// 0000h or ffffh = device does not report version
|
|
||||||
unsigned short Transport_Major_Version_Number;
|
|
||||||
|
|
||||||
// 223 Transport Minor version number
|
|
||||||
unsigned short Transport_Minor_Version_Number;
|
|
||||||
|
|
||||||
// 224-233 Reserved for CE-ATA
|
|
||||||
unsigned short Reserved13[10];
|
|
||||||
|
|
||||||
// 234 Minimum number of 512-byte data blocks per DOWNLOAD MICROCODE command for mode 03h
|
|
||||||
unsigned short Mini_blocks_per_CMD;
|
|
||||||
|
|
||||||
// 235 Maximum number of 512-byte data blocks per DOWNLOAD MICROCODE command for mode 03h
|
|
||||||
unsigned short Max_blocks_per_CMD;
|
|
||||||
|
|
||||||
// 236-254 Reserved
|
|
||||||
unsigned short Reserved14[19];
|
|
||||||
|
|
||||||
// 255 Integrity word
|
|
||||||
// 15:8 Checksum
|
|
||||||
// 7:0 Checksum Validity Indicator
|
|
||||||
unsigned short Integrity_word;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 初始化ATA磁盘驱动程序
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void ata_init();
|
|
@ -295,10 +295,3 @@ impl TimerFunction for VideoRefreshExecutor {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn rs_video_init() -> i32 {
|
|
||||||
return VideoRefreshManager::video_init()
|
|
||||||
.map(|_| 0)
|
|
||||||
.unwrap_or_else(|e| e.to_posix_errno());
|
|
||||||
}
|
|
||||||
|
@ -28,11 +28,6 @@ const MAX_SOFTIRQ_RESTART: i32 = 20;
|
|||||||
static mut __CPU_PENDING: Option<Box<[VecStatus; PerCpu::MAX_CPU_NUM as usize]>> = None;
|
static mut __CPU_PENDING: Option<Box<[VecStatus; PerCpu::MAX_CPU_NUM as usize]>> = None;
|
||||||
static mut __SORTIRQ_VECTORS: *mut Softirq = null_mut();
|
static mut __SORTIRQ_VECTORS: *mut Softirq = null_mut();
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn rs_softirq_init() {
|
|
||||||
softirq_init().expect("softirq_init failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub fn softirq_init() -> Result<(), SystemError> {
|
pub fn softirq_init() -> Result<(), SystemError> {
|
||||||
info!("Initializing softirq...");
|
info!("Initializing softirq...");
|
||||||
|
@ -1,316 +0,0 @@
|
|||||||
/* Copyright (C) 1997-2022 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
The GNU C Library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the GNU C Library; if not, see
|
|
||||||
<https://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ISO C99: 7.18 Integer types <stdint.h>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _STDINT_H
|
|
||||||
#define _STDINT_H 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# define __WORDSIZE 64
|
|
||||||
|
|
||||||
/* Convenience types. */
|
|
||||||
typedef unsigned char __u_char;
|
|
||||||
typedef unsigned short int __u_short;
|
|
||||||
typedef unsigned int __u_int;
|
|
||||||
typedef unsigned long int __u_long;
|
|
||||||
|
|
||||||
/* Fixed-size types, underlying types depend on word size and compiler. */
|
|
||||||
typedef signed char __int8_t;
|
|
||||||
typedef unsigned char __uint8_t;
|
|
||||||
typedef signed short int __int16_t;
|
|
||||||
typedef unsigned short int __uint16_t;
|
|
||||||
typedef signed int __int32_t;
|
|
||||||
typedef unsigned int __uint32_t;
|
|
||||||
#if __WORDSIZE == 64
|
|
||||||
typedef signed long int __int64_t;
|
|
||||||
typedef unsigned long int __uint64_t;
|
|
||||||
#else
|
|
||||||
__extension__ typedef signed long long int __int64_t;
|
|
||||||
__extension__ typedef unsigned long long int __uint64_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Smallest types with at least a given width. */
|
|
||||||
typedef __int8_t __int_least8_t;
|
|
||||||
typedef __uint8_t __uint_least8_t;
|
|
||||||
typedef __int16_t __int_least16_t;
|
|
||||||
typedef __uint16_t __uint_least16_t;
|
|
||||||
typedef __int32_t __int_least32_t;
|
|
||||||
typedef __uint32_t __uint_least32_t;
|
|
||||||
typedef __int64_t __int_least64_t;
|
|
||||||
typedef __uint64_t __uint_least64_t;
|
|
||||||
|
|
||||||
typedef __uint8_t uint8_t;
|
|
||||||
typedef __uint16_t uint16_t;
|
|
||||||
typedef __uint32_t uint32_t;
|
|
||||||
typedef __uint64_t uint64_t;
|
|
||||||
|
|
||||||
typedef __int8_t int8_t;
|
|
||||||
typedef __int16_t int16_t;
|
|
||||||
typedef __int32_t int32_t;
|
|
||||||
typedef __int64_t int64_t;
|
|
||||||
|
|
||||||
/* Small types. */
|
|
||||||
|
|
||||||
/* Signed. */
|
|
||||||
typedef __int_least8_t int_least8_t;
|
|
||||||
typedef __int_least16_t int_least16_t;
|
|
||||||
typedef __int_least32_t int_least32_t;
|
|
||||||
typedef __int_least64_t int_least64_t;
|
|
||||||
|
|
||||||
/* Unsigned. */
|
|
||||||
typedef __uint_least8_t uint_least8_t;
|
|
||||||
typedef __uint_least16_t uint_least16_t;
|
|
||||||
typedef __uint_least32_t uint_least32_t;
|
|
||||||
typedef __uint_least64_t uint_least64_t;
|
|
||||||
|
|
||||||
|
|
||||||
/* Fast types. */
|
|
||||||
|
|
||||||
/* Signed. */
|
|
||||||
typedef signed char int_fast8_t;
|
|
||||||
#if __WORDSIZE == 64
|
|
||||||
typedef long int int_fast16_t;
|
|
||||||
typedef long int int_fast32_t;
|
|
||||||
typedef long int int_fast64_t;
|
|
||||||
#else
|
|
||||||
typedef int int_fast16_t;
|
|
||||||
typedef int int_fast32_t;
|
|
||||||
__extension__
|
|
||||||
typedef long long int int_fast64_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Unsigned. */
|
|
||||||
typedef unsigned char uint_fast8_t;
|
|
||||||
#if __WORDSIZE == 64
|
|
||||||
typedef unsigned long int uint_fast16_t;
|
|
||||||
typedef unsigned long int uint_fast32_t;
|
|
||||||
typedef unsigned long int uint_fast64_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned int uint_fast16_t;
|
|
||||||
typedef unsigned int uint_fast32_t;
|
|
||||||
__extension__
|
|
||||||
typedef unsigned long long int uint_fast64_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Types for `void *' pointers. */
|
|
||||||
#if __WORDSIZE == 64
|
|
||||||
# ifndef __intptr_t_defined
|
|
||||||
typedef long int intptr_t;
|
|
||||||
# define __intptr_t_defined
|
|
||||||
# endif
|
|
||||||
typedef unsigned long int uintptr_t;
|
|
||||||
#else
|
|
||||||
# ifndef __intptr_t_defined
|
|
||||||
typedef int intptr_t;
|
|
||||||
# define __intptr_t_defined
|
|
||||||
# endif
|
|
||||||
typedef unsigned int uintptr_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Largest integral types. */
|
|
||||||
#if __WORDSIZE == 64
|
|
||||||
typedef long int __intmax_t;
|
|
||||||
typedef unsigned long int __uintmax_t;
|
|
||||||
#else
|
|
||||||
__extension__ typedef long long int __intmax_t;
|
|
||||||
__extension__ typedef unsigned long long int __uintmax_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Largest integral types. */
|
|
||||||
typedef __intmax_t intmax_t;
|
|
||||||
typedef __uintmax_t uintmax_t;
|
|
||||||
|
|
||||||
|
|
||||||
# if __WORDSIZE == 64
|
|
||||||
# define __INT64_C(c) c ## L
|
|
||||||
# define __UINT64_C(c) c ## UL
|
|
||||||
# else
|
|
||||||
# define __INT64_C(c) c ## LL
|
|
||||||
# define __UINT64_C(c) c ## ULL
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Limits of integral types. */
|
|
||||||
|
|
||||||
/* Minimum of signed integral types. */
|
|
||||||
# define INT8_MIN (-128)
|
|
||||||
# define INT16_MIN (-32767-1)
|
|
||||||
# define INT32_MIN (-2147483647-1)
|
|
||||||
# define INT64_MIN (-__INT64_C(9223372036854775807)-1)
|
|
||||||
/* Maximum of signed integral types. */
|
|
||||||
# define INT8_MAX (127)
|
|
||||||
# define INT16_MAX (32767)
|
|
||||||
# define INT32_MAX (2147483647)
|
|
||||||
# define INT64_MAX (__INT64_C(9223372036854775807))
|
|
||||||
|
|
||||||
/* Maximum of unsigned integral types. */
|
|
||||||
# define UINT8_MAX (255)
|
|
||||||
# define UINT16_MAX (65535)
|
|
||||||
# define UINT32_MAX (4294967295U)
|
|
||||||
# define UINT64_MAX (__UINT64_C(18446744073709551615))
|
|
||||||
|
|
||||||
|
|
||||||
/* Minimum of signed integral types having a minimum size. */
|
|
||||||
# define INT_LEAST8_MIN (-128)
|
|
||||||
# define INT_LEAST16_MIN (-32767-1)
|
|
||||||
# define INT_LEAST32_MIN (-2147483647-1)
|
|
||||||
# define INT_LEAST64_MIN (-__INT64_C(9223372036854775807)-1)
|
|
||||||
/* Maximum of signed integral types having a minimum size. */
|
|
||||||
# define INT_LEAST8_MAX (127)
|
|
||||||
# define INT_LEAST16_MAX (32767)
|
|
||||||
# define INT_LEAST32_MAX (2147483647)
|
|
||||||
# define INT_LEAST64_MAX (__INT64_C(9223372036854775807))
|
|
||||||
|
|
||||||
/* Maximum of unsigned integral types having a minimum size. */
|
|
||||||
# define UINT_LEAST8_MAX (255)
|
|
||||||
# define UINT_LEAST16_MAX (65535)
|
|
||||||
# define UINT_LEAST32_MAX (4294967295U)
|
|
||||||
# define UINT_LEAST64_MAX (__UINT64_C(18446744073709551615))
|
|
||||||
|
|
||||||
|
|
||||||
/* Minimum of fast signed integral types having a minimum size. */
|
|
||||||
# define INT_FAST8_MIN (-128)
|
|
||||||
# if __WORDSIZE == 64
|
|
||||||
# define INT_FAST16_MIN (-9223372036854775807L-1)
|
|
||||||
# define INT_FAST32_MIN (-9223372036854775807L-1)
|
|
||||||
# else
|
|
||||||
# define INT_FAST16_MIN (-2147483647-1)
|
|
||||||
# define INT_FAST32_MIN (-2147483647-1)
|
|
||||||
# endif
|
|
||||||
# define INT_FAST64_MIN (-__INT64_C(9223372036854775807)-1)
|
|
||||||
/* Maximum of fast signed integral types having a minimum size. */
|
|
||||||
# define INT_FAST8_MAX (127)
|
|
||||||
# if __WORDSIZE == 64
|
|
||||||
# define INT_FAST16_MAX (9223372036854775807L)
|
|
||||||
# define INT_FAST32_MAX (9223372036854775807L)
|
|
||||||
# else
|
|
||||||
# define INT_FAST16_MAX (2147483647)
|
|
||||||
# define INT_FAST32_MAX (2147483647)
|
|
||||||
# endif
|
|
||||||
# define INT_FAST64_MAX (__INT64_C(9223372036854775807))
|
|
||||||
|
|
||||||
/* Maximum of fast unsigned integral types having a minimum size. */
|
|
||||||
# define UINT_FAST8_MAX (255)
|
|
||||||
# if __WORDSIZE == 64
|
|
||||||
# define UINT_FAST16_MAX (18446744073709551615UL)
|
|
||||||
# define UINT_FAST32_MAX (18446744073709551615UL)
|
|
||||||
# else
|
|
||||||
# define UINT_FAST16_MAX (4294967295U)
|
|
||||||
# define UINT_FAST32_MAX (4294967295U)
|
|
||||||
# endif
|
|
||||||
# define UINT_FAST64_MAX (__UINT64_C(18446744073709551615))
|
|
||||||
|
|
||||||
|
|
||||||
/* Values to test for integral types holding `void *' pointer. */
|
|
||||||
# if __WORDSIZE == 64
|
|
||||||
# define INTPTR_MIN (-9223372036854775807L-1)
|
|
||||||
# define INTPTR_MAX (9223372036854775807L)
|
|
||||||
# define UINTPTR_MAX (18446744073709551615UL)
|
|
||||||
# else
|
|
||||||
# define INTPTR_MIN (-2147483647-1)
|
|
||||||
# define INTPTR_MAX (2147483647)
|
|
||||||
# define UINTPTR_MAX (4294967295U)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Minimum for largest signed integral type. */
|
|
||||||
# define INTMAX_MIN (-__INT64_C(9223372036854775807)-1)
|
|
||||||
/* Maximum for largest signed integral type. */
|
|
||||||
# define INTMAX_MAX (__INT64_C(9223372036854775807))
|
|
||||||
|
|
||||||
/* Maximum for largest unsigned integral type. */
|
|
||||||
# define UINTMAX_MAX (__UINT64_C(18446744073709551615))
|
|
||||||
|
|
||||||
|
|
||||||
/* Limits of other integer types. */
|
|
||||||
|
|
||||||
/* Limits of `ptrdiff_t' type. */
|
|
||||||
# if __WORDSIZE == 64
|
|
||||||
# define PTRDIFF_MIN (-9223372036854775807L-1)
|
|
||||||
# define PTRDIFF_MAX (9223372036854775807L)
|
|
||||||
# else
|
|
||||||
# if __WORDSIZE32_PTRDIFF_LONG
|
|
||||||
# define PTRDIFF_MIN (-2147483647L-1)
|
|
||||||
# define PTRDIFF_MAX (2147483647L)
|
|
||||||
# else
|
|
||||||
# define PTRDIFF_MIN (-2147483647-1)
|
|
||||||
# define PTRDIFF_MAX (2147483647)
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Limits of `sig_atomic_t'. */
|
|
||||||
# define SIG_ATOMIC_MIN (-2147483647-1)
|
|
||||||
# define SIG_ATOMIC_MAX (2147483647)
|
|
||||||
|
|
||||||
/* Limit of `size_t' type. */
|
|
||||||
# if __WORDSIZE == 64
|
|
||||||
# define SIZE_MAX (18446744073709551615UL)
|
|
||||||
# else
|
|
||||||
# if __WORDSIZE32_SIZE_ULONG
|
|
||||||
# define SIZE_MAX (4294967295UL)
|
|
||||||
# else
|
|
||||||
# define SIZE_MAX (4294967295U)
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Limits of `wchar_t'. */
|
|
||||||
# ifndef WCHAR_MIN
|
|
||||||
/* These constants might also be defined in <wchar.h>. */
|
|
||||||
# define WCHAR_MIN __WCHAR_MIN
|
|
||||||
# define WCHAR_MAX __WCHAR_MAX
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Limits of `wint_t'. */
|
|
||||||
# define WINT_MIN (0u)
|
|
||||||
# define WINT_MAX (4294967295u)
|
|
||||||
|
|
||||||
/* Signed. */
|
|
||||||
# define INT8_C(c) c
|
|
||||||
# define INT16_C(c) c
|
|
||||||
# define INT32_C(c) c
|
|
||||||
# if __WORDSIZE == 64
|
|
||||||
# define INT64_C(c) c ## L
|
|
||||||
# else
|
|
||||||
# define INT64_C(c) c ## LL
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Unsigned. */
|
|
||||||
# define UINT8_C(c) c
|
|
||||||
# define UINT16_C(c) c
|
|
||||||
# define UINT32_C(c) c ## U
|
|
||||||
# if __WORDSIZE == 64
|
|
||||||
# define UINT64_C(c) c ## UL
|
|
||||||
# else
|
|
||||||
# define UINT64_C(c) c ## ULL
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Maximal type. */
|
|
||||||
# if __WORDSIZE == 64
|
|
||||||
# define INTMAX_C(c) c ## L
|
|
||||||
# define UINTMAX_C(c) c ## UL
|
|
||||||
# else
|
|
||||||
# define INTMAX_C(c) c ## LL
|
|
||||||
# define UINTMAX_C(c) c ## ULL
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* stdint.h */
|
|
@ -6,5 +6,4 @@
|
|||||||
missing_docs,
|
missing_docs,
|
||||||
clippy::module_inception
|
clippy::module_inception
|
||||||
)]
|
)]
|
||||||
pub mod bindings;
|
|
||||||
pub mod linux_bpf;
|
pub mod linux_bpf;
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file sched-wrapper.h
|
|
||||||
* @author longjin (longjin@RinGoTek.cn)
|
|
||||||
* @brief 这是为调度器相关接口创建rust绑定的wrapper
|
|
||||||
* @version 0.1
|
|
||||||
* @date 2022-11-10
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <common/glib.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 在默认窗口上输出一个字符
|
|
||||||
*
|
|
||||||
* @param character 字符
|
|
||||||
* @param FRcolor 前景色(RGB)
|
|
||||||
* @param BKcolor 背景色(RGB)
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
extern int rs_textui_putchar(uint16_t character, uint32_t FRcolor, uint32_t BKcolor);
|
|
@ -1,8 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
driver::{
|
driver::{serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager},
|
||||||
serial::serial8250::send_to_default_serial8250_port, tty::virtual_terminal::vc_manager,
|
|
||||||
video::video_refresh_manager,
|
|
||||||
},
|
|
||||||
libs::{
|
libs::{
|
||||||
lib_ui::font::FONT_8x16,
|
lib_ui::font::FONT_8x16,
|
||||||
rwlock::RwLock,
|
rwlock::RwLock,
|
||||||
@ -1017,69 +1014,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 在默认窗口上输出一个字符
|
|
||||||
/// ## 参数
|
|
||||||
/// - character 字符
|
|
||||||
/// - FRcolor 前景色(RGB)
|
|
||||||
/// - BKcolor 背景色(RGB)
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn rs_textui_putchar(character: u8, fr_color: u32, bk_color: u32) -> i32 {
|
|
||||||
if let Some(current_vc) = vc_manager().current_vc() {
|
|
||||||
// tty已经初始化了之后才输出到屏幕
|
|
||||||
let fr = (fr_color & 0x00ff0000) >> 16;
|
|
||||||
let fg = (fr_color & 0x0000ff00) >> 8;
|
|
||||||
let fb = fr_color & 0x000000ff;
|
|
||||||
let br = (bk_color & 0x00ff0000) >> 16;
|
|
||||||
let bg = (bk_color & 0x0000ff00) >> 8;
|
|
||||||
let bb = bk_color & 0x000000ff;
|
|
||||||
let buf = format!(
|
|
||||||
"\x1B[38;2;{fr};{fg};{fb};48;2;{br};{bg};{bb}m{}\x1B[0m",
|
|
||||||
character as char
|
|
||||||
);
|
|
||||||
let port = current_vc.port();
|
|
||||||
let tty = port.port_data().internal_tty();
|
|
||||||
if let Some(tty) = tty {
|
|
||||||
return tty
|
|
||||||
.write_to_core(buf.as_bytes(), buf.len())
|
|
||||||
.map(|_| 0)
|
|
||||||
.unwrap_or_else(|e| e.to_posix_errno());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return textui_putchar(
|
|
||||||
character as char,
|
|
||||||
FontColor::from(fr_color),
|
|
||||||
FontColor::from(bk_color),
|
|
||||||
)
|
|
||||||
.map(|_| 0)
|
|
||||||
.unwrap_or_else(|e| e.to_posix_errno());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn textui_putchar(
|
|
||||||
character: char,
|
|
||||||
fr_color: FontColor,
|
|
||||||
bk_color: FontColor,
|
|
||||||
) -> Result<(), SystemError> {
|
|
||||||
if unsafe { TEXTUI_IS_INIT } {
|
|
||||||
return textui_framework()
|
|
||||||
.current_window
|
|
||||||
.lock_irqsave()
|
|
||||||
.textui_putchar_window(
|
|
||||||
character,
|
|
||||||
fr_color,
|
|
||||||
bk_color,
|
|
||||||
textui_is_enable_put_to_window(),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
//未初始化暴力输出
|
|
||||||
return no_init_textui_putchar_window(
|
|
||||||
character,
|
|
||||||
fr_color,
|
|
||||||
bk_color,
|
|
||||||
textui_is_enable_put_to_window(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 向默认窗口输出一个字符串
|
/// 向默认窗口输出一个字符串
|
||||||
pub fn textui_putstr(
|
pub fn textui_putstr(
|
||||||
string: &str,
|
string: &str,
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
//! 这是暴露给C的接口,用于在C语言中使用Rust的内存分配器。
|
|
||||||
|
|
||||||
use core::intrinsics::unlikely;
|
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
|
||||||
use hashbrown::HashMap;
|
|
||||||
use log::error;
|
|
||||||
use system_error::SystemError;
|
|
||||||
|
|
||||||
use crate::libs::spinlock::SpinLock;
|
|
||||||
|
|
||||||
use super::{mmio_buddy::mmio_pool, VirtAddr};
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
// 用于记录内核分配给C的空间信息
|
|
||||||
static ref C_ALLOCATION_MAP: SpinLock<HashMap<VirtAddr, (VirtAddr, usize, usize)>> = SpinLock::new(HashMap::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn kzalloc(size: usize, _gfp: u64) -> usize {
|
|
||||||
// debug!("kzalloc: size: {size}");
|
|
||||||
return do_kmalloc(size, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn kmalloc(size: usize, _gfp: u64) -> usize {
|
|
||||||
// debug!("kmalloc: size: {size}");
|
|
||||||
// 由于C代码不规范,因此都全部清空
|
|
||||||
return do_kmalloc(size, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn do_kmalloc(size: usize, _zero: bool) -> usize {
|
|
||||||
let space: Vec<u8> = vec![0u8; size];
|
|
||||||
|
|
||||||
assert!(space.len() == size);
|
|
||||||
let (ptr, len, cap) = space.into_raw_parts();
|
|
||||||
if !ptr.is_null() {
|
|
||||||
let vaddr = VirtAddr::new(ptr as usize);
|
|
||||||
let mut guard = C_ALLOCATION_MAP.lock();
|
|
||||||
if unlikely(guard.contains_key(&vaddr)) {
|
|
||||||
drop(guard);
|
|
||||||
unsafe {
|
|
||||||
drop(Vec::from_raw_parts(vaddr.data() as *mut u8, len, cap));
|
|
||||||
}
|
|
||||||
panic!(
|
|
||||||
"do_kmalloc: vaddr {:?} already exists in C Allocation Map, query size: {size}, zero: {_zero}",
|
|
||||||
vaddr
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// 插入到C Allocation Map中
|
|
||||||
guard.insert(vaddr, (vaddr, len, cap));
|
|
||||||
return vaddr.data();
|
|
||||||
} else {
|
|
||||||
return SystemError::ENOMEM.to_posix_errno() as i64 as usize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn kfree(vaddr: usize) -> usize {
|
|
||||||
let vaddr = VirtAddr::new(vaddr);
|
|
||||||
let mut guard = C_ALLOCATION_MAP.lock();
|
|
||||||
let p = guard.remove(&vaddr);
|
|
||||||
drop(guard);
|
|
||||||
|
|
||||||
if p.is_none() {
|
|
||||||
error!("kfree: vaddr {:?} not found in C Allocation Map", vaddr);
|
|
||||||
return SystemError::EINVAL.to_posix_errno() as i64 as usize;
|
|
||||||
}
|
|
||||||
let (vaddr, len, cap) = p.unwrap();
|
|
||||||
drop(Vec::from_raw_parts(vaddr.data() as *mut u8, len, cap));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief 创建一块mmio区域,并将vma绑定到initial_mm
|
|
||||||
///
|
|
||||||
/// @param size mmio区域的大小(字节)
|
|
||||||
///
|
|
||||||
/// @param vm_flags 要把vma设置成的标志
|
|
||||||
///
|
|
||||||
/// @param res_vaddr 返回值-分配得到的虚拟地址
|
|
||||||
///
|
|
||||||
/// @param res_length 返回值-分配的虚拟地址空间长度
|
|
||||||
///
|
|
||||||
/// @return int 错误码
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn rs_mmio_create(
|
|
||||||
size: u32,
|
|
||||||
_vm_flags: u64,
|
|
||||||
res_vaddr: *mut u64,
|
|
||||||
res_length: *mut u64,
|
|
||||||
) -> i32 {
|
|
||||||
// debug!("mmio_create");
|
|
||||||
let r = mmio_pool().create_mmio(size as usize);
|
|
||||||
if let Err(e) = r {
|
|
||||||
return e.to_posix_errno();
|
|
||||||
}
|
|
||||||
let space_guard = r.unwrap();
|
|
||||||
*res_vaddr = space_guard.vaddr().data() as u64;
|
|
||||||
*res_length = space_guard.size() as u64;
|
|
||||||
// 由于space_guard drop的时候会自动释放内存,所以这里要忽略它的释放
|
|
||||||
core::mem::forget(space_guard);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief 取消mmio的映射并将地址空间归还到buddy中
|
|
||||||
///
|
|
||||||
/// @param vaddr 起始的虚拟地址
|
|
||||||
///
|
|
||||||
/// @param length 要归还的地址空间的长度
|
|
||||||
///
|
|
||||||
/// @return Ok(i32) 成功返回0
|
|
||||||
///
|
|
||||||
/// @return Err(i32) 失败返回错误码
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn rs_mmio_release(vaddr: u64, length: u64) -> i32 {
|
|
||||||
return mmio_pool()
|
|
||||||
.release_mmio(VirtAddr::new(vaddr as usize), length as usize)
|
|
||||||
.unwrap_or_else(|err| err.to_posix_errno());
|
|
||||||
}
|
|
@ -1,137 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <common/glib.h>
|
|
||||||
#include <process/process.h>
|
|
||||||
|
|
||||||
#define PAGE_4K_SHIFT 12
|
|
||||||
#define PAGE_2M_SHIFT 21
|
|
||||||
#define PAGE_1G_SHIFT 30
|
|
||||||
#define PAGE_GDT_SHIFT 39
|
|
||||||
|
|
||||||
// 不同大小的页的容量
|
|
||||||
#define PAGE_4K_SIZE (1UL << PAGE_4K_SHIFT)
|
|
||||||
#define PAGE_2M_SIZE (1UL << PAGE_2M_SHIFT)
|
|
||||||
#define PAGE_1G_SIZE (1UL << PAGE_1G_SHIFT)
|
|
||||||
|
|
||||||
// 屏蔽低于x的数值
|
|
||||||
#define PAGE_4K_MASK (~(PAGE_4K_SIZE - 1))
|
|
||||||
#define PAGE_2M_MASK (~(PAGE_2M_SIZE - 1))
|
|
||||||
|
|
||||||
// 将addr按照x的上边界对齐
|
|
||||||
#define PAGE_4K_ALIGN(addr) \
|
|
||||||
(((unsigned long)(addr) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK)
|
|
||||||
#define PAGE_2M_ALIGN(addr) \
|
|
||||||
(((unsigned long)(addr) + PAGE_2M_SIZE - 1) & PAGE_2M_MASK)
|
|
||||||
|
|
||||||
// 虚拟地址与物理地址转换
|
|
||||||
#define virt_2_phys(addr) ((unsigned long)(addr)-PAGE_OFFSET)
|
|
||||||
#define phys_2_virt(addr) \
|
|
||||||
((unsigned long *)((unsigned long)(addr) + PAGE_OFFSET))
|
|
||||||
|
|
||||||
// ===== 页面属性 =====
|
|
||||||
// 页面在页表中已被映射 mapped=1 unmapped=0
|
|
||||||
#define PAGE_PGT_MAPPED (1 << 0)
|
|
||||||
|
|
||||||
// 内核初始化所占用的页 init-code=1 normal-code/data=0
|
|
||||||
#define PAGE_KERNEL_INIT (1 << 1)
|
|
||||||
|
|
||||||
// 1=设备MMIO映射的内存 0=物理内存
|
|
||||||
#define PAGE_DEVICE (1 << 2)
|
|
||||||
|
|
||||||
// 内核层页 kernel=1 memory=0
|
|
||||||
#define PAGE_KERNEL (1 << 3)
|
|
||||||
|
|
||||||
// 共享的页 shared=1 single-use=0
|
|
||||||
#define PAGE_SHARED (1 << 4)
|
|
||||||
|
|
||||||
// =========== 页表项权限 ========
|
|
||||||
|
|
||||||
// bit 63 Execution Disable:
|
|
||||||
#define PAGE_XD (1UL << 63)
|
|
||||||
|
|
||||||
// bit 12 Page Attribute Table
|
|
||||||
#define PAGE_PAT (1UL << 12)
|
|
||||||
// 对于PTE而言,第7位是PAT
|
|
||||||
#define PAGE_4K_PAT (1UL << 7)
|
|
||||||
|
|
||||||
// bit 8 Global Page:1,global;0,part
|
|
||||||
#define PAGE_GLOBAL (1UL << 8)
|
|
||||||
|
|
||||||
// bit 7 Page Size:1,big page;0,small page;
|
|
||||||
#define PAGE_PS (1UL << 7)
|
|
||||||
|
|
||||||
// bit 6 Dirty:1,dirty;0,clean;
|
|
||||||
#define PAGE_DIRTY (1UL << 6)
|
|
||||||
|
|
||||||
// bit 5 Accessed:1,visited;0,unvisited;
|
|
||||||
#define PAGE_ACCESSED (1UL << 5)
|
|
||||||
|
|
||||||
// bit 4 Page Level Cache Disable
|
|
||||||
#define PAGE_PCD (1UL << 4)
|
|
||||||
|
|
||||||
// bit 3 Page Level Write Through
|
|
||||||
#define PAGE_PWT (1UL << 3)
|
|
||||||
|
|
||||||
// bit 2 User Supervisor:1,user and supervisor;0,supervisor;
|
|
||||||
#define PAGE_U_S (1UL << 2)
|
|
||||||
|
|
||||||
// bit 1 Read Write:1,read and write;0,read;
|
|
||||||
#define PAGE_R_W (1UL << 1)
|
|
||||||
|
|
||||||
// bit 0 Present:1,present;0,no present;
|
|
||||||
#define PAGE_PRESENT (1UL << 0)
|
|
||||||
|
|
||||||
// 1,0
|
|
||||||
#define PAGE_KERNEL_PGT (PAGE_R_W | PAGE_PRESENT)
|
|
||||||
|
|
||||||
// 1,0
|
|
||||||
#define PAGE_KERNEL_DIR (PAGE_R_W | PAGE_PRESENT)
|
|
||||||
|
|
||||||
// 1,0 (4级页表在3级页表中的页表项的属性)
|
|
||||||
#define PAGE_KERNEL_PDE (PAGE_R_W | PAGE_PRESENT)
|
|
||||||
|
|
||||||
// 7,1,0
|
|
||||||
#define PAGE_KERNEL_PAGE (PAGE_PS | PAGE_R_W | PAGE_PRESENT)
|
|
||||||
|
|
||||||
#define PAGE_KERNEL_4K_PAGE (PAGE_R_W | PAGE_PRESENT)
|
|
||||||
|
|
||||||
#define PAGE_USER_PGT (PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
|
|
||||||
|
|
||||||
// 2,1,0
|
|
||||||
#define PAGE_USER_DIR (PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
|
|
||||||
|
|
||||||
// 1,0 (4级页表在3级页表中的页表项的属性)
|
|
||||||
#define PAGE_USER_PDE (PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
|
|
||||||
// 7,2,1,0
|
|
||||||
#define PAGE_USER_PAGE (PAGE_PS | PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
|
|
||||||
|
|
||||||
#define PAGE_USER_4K_PAGE (PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
|
|
||||||
|
|
||||||
// 导出内核程序的几个段的起止地址
|
|
||||||
extern char _text;
|
|
||||||
extern char _etext;
|
|
||||||
extern char _data;
|
|
||||||
extern char _edata;
|
|
||||||
extern char _rodata;
|
|
||||||
extern char _erodata;
|
|
||||||
extern char _bss;
|
|
||||||
extern char _ebss;
|
|
||||||
extern char _end;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* vm_area_struct中的vm_flags的可选值
|
|
||||||
* 对应的结构体请见mm-types.h
|
|
||||||
*/
|
|
||||||
#define VM_NONE 0
|
|
||||||
#define VM_READ (1 << 0)
|
|
||||||
#define VM_WRITE (1 << 1)
|
|
||||||
#define VM_EXEC (1 << 2)
|
|
||||||
#define VM_SHARED (1 << 3)
|
|
||||||
#define VM_IO (1 << 4) // MMIO的内存区域
|
|
||||||
#define VM_SOFTDIRTY (1 << 5)
|
|
||||||
#define VM_MAYSHARE (1 << 6) // 该vma可被共享
|
|
||||||
#define VM_USER (1 << 7) // 该vma可被用户态访问
|
|
||||||
#define VM_DONTCOPY (1 << 8) // 当fork的时候不拷贝该虚拟内存区域
|
|
||||||
|
|
||||||
/* VMA basic access permission flags */
|
|
||||||
#define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC)
|
|
@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "mm.h"
|
|
||||||
|
|
||||||
extern int rs_mmio_create(uint32_t size, uint64_t vm_flags, uint64_t* res_vaddr, uint64_t* res_length);
|
|
||||||
extern int rs_mmio_release(uint64_t vaddr, uint64_t length);
|
|
@ -21,7 +21,6 @@ use self::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub mod allocator;
|
pub mod allocator;
|
||||||
pub mod c_adapter;
|
|
||||||
pub mod early_ioremap;
|
pub mod early_ioremap;
|
||||||
pub mod fault;
|
pub mod fault;
|
||||||
pub mod init;
|
pub mod init;
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "mm.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 通用内存分配函数
|
|
||||||
*
|
|
||||||
* @param size 要分配的内存大小
|
|
||||||
* @param gfp 内存的flag
|
|
||||||
* @return void* 分配得到的内存的指针
|
|
||||||
*/
|
|
||||||
extern void *kmalloc(unsigned long size, gfp_t gfp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从kmalloc申请一块内存,并将这块内存清空
|
|
||||||
*
|
|
||||||
* @param size 要分配的内存大小
|
|
||||||
* @param gfp 内存的flag
|
|
||||||
* @return void* 分配得到的内存的指针
|
|
||||||
*/
|
|
||||||
extern void *kzalloc(size_t size, gfp_t gfp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 通用内存释放函数
|
|
||||||
*
|
|
||||||
* @param address 要释放的内存地址
|
|
||||||
* @return unsigned long
|
|
||||||
*/
|
|
||||||
extern unsigned long kfree(void *address);
|
|
@ -1,80 +0,0 @@
|
|||||||
use crate::smp::core::smp_get_processor_id;
|
|
||||||
|
|
||||||
use super::{process_init, ProcessManager, __PROCESS_MANAGEMENT_INIT_DONE};
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn rs_process_init() {
|
|
||||||
process_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 临时用于获取空闲进程的栈顶的函数,这个函数是为了旧的smp模块的初始化而写在这的
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn rs_get_idle_stack_top(cpu_id: u32) -> usize {
|
|
||||||
return ProcessManager::idle_pcb()[cpu_id as usize]
|
|
||||||
.kernel_stack()
|
|
||||||
.stack_max_address()
|
|
||||||
.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn rs_current_pcb_cpuid() -> u32 {
|
|
||||||
return smp_get_processor_id().data();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn rs_current_pcb_pid() -> u32 {
|
|
||||||
if unsafe { __PROCESS_MANAGEMENT_INIT_DONE } {
|
|
||||||
return ProcessManager::current_pcb().pid().0 as u32;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn rs_current_pcb_preempt_count() -> u32 {
|
|
||||||
if unsafe { !__PROCESS_MANAGEMENT_INIT_DONE } {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return ProcessManager::current_pcb().preempt_count() as u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn rs_current_pcb_flags() -> u32 {
|
|
||||||
if unsafe { !__PROCESS_MANAGEMENT_INIT_DONE } {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return ProcessManager::current_pcb().flags().bits() as u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
unsafe extern "C" fn rs_current_pcb_thread_rbp() -> u64 {
|
|
||||||
if unsafe { !__PROCESS_MANAGEMENT_INIT_DONE } {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return ProcessManager::current_pcb().arch_info_irqsave().rbp() as u64;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
#[cfg(target_arch = "riscv64")]
|
|
||||||
unsafe extern "C" fn rs_current_pcb_thread_rbp() -> u64 {
|
|
||||||
// 不应该实现这个函数
|
|
||||||
unimplemented!("rs_current_pcb_thread_rbp")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn rs_preempt_disable() {
|
|
||||||
return ProcessManager::preempt_disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn rs_preempt_enable() {
|
|
||||||
return ProcessManager::preempt_enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
unsafe extern "C" fn rs_process_do_exit(exit_code: usize) -> usize {
|
|
||||||
if unsafe { !__PROCESS_MANAGEMENT_INIT_DONE } {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ProcessManager::exit(exit_code);
|
|
||||||
}
|
|
@ -71,7 +71,6 @@ use timer::AlarmTimer;
|
|||||||
use self::{cred::Cred, kthread::WorkerPrivate};
|
use self::{cred::Cred, kthread::WorkerPrivate};
|
||||||
|
|
||||||
pub mod abi;
|
pub mod abi;
|
||||||
pub mod c_adapter;
|
|
||||||
pub mod cred;
|
pub mod cred;
|
||||||
pub mod exec;
|
pub mod exec;
|
||||||
pub mod exit;
|
pub mod exit;
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
extern void rs_preempt_disable();
|
|
||||||
extern void rs_preempt_enable();
|
|
@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file process.h
|
|
||||||
* @author longjin
|
|
||||||
* @brief 进程
|
|
||||||
* @date 2022-01-29
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "ptrace.h"
|
|
||||||
#include <common/errno.h>
|
|
||||||
#include <common/glib.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 进程退出时执行的函数
|
|
||||||
*
|
|
||||||
* @param code 返回码
|
|
||||||
* @return ul
|
|
||||||
*/
|
|
||||||
extern ul rs_process_do_exit(ul code);
|
|
||||||
|
|
||||||
extern int rs_current_cpu_id();
|
|
||||||
|
|
||||||
extern unsigned long head_stack_start; // 导出内核层栈基地址(定义在head.S)
|
|
||||||
extern ul _stack_start;
|
|
||||||
extern void ret_from_intr(void); // 导出从中断返回的函数(定义在entry.S)
|
|
||||||
|
|
||||||
extern uint32_t rs_current_pcb_cpuid();
|
|
||||||
extern uint32_t rs_current_pcb_pid();
|
|
||||||
extern uint32_t rs_current_pcb_preempt_count();
|
|
||||||
extern uint32_t rs_current_pcb_flags();
|
|
||||||
extern uint64_t rs_current_pcb_thread_rbp();
|
|
||||||
|
|
||||||
#define PF_NEED_SCHED (1UL << 1)
|
|
@ -1,44 +0,0 @@
|
|||||||
#ifndef __PTRACE_H__
|
|
||||||
|
|
||||||
#define __PTRACE_H__
|
|
||||||
|
|
||||||
struct pt_regs
|
|
||||||
{
|
|
||||||
unsigned long r15;
|
|
||||||
unsigned long r14;
|
|
||||||
unsigned long r13;
|
|
||||||
unsigned long r12;
|
|
||||||
unsigned long r11;
|
|
||||||
unsigned long r10;
|
|
||||||
unsigned long r9;
|
|
||||||
unsigned long r8;
|
|
||||||
unsigned long rbx;
|
|
||||||
unsigned long rcx;
|
|
||||||
unsigned long rdx;
|
|
||||||
unsigned long rsi;
|
|
||||||
unsigned long rdi;
|
|
||||||
unsigned long rbp;
|
|
||||||
unsigned long ds;
|
|
||||||
unsigned long es;
|
|
||||||
unsigned long rax;
|
|
||||||
unsigned long func;
|
|
||||||
unsigned long errcode;
|
|
||||||
unsigned long rip;
|
|
||||||
unsigned long cs;
|
|
||||||
unsigned long rflags;
|
|
||||||
unsigned long rsp;
|
|
||||||
unsigned long ss;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 判断pt_regs是否来自用户态
|
|
||||||
*
|
|
||||||
* @param regs
|
|
||||||
* @return __always_inline
|
|
||||||
*/
|
|
||||||
static inline int user_mode(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return !!(regs->cs & 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -110,8 +110,3 @@ pub fn jiffies_init() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn rs_jiffies_init() {
|
|
||||||
jiffies_init();
|
|
||||||
}
|
|
||||||
|
@ -385,10 +385,3 @@ pub fn update_timer_jiffies(add_jiffies: u64) -> u64 {
|
|||||||
pub fn clock() -> u64 {
|
pub fn clock() -> u64 {
|
||||||
return TIMER_JIFFIES.load(Ordering::SeqCst);
|
return TIMER_JIFFIES.load(Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== 以下为给C提供的接口 ======
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn rs_timer_init() {
|
|
||||||
timer_init();
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user