mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 16:26:31 +00:00
feat: la64 boot (#1132)
* la64能够进入到kernel_main * ci: 添加为ubuntu编译qemu-loongarch64的脚本 * feat: la64能输出hello world * la64 安装gcc && 配置github ci * chore: 更新CI工作流和构建脚本中的Docker镜像版本至v1.10 Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
66
.github/workflows/makefile.yml
vendored
66
.github/workflows/makefile.yml
vendored
@ -11,14 +11,14 @@ jobs:
|
||||
name: Format check ${{ matrix.arch }}
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
container: dragonos/dragonos-dev:v1.9
|
||||
container: dragonos/dragonos-dev:v1.10
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x86_64, riscv64]
|
||||
arch: [x86_64, riscv64, loongarch64]
|
||||
|
||||
steps:
|
||||
- run: echo "Running in dragonos/dragonos-dev:v1.9"
|
||||
- run: echo "Running in dragonos/dragonos-dev:v1.10"
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Format check
|
||||
@ -35,14 +35,14 @@ jobs:
|
||||
name: Kernel static test ${{ matrix.arch }}
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
container: dragonos/dragonos-dev:v1.9
|
||||
container: dragonos/dragonos-dev:v1.10
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x86_64, riscv64]
|
||||
arch: [x86_64, riscv64, loongarch64]
|
||||
|
||||
steps:
|
||||
- run: echo "Running in dragonos/dragonos-dev:v1.9"
|
||||
- run: echo "Running in dragonos/dragonos-dev:v1.10"
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
@ -53,46 +53,40 @@ jobs:
|
||||
HOME: /root
|
||||
run: bash -c "source /root/.cargo/env && cd kernel && make test && make test-rbpf"
|
||||
|
||||
build-x86_64:
|
||||
build:
|
||||
name: Build ${{ matrix.arch }}
|
||||
runs-on: ubuntu-latest
|
||||
container: dragonos/dragonos-dev:v1.9
|
||||
container: dragonos/dragonos-dev:v1.10
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- arch: x86_64
|
||||
make_target: all
|
||||
checkout_params: {}
|
||||
- arch: riscv64
|
||||
make_target: all
|
||||
checkout_params:
|
||||
submodules: "recursive"
|
||||
- arch: loongarch64
|
||||
make_target: all
|
||||
checkout_params: {}
|
||||
|
||||
steps:
|
||||
- run: echo "Running in dragonos/dragonos-dev:v1.9"
|
||||
- run: echo "Running in dragonos/dragonos-dev:v1.10"
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- name: build the DragonOS
|
||||
with: ${{ matrix.checkout_params }}
|
||||
|
||||
- name: Build the DragonOS
|
||||
env:
|
||||
ARCH: x86_64
|
||||
ARCH: ${{ matrix.arch }}
|
||||
HOME: /root
|
||||
shell: bash -ileo pipefail {0}
|
||||
|
||||
run: |
|
||||
source ~/.bashrc
|
||||
source ~/.cargo/env
|
||||
if [[ "$ARCH" == "x86_64" ]]; then
|
||||
export DragonOS_GCC=$HOME/opt/dragonos-gcc/gcc-x86_64-unknown-none/bin
|
||||
fi
|
||||
sed -i 's/arch = ".*"/arch = "${{ env.ARCH }}"/' dadk-manifest.toml
|
||||
|
||||
make all -j $(nproc)
|
||||
|
||||
build-riscv64:
|
||||
runs-on: ubuntu-latest
|
||||
container: dragonos/dragonos-dev:v1.9
|
||||
|
||||
steps:
|
||||
- run: echo "Running in dragonos/dragonos-dev:v1.9"
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: build the DragonOS
|
||||
shell: bash -ileo pipefail {0}
|
||||
env:
|
||||
ARCH: riscv64
|
||||
HOME: /root
|
||||
|
||||
run: |
|
||||
source ~/.bashrc && source ~/.cargo/env
|
||||
sed -i 's/arch = ".*"/arch = "${{ env.ARCH }}"/' dadk-manifest.toml
|
||||
make kernel -j $(nproc)
|
||||
make ${{ matrix.make_target }} -j $(nproc)
|
||||
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -9,6 +9,7 @@
|
||||
"./kernel/Cargo.toml",
|
||||
//"./tools/Cargo.toml",
|
||||
],
|
||||
// "rust-analyzer.cargo.target": "loongarch64-unknown-none",
|
||||
// "rust-analyzer.cargo.target": "riscv64gc-unknown-none-elf",
|
||||
"rust-analyzer.cargo.target": "x86_64-unknown-none",
|
||||
"rust-analyzer.check.overrideCommand": [
|
||||
|
2
Makefile
2
Makefile
@ -74,6 +74,8 @@ clean-docs:
|
||||
gdb:
|
||||
ifeq ($(ARCH), x86_64)
|
||||
rust-gdb -n -x tools/.gdbinit
|
||||
else ifeq ($(ARCH), loongarch64)
|
||||
loongarch64-unknown-linux-gnu-gdb -n -x tools/.gdbinit
|
||||
else
|
||||
gdb-multiarch -n -x tools/.gdbinit
|
||||
endif
|
||||
|
10
build-scripts/kernel_build/src/bindgen/arch/loongarch64.rs
Normal file
10
build-scripts/kernel_build/src/bindgen/arch/loongarch64.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use super::BindgenArch;
|
||||
|
||||
pub struct LoongArch64BindgenArch;
|
||||
impl BindgenArch for LoongArch64BindgenArch {
|
||||
fn generate_bindings(&self, builder: bindgen::Builder) -> bindgen::Builder {
|
||||
builder
|
||||
.clang_arg("-I./src/arch/loongarch64/include")
|
||||
.clang_arg("--target=x86_64-none-none") // 由于clang不支持loongarch64,所以使用x86_64作为目标,按理来说问题不大
|
||||
}
|
||||
}
|
29
build-scripts/kernel_build/src/cfiles/arch/loongarch64.rs
Normal file
29
build-scripts/kernel_build/src/cfiles/arch/loongarch64.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use std::{collections::HashSet, path::PathBuf};
|
||||
|
||||
use crate::constant::ARCH_DIR_LOONGARCH64;
|
||||
|
||||
use super::CFilesArch;
|
||||
|
||||
pub(super) struct LoongArch64CFilesArch;
|
||||
|
||||
impl CFilesArch for LoongArch64CFilesArch {
|
||||
fn setup_defines(&self, c: &mut cc::Build) {
|
||||
c.define("__loongarch64__", None);
|
||||
c.define("__loongarch", None);
|
||||
}
|
||||
|
||||
fn setup_files(&self, _c: &mut cc::Build, _files: &mut HashSet<PathBuf>) {}
|
||||
|
||||
fn setup_global_flags(&self, c: &mut cc::Build) {
|
||||
// 在这里设置编译器,不然的话vscode的rust-analyzer会报错
|
||||
c.compiler("loongarch64-unknown-linux-gnu-gcc");
|
||||
c.flag("-mcmodel=normal");
|
||||
|
||||
c.flag("-march=loongarch64");
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn arch_path(relative_path: &str) -> PathBuf {
|
||||
PathBuf::from(format!("{}/{}", ARCH_DIR_LOONGARCH64, relative_path))
|
||||
}
|
@ -6,6 +6,7 @@ use crate::utils::cargo_handler::{CargoHandler, TargetArch};
|
||||
|
||||
use self::x86_64::X86_64CFilesArch;
|
||||
|
||||
pub mod loongarch64;
|
||||
pub mod riscv64;
|
||||
pub mod x86_64;
|
||||
|
||||
@ -24,6 +25,8 @@ pub(super) fn current_cfiles_arch() -> &'static dyn CFilesArch {
|
||||
match arch {
|
||||
TargetArch::X86_64 => &X86_64CFilesArch,
|
||||
TargetArch::Riscv64 => &riscv64::RiscV64CFilesArch,
|
||||
TargetArch::LoongArch64 => &loongarch64::LoongArch64CFilesArch,
|
||||
|
||||
_ => panic!("Unsupported arch: {:?}", arch),
|
||||
}
|
||||
}
|
||||
|
5
build-scripts/kernel_build/src/constant.rs
Normal file
5
build-scripts/kernel_build/src/constant.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#[allow(dead_code)]
|
||||
pub const ARCH_DIR_X86_64: &str = "src/arch/x86_64";
|
||||
#[allow(dead_code)]
|
||||
pub const ARCH_DIR_RISCV64: &str = "src/arch/riscv64";
|
||||
pub const ARCH_DIR_LOONGARCH64: &str = "src/arch/loongarch64";
|
@ -3,6 +3,7 @@ extern crate lazy_static;
|
||||
extern crate cc;
|
||||
|
||||
mod cfiles;
|
||||
mod constant;
|
||||
mod kconfig;
|
||||
mod utils;
|
||||
|
||||
|
@ -68,6 +68,7 @@ pub enum TargetArch {
|
||||
Riscv64,
|
||||
Mips64,
|
||||
Powerpc64,
|
||||
LoongArch64,
|
||||
S390x,
|
||||
Sparc64,
|
||||
Unknown,
|
||||
@ -85,6 +86,7 @@ impl TargetArch {
|
||||
"riscv64" => TargetArch::Riscv64,
|
||||
"mips64" => TargetArch::Mips64,
|
||||
"powerpc64" => TargetArch::Powerpc64,
|
||||
"loongarch64" => TargetArch::LoongArch64,
|
||||
"s390x" => TargetArch::S390x,
|
||||
"sparc64" => TargetArch::Sparc64,
|
||||
_ => TargetArch::Unknown,
|
||||
|
@ -1 +1,51 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub mod cargo_handler;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct FileUtils;
|
||||
|
||||
#[allow(dead_code)]
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
# DADK 总控文件
|
||||
|
||||
[metadata]
|
||||
# Target architecture. Options: x86_64, riscv64
|
||||
# Target architecture. Options: x86_64, riscv64, loongarch64
|
||||
arch = "x86_64"
|
||||
|
||||
# Hypervisor config path
|
||||
|
3
env.mk
3
env.mk
@ -1,6 +1,7 @@
|
||||
|
||||
ifeq ($(ARCH), )
|
||||
# !!!!在这里设置ARCH,可选 x86_64 和 riscv64
|
||||
# !!!!在这里设置ARCH,可选:
|
||||
# x86_64, riscv64, loongarch64
|
||||
# !!!!!!!如果不同时调整这里以及vscode的settings.json,那么自动补全和检查将会失效
|
||||
export ARCH?=x86_64
|
||||
endif
|
||||
|
31
kernel/Cargo.lock
generated
31
kernel/Cargo.lock
generated
@ -361,22 +361,6 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||
|
||||
[[package]]
|
||||
name = "cstr_core"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd98742e4fdca832d40cab219dc2e3048de17d873248f83f17df47c1bea70956"
|
||||
dependencies = [
|
||||
"cty",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cty"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
|
||||
|
||||
[[package]]
|
||||
name = "defer"
|
||||
version = "0.2.1"
|
||||
@ -465,6 +449,7 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"linkme",
|
||||
"log",
|
||||
"loongArch64",
|
||||
"lru",
|
||||
"multiboot2",
|
||||
"num",
|
||||
@ -872,6 +857,15 @@ version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "loongArch64"
|
||||
version = "0.2.4"
|
||||
source = "git+https://github.com/fslongjin/loongArch64?rev=7af150e#7af150e01e7ce3139f519578751c95bbdaf4fb4d"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.12.5"
|
||||
@ -1089,12 +1083,9 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "printf-compat"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b002af28ffe3d3d67202ae717810a28125a494d5396debc43de01ee136ac404"
|
||||
source = "git+https://git.mirrors.dragonos.org.cn/DragonOS-Community/printf-compat?rev=5f5c9cc363#5f5c9cc363f047411a0dccb37e0efb452ffb61d9"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cstr_core",
|
||||
"cty",
|
||||
"itertools",
|
||||
]
|
||||
|
||||
|
@ -73,18 +73,14 @@ kprobe = { path = "crates/kprobe" }
|
||||
lru = "0.12.3"
|
||||
|
||||
rbpf = { path = "crates/rbpf" }
|
||||
printf-compat = { version = "0.1.1", default-features = false }
|
||||
printf-compat = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/printf-compat", rev = "5f5c9cc363", default-features = false }
|
||||
|
||||
static-keys = "=0.6.1"
|
||||
unwinding = { version = "=0.2.3", default-features = false, features = [
|
||||
"unwinder",
|
||||
"fde-gnu-eh-frame-hdr",
|
||||
"panic",
|
||||
"personality",
|
||||
] }
|
||||
|
||||
defer = "0.2.1"
|
||||
cfg-if = { version = "1.0.0" }
|
||||
|
||||
|
||||
# target为x86_64时,使用下面的依赖
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
multiboot2 = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/multiboot2", rev = "05739aab40" }
|
||||
@ -99,6 +95,18 @@ riscv = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/riscv.gi
|
||||
] }
|
||||
sbi-rt = { version = "=0.0.3", features = ["legacy"] }
|
||||
|
||||
# target为loongarch64时,使用下面的依赖
|
||||
[target.'cfg(target_arch = "loongarch64")'.dependencies]
|
||||
loongArch64 = { git = "https://github.com/fslongjin/loongArch64", rev = "7af150e" }
|
||||
|
||||
# 由于unwinding库不支持loongarch64架构,因此需要排除该依赖项
|
||||
[target.'cfg(not(target_arch = "loongarch64"))'.dependencies]
|
||||
unwinding = { version = "=0.2.3", default-features = false, features = [
|
||||
"unwinder",
|
||||
"fde-gnu-eh-frame-hdr",
|
||||
"panic",
|
||||
"personality",
|
||||
] }
|
||||
|
||||
# 构建时依赖项
|
||||
[build-dependencies]
|
||||
|
@ -7,6 +7,10 @@ ifeq ($(ARCH), x86_64)
|
||||
export TARGET_JSON=arch/x86_64/x86_64-unknown-none.json
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
export TARGET_JSON=arch/riscv64/riscv64gc-unknown-none-elf.json
|
||||
else ifeq ($(ARCH), loongarch64)
|
||||
export TARGET_JSON=arch/loongarch64/loongarch64-unknown-none.json
|
||||
else
|
||||
$(error "Unsupported ARCH: $(ARCH)")
|
||||
endif
|
||||
|
||||
export CARGO_ZBUILD=-Z build-std=core,alloc,compiler_builtins -Z build-std-features=compiler-builtins-mem
|
||||
|
@ -77,6 +77,7 @@ impl KprobeBuilder {
|
||||
};
|
||||
let inst_tmp_ptr = point.inst_tmp.as_ptr() as usize;
|
||||
let inst_32 = unsafe { core::ptr::read(address as *const u32) };
|
||||
|
||||
unsafe {
|
||||
core::ptr::write(address as *mut u32, EBREAK_INST);
|
||||
// inst_32 :0-32
|
||||
@ -90,6 +91,7 @@ impl KprobeBuilder {
|
||||
self.symbol,
|
||||
inst_32
|
||||
);
|
||||
Arc::new(point)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,10 @@ ifeq ($(ARCH), x86_64)
|
||||
CCPREFIX=x86_64-linux-gnu-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
CCPREFIX=riscv64-linux-gnu-
|
||||
else ifeq ($(ARCH), loongarch64)
|
||||
CCPREFIX=loongarch64-unknown-linux-gnu-
|
||||
else
|
||||
$(error "Unsupported ARCH: $(ARCH)")
|
||||
endif
|
||||
|
||||
export CC=$(CCPREFIX)gcc
|
||||
@ -24,6 +28,8 @@ ifeq ($(ARCH), x86_64)
|
||||
GLOBAL_CFLAGS += -mcmodel=large -m64
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
GLOBAL_CFLAGS += -mcmodel=medany -march=rv64gc -mabi=lp64d
|
||||
else ifeq ($(ARCH), loongarch64)
|
||||
GLOBAL_CFLAGS += -mcmodel=large -march=loongarch64
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG), DEBUG)
|
||||
|
@ -10,17 +10,20 @@ LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns)))
|
||||
|
||||
# unwind/backtrace related
|
||||
UNWIND_ENABLE ?= yes
|
||||
|
||||
ifeq ($(ARCH), loongarch64)
|
||||
UNWIND_ENABLE = no
|
||||
endif
|
||||
|
||||
CFLAGS_UNWIND =
|
||||
LDFLAGS_UNWIND =
|
||||
RUSTFLAGS_UNWIND =
|
||||
ifeq ($(UNWIND_ENABLE), yes)
|
||||
CFLAGS_UNWIND = -funwind-tables
|
||||
LDFLAGS_UNWIND = --eh-frame-hdr
|
||||
RUSTFLAGS_UNWIND = -Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld -Cpanic=unwind
|
||||
RUSTFLAGS += -Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld -Cpanic=unwind
|
||||
endif
|
||||
|
||||
RUSTFLAGS += $(RUSTFLAGS_UNWIND)
|
||||
|
||||
CFLAGS = $(GLOBAL_CFLAGS) -fno-pie $(CFLAGS_UNWIND) -I $(shell pwd) -I $(shell pwd)/include
|
||||
|
||||
ifeq ($(ARCH), x86_64)
|
||||
@ -48,6 +51,10 @@ ifeq ($(ARCH), x86_64)
|
||||
$(MAKE) __link_x86_64_kernel
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
$(MAKE) __link_riscv64_kernel
|
||||
else ifeq ($(ARCH), loongarch64)
|
||||
$(MAKE) __link_loongarch64_kernel
|
||||
else
|
||||
$(error Unknown ARCH: $(ARCH))
|
||||
endif
|
||||
|
||||
@echo "Kernel Build Done."
|
||||
@ -113,6 +120,32 @@ else
|
||||
endif
|
||||
rm kernel
|
||||
|
||||
|
||||
__link_loongarch64_kernel:
|
||||
@echo "Linking kernel..."
|
||||
$(LD) -b elf64-loongarch -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/loongarch64-unknown-none/release/libdragonos_kernel.a -T arch/loongarch64/link.ld --no-relax
|
||||
# 生成kallsyms
|
||||
current_dir=$(pwd)
|
||||
|
||||
@dbg='debug';for x in $$dbg; do \
|
||||
cd $$x;\
|
||||
$(MAKE) generate_kallsyms kernel_root_path="$(shell pwd)"||exit 1;\
|
||||
cd ..;\
|
||||
done
|
||||
|
||||
# 重新链接
|
||||
@echo "Re-Linking kernel..."
|
||||
@echo $(shell find . -name "*.o")
|
||||
$(LD) -b elf64-loongarch -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/loongarch64-unknown-none/release/libdragonos_kernel.a ./debug/kallsyms.o -T arch/loongarch64/link.ld --no-relax
|
||||
@echo "Generating kernel ELF file..."
|
||||
# 生成内核文件
|
||||
ifeq ($(UNWIND_ENABLE), yes)
|
||||
$(OBJCOPY) -I elf64-loongarch -O elf64-loongarch kernel ../../bin/kernel/kernel.elf
|
||||
else
|
||||
$(OBJCOPY) -I elf64-loongarch -O elf64-loongarch -R ".eh_frame" kernel ../../bin/kernel/kernel.elf
|
||||
endif
|
||||
rm kernel
|
||||
|
||||
__dragon_stub:
|
||||
@echo "Linking dragon_stub..."
|
||||
@mkdir -p $(ROOT_PATH)/bin/sysroot
|
||||
|
14
kernel/src/arch/loongarch64/asm/bitops.rs
Normal file
14
kernel/src/arch/loongarch64/asm/bitops.rs
Normal file
@ -0,0 +1,14 @@
|
||||
/// 寻找u64中的第一个0所在的位(从第0位开始寻找)
|
||||
///
|
||||
/// 注意:如果x中没有0,那么结果将是未定义的。请确保传入的x至少存在1个0
|
||||
///
|
||||
/// # 参数
|
||||
/// * `x` - 目标u64
|
||||
///
|
||||
/// # 返回值
|
||||
/// 第一个(最低有效位)0位的位号(0..63)
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn ffz(x: u64) -> i32 {
|
||||
(!x).trailing_zeros() as i32
|
||||
}
|
98
kernel/src/arch/loongarch64/asm/boot.rs
Normal file
98
kernel/src/arch/loongarch64/asm/boot.rs
Normal file
@ -0,0 +1,98 @@
|
||||
///
|
||||
/// The earliest entry point for the primary CPU.
|
||||
///
|
||||
/// 这些代码拷贝、修改自 polyhal (https://github.com/Byte-OS/polyhal.git)
|
||||
use crate::arch::{cpu::current_cpu_id, init::boot::kernel_main};
|
||||
|
||||
const QEMU_DTB_PADDR: usize = 0x100000;
|
||||
|
||||
/// The earliest entry point for the primary CPU.
|
||||
///
|
||||
/// We can't use bl to jump to higher address, so we use jirl to jump to higher address.
|
||||
#[naked]
|
||||
#[no_mangle]
|
||||
#[link_section = ".text.entry"]
|
||||
unsafe extern "C" fn _start() -> ! {
|
||||
core::arch::naked_asm!("
|
||||
|
||||
ori $t0, $zero, 0x1 # CSR_DMW1_PLV0
|
||||
lu52i.d $t0, $t0, -2048 # UC, PLV0, 0x8000 xxxx xxxx xxxx
|
||||
csrwr $t0, 0x180 # LOONGARCH_CSR_DMWIN0
|
||||
ori $t0, $zero, 0x11 # CSR_DMW1_MAT | CSR_DMW1_PLV0
|
||||
lu52i.d $t0, $t0, -1792 # CA, PLV0, 0x9000 xxxx xxxx xxxx
|
||||
csrwr $t0, 0x181 # LOONGARCH_CSR_DMWIN1
|
||||
|
||||
# Goto 1 if hart is not 0
|
||||
csrrd $t1, 0x20 # read cpu from csr
|
||||
bnez $t1, 1f
|
||||
|
||||
# Enable PG
|
||||
li.w $t0, 0xb0 # PLV=0, IE=0, PG=1
|
||||
csrwr $t0, 0x0 # LOONGARCH_CSR_CRMD
|
||||
li.w $t0, 0x00 # PLV=0, PIE=0, PWE=0
|
||||
csrwr $t0, 0x1 # LOONGARCH_CSR_PRMD
|
||||
li.w $t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0
|
||||
csrwr $t0, 0x2 # LOONGARCH_CSR_EUEN
|
||||
|
||||
|
||||
la.global $sp, {boot_stack}
|
||||
li.d $t0, {boot_stack_size}
|
||||
add.d $sp, $sp, $t0 # setup boot stack
|
||||
csrrd $a0, 0x20 # cpuid
|
||||
la.global $t0, {entry}
|
||||
jirl $zero,$t0,0
|
||||
1:
|
||||
li.w $s0, {MBUF0}
|
||||
iocsrrd.d $t0, $s0
|
||||
la.global $t1, {sec_entry}
|
||||
bne $t0, $t1, 1b
|
||||
jirl $zero, $t1, 0
|
||||
",
|
||||
boot_stack_size = const size_of_val(&crate::arch::process::BSP_IDLE_STACK_SPACE),
|
||||
boot_stack = sym crate::arch::process::BSP_IDLE_STACK_SPACE,
|
||||
MBUF0 = const loongArch64::consts::LOONGARCH_CSR_MAIL_BUF0,
|
||||
entry = sym rust_tmp_main,
|
||||
sec_entry = sym _start_secondary,
|
||||
)
|
||||
}
|
||||
|
||||
/// The earliest entry point for the primary CPU.
|
||||
///
|
||||
/// We can't use bl to jump to higher address, so we use jirl to jump to higher address.
|
||||
#[naked]
|
||||
#[no_mangle]
|
||||
#[link_section = ".text.entry"]
|
||||
pub(crate) unsafe extern "C" fn _start_secondary() -> ! {
|
||||
core::arch::naked_asm!(
|
||||
"
|
||||
ori $t0, $zero, 0x1 # CSR_DMW1_PLV0
|
||||
lu52i.d $t0, $t0, -2048 # UC, PLV0, 0x8000 xxxx xxxx xxxx
|
||||
csrwr $t0, 0x180 # LOONGARCH_CSR_DMWIN0
|
||||
ori $t0, $zero, 0x11 # CSR_DMW1_MAT | CSR_DMW1_PLV0
|
||||
lu52i.d $t0, $t0, -1792 # CA, PLV0, 0x9000 xxxx xxxx xxxx
|
||||
csrwr $t0, 0x181 # LOONGARCH_CSR_DMWIN1
|
||||
|
||||
li.w $t0, {MBUF1}
|
||||
iocsrrd.d $sp, $t0
|
||||
|
||||
csrrd $a0, 0x20 # cpuid
|
||||
la.global $t0, {entry}
|
||||
|
||||
jirl $zero,$t0,0
|
||||
",
|
||||
MBUF1 = const loongArch64::consts::LOONGARCH_CSR_MAIL_BUF1,
|
||||
entry = sym _rust_secondary_main,
|
||||
)
|
||||
}
|
||||
|
||||
/// Rust temporary entry point
|
||||
///
|
||||
/// This function will be called after assembly boot stage.
|
||||
fn rust_tmp_main(hart_id: usize) {
|
||||
unsafe { kernel_main(hart_id, QEMU_DTB_PADDR) };
|
||||
}
|
||||
|
||||
/// The entry point for the second core.
|
||||
pub(crate) extern "C" fn _rust_secondary_main() {
|
||||
unsafe { kernel_main(current_cpu_id().data() as usize, QEMU_DTB_PADDR) }
|
||||
}
|
2
kernel/src/arch/loongarch64/asm/mod.rs
Normal file
2
kernel/src/arch/loongarch64/asm/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod bitops;
|
||||
pub mod boot;
|
15
kernel/src/arch/loongarch64/cpu.rs
Normal file
15
kernel/src/arch/loongarch64/cpu.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use crate::smp::cpu::ProcessorId;
|
||||
|
||||
/// 重置cpu
|
||||
pub unsafe fn cpu_reset() -> ! {
|
||||
log::warn!("cpu_reset on loongarch64 platform was not implemented!");
|
||||
loop {
|
||||
unsafe { loongArch64::asm::idle() };
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取当前cpu的id
|
||||
#[inline]
|
||||
pub fn current_cpu_id() -> ProcessorId {
|
||||
ProcessorId::new(loongArch64::register::cpuid::read().core_id() as u32)
|
||||
}
|
10
kernel/src/arch/loongarch64/elf.rs
Normal file
10
kernel/src/arch/loongarch64/elf.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use crate::{arch::MMArch, libs::elf::ElfArch, mm::MemoryManagementArch};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash)]
|
||||
pub struct LoongArch64ElfArch;
|
||||
|
||||
impl ElfArch for LoongArch64ElfArch {
|
||||
const ELF_ET_DYN_BASE: usize = MMArch::USER_END_VADDR.data() / 3 * 2;
|
||||
|
||||
const ELF_PAGE_SIZE: usize = MMArch::PAGE_SIZE;
|
||||
}
|
1
kernel/src/arch/loongarch64/include/asm/asm.h
Normal file
1
kernel/src/arch/loongarch64/include/asm/asm.h
Normal file
@ -0,0 +1 @@
|
||||
#pragma once
|
54
kernel/src/arch/loongarch64/init/boot.rs
Normal file
54
kernel/src/arch/loongarch64/init/boot.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use loongArch64::register::{ecfg, eentry};
|
||||
|
||||
use crate::{init::init::start_kernel, mm::PhysAddr};
|
||||
|
||||
static mut BOOT_HARTID: u32 = 0;
|
||||
static mut BOOT_FDT_PADDR: PhysAddr = PhysAddr::new(0);
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
|
||||
clear_bss();
|
||||
|
||||
let fdt_paddr = PhysAddr::new(fdt_paddr);
|
||||
|
||||
unsafe {
|
||||
BOOT_HARTID = hartid as u32;
|
||||
BOOT_FDT_PADDR = fdt_paddr;
|
||||
}
|
||||
setup_trap_vector();
|
||||
start_kernel();
|
||||
}
|
||||
|
||||
/// 设置中断、异常处理函数
|
||||
fn setup_trap_vector() {
|
||||
// todo!();
|
||||
// let ptr = handle_exception as *const () as usize;
|
||||
// ecfg::set_vs(0);
|
||||
// eentry::set_eentry(handle_exception as usize);
|
||||
}
|
||||
|
||||
/// Clear the bss section
|
||||
fn clear_bss() {
|
||||
extern "C" {
|
||||
fn _bss();
|
||||
fn _ebss();
|
||||
}
|
||||
unsafe {
|
||||
let bss_start = _bss as *mut u8;
|
||||
let bss_end = _ebss as *mut u8;
|
||||
let bss_size = bss_end as usize - bss_start as usize;
|
||||
|
||||
// Clear in chunks of u128 for efficiency
|
||||
let u128_count = bss_size / core::mem::size_of::<u128>();
|
||||
let u128_slice = core::slice::from_raw_parts_mut(bss_start as *mut u128, u128_count);
|
||||
u128_slice.fill(0);
|
||||
|
||||
// Clear any remaining bytes
|
||||
let remaining_bytes = bss_size % core::mem::size_of::<u128>();
|
||||
if remaining_bytes > 0 {
|
||||
let remaining_start = bss_start.add(u128_count * core::mem::size_of::<u128>());
|
||||
let remaining_slice = core::slice::from_raw_parts_mut(remaining_start, remaining_bytes);
|
||||
remaining_slice.fill(0);
|
||||
}
|
||||
}
|
||||
}
|
24
kernel/src/arch/loongarch64/init/mod.rs
Normal file
24
kernel/src/arch/loongarch64/init/mod.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use system_error::SystemError;
|
||||
pub mod boot;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArchBootParams {}
|
||||
|
||||
impl ArchBootParams {
|
||||
pub const DEFAULT: Self = ArchBootParams {};
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn early_setup_arch() -> Result<(), SystemError> {
|
||||
todo!("la64:early_setup_arch");
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn setup_arch() -> Result<(), SystemError> {
|
||||
todo!("la64:setup_arch");
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn setup_arch_post() -> Result<(), SystemError> {
|
||||
todo!("la64:setup_arch_post");
|
||||
}
|
6
kernel/src/arch/loongarch64/interrupt/ipi.rs
Normal file
6
kernel/src/arch/loongarch64/interrupt/ipi.rs
Normal file
@ -0,0 +1,6 @@
|
||||
use crate::exception::ipi::{IpiKind, IpiTarget};
|
||||
|
||||
#[inline(always)]
|
||||
pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
|
||||
todo!("la64: send_ipi")
|
||||
}
|
123
kernel/src/arch/loongarch64/interrupt/mod.rs
Normal file
123
kernel/src/arch/loongarch64/interrupt/mod.rs
Normal file
@ -0,0 +1,123 @@
|
||||
pub mod ipi;
|
||||
|
||||
use core::any::Any;
|
||||
|
||||
use kprobe::ProbeArgs;
|
||||
use loongArch64::register::CpuMode;
|
||||
|
||||
use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber};
|
||||
|
||||
pub struct LoongArch64InterruptArch;
|
||||
|
||||
impl InterruptArch for LoongArch64InterruptArch {
|
||||
unsafe fn arch_irq_init() -> Result<(), system_error::SystemError> {
|
||||
todo!("arch_irq_init() not implemented for LoongArch64InterruptArch")
|
||||
}
|
||||
|
||||
unsafe fn interrupt_enable() {
|
||||
loongArch64::register::crmd::set_ie(true);
|
||||
}
|
||||
|
||||
unsafe fn interrupt_disable() {
|
||||
loongArch64::register::crmd::set_ie(false);
|
||||
}
|
||||
|
||||
fn is_irq_enabled() -> bool {
|
||||
loongArch64::register::crmd::read().ie()
|
||||
}
|
||||
|
||||
unsafe fn save_and_disable_irq() -> IrqFlagsGuard {
|
||||
let ie = loongArch64::register::crmd::read().ie();
|
||||
loongArch64::register::crmd::set_ie(false);
|
||||
IrqFlagsGuard::new(IrqFlags::new(if ie { 1 } else { 0 }))
|
||||
}
|
||||
|
||||
unsafe fn restore_irq(flags: IrqFlags) {
|
||||
loongArch64::register::crmd::set_ie(flags.flags() == 1);
|
||||
}
|
||||
|
||||
fn probe_total_irq_num() -> u32 {
|
||||
todo!("probe_total_irq_num() not implemented for LoongArch64InterruptArch")
|
||||
}
|
||||
|
||||
fn ack_bad_irq(irq: IrqNumber) {
|
||||
todo!("ack_bad_irq() not implemented for LoongArch64InterruptArch")
|
||||
}
|
||||
}
|
||||
|
||||
/// 中断栈帧结构体
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct TrapFrame {
|
||||
pub r0: usize, // 0*8
|
||||
pub ra: usize, // 1*8
|
||||
pub tp: usize, // 2*8
|
||||
pub usp: usize, // 3*8 (user stack pointer)
|
||||
pub a0: usize, // 4*8
|
||||
pub a1: usize, // 5*8
|
||||
pub a2: usize, // 6*8
|
||||
pub a3: usize, // 7*8
|
||||
pub a4: usize, // 8*8
|
||||
pub a5: usize, // 9*8
|
||||
pub a6: usize, // 10*8
|
||||
pub a7: usize, // 11*8
|
||||
pub t0: usize, // 12*8
|
||||
pub t1: usize, // 13*8
|
||||
pub t2: usize, // 14*8
|
||||
pub t3: usize, // 15*8
|
||||
pub t4: usize, // 16*8
|
||||
pub t5: usize, // 17*8
|
||||
pub t6: usize, // 18*8
|
||||
pub t7: usize, // 19*8
|
||||
pub t8: usize, // 20*8
|
||||
pub r21: usize, // 21*8
|
||||
pub fp: usize, // 22*8
|
||||
pub s0: usize, // 23*8
|
||||
pub s1: usize, // 24*8
|
||||
pub s2: usize, // 25*8
|
||||
pub s3: usize, // 26*8
|
||||
pub s4: usize, // 27*8
|
||||
pub s5: usize, // 28*8
|
||||
pub s6: usize, // 29*8
|
||||
pub s7: usize, // 30*8
|
||||
pub s8: usize, // 31*8
|
||||
/// original syscall arg0
|
||||
pub orig_a0: usize,
|
||||
|
||||
pub csr_era: usize,
|
||||
pub csr_badvaddr: usize,
|
||||
pub csr_crmd: usize,
|
||||
pub csr_prmd: usize,
|
||||
pub csr_euen: usize,
|
||||
pub csr_ecfg: usize,
|
||||
pub csr_estat: usize,
|
||||
}
|
||||
|
||||
impl TrapFrame {
|
||||
/// 中断栈帧结构体的大小
|
||||
pub const SIZE: usize = core::mem::size_of::<TrapFrame>();
|
||||
|
||||
/// 判断当前中断是否来自用户模式
|
||||
pub fn is_from_user(&self) -> bool {
|
||||
loongArch64::register::crmd::Crmd::from(self.csr_crmd).plv() == CpuMode::Ring3
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub const fn new() -> Self {
|
||||
let x = core::mem::MaybeUninit::<Self>::zeroed();
|
||||
unsafe { x.assume_init() }
|
||||
}
|
||||
}
|
||||
|
||||
impl ProbeArgs for TrapFrame {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
fn break_address(&self) -> usize {
|
||||
todo!("TrapFrame::break_address()")
|
||||
}
|
||||
|
||||
fn debug_address(&self) -> usize {
|
||||
todo!("TrapFrame::debug_address()")
|
||||
}
|
||||
}
|
1
kernel/src/arch/loongarch64/ipc/mod.rs
Normal file
1
kernel/src/arch/loongarch64/ipc/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod signal;
|
64
kernel/src/arch/loongarch64/ipc/signal.rs
Normal file
64
kernel/src/arch/loongarch64/ipc/signal.rs
Normal file
@ -0,0 +1,64 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
pub use crate::ipc::generic_signal::AtomicGenericSignal as AtomicSignal;
|
||||
pub use crate::ipc::generic_signal::GenericSigChildCode as SigChildCode;
|
||||
pub use crate::ipc::generic_signal::GenericSigSet as SigSet;
|
||||
pub use crate::ipc::generic_signal::GenericSignal as Signal;
|
||||
pub use crate::ipc::generic_signal::GENERIC_MAX_SIG_NUM as MAX_SIG_NUM;
|
||||
pub use crate::ipc::generic_signal::GENERIC_STACK_ALIGN as STACK_ALIGN;
|
||||
|
||||
pub use crate::ipc::generic_signal::GenericSigFlags as SigFlags;
|
||||
|
||||
use crate::ipc::signal_types::SignalArch;
|
||||
|
||||
pub struct LoongArch64SignalArch;
|
||||
|
||||
impl SignalArch for LoongArch64SignalArch {
|
||||
// TODO: 为LoongArch64实现信号处理
|
||||
// 注意,la64现在在中断/系统调用返回用户态时,没有进入 irqentry_exit() 函数,
|
||||
// 到时候实现信号处理时,需要修改中断/系统调用返回用户态的代码,进入 irqentry_exit() 函数
|
||||
unsafe fn do_signal_or_restart(_frame: &mut TrapFrame) {
|
||||
todo!("la64:do_signal_or_restart")
|
||||
}
|
||||
|
||||
fn sys_rt_sigreturn(_trap_frame: &mut TrapFrame) -> u64 {
|
||||
todo!("la64:sys_rt_sigreturn")
|
||||
}
|
||||
}
|
||||
|
||||
/// siginfo中的si_code的可选值
|
||||
/// 请注意,当这个值小于0时,表示siginfo来自用户态,否则来自内核态
|
||||
#[derive(Copy, Debug, Clone)]
|
||||
#[repr(i32)]
|
||||
pub enum SigCode {
|
||||
/// sent by kill, sigsend, raise
|
||||
User = 0,
|
||||
/// sent by kernel from somewhere
|
||||
Kernel = 0x80,
|
||||
/// 通过sigqueue发送
|
||||
Queue = -1,
|
||||
/// 定时器过期时发送
|
||||
Timer = -2,
|
||||
/// 当实时消息队列的状态发生改变时发送
|
||||
Mesgq = -3,
|
||||
/// 当异步IO完成时发送
|
||||
AsyncIO = -4,
|
||||
/// sent by queued SIGIO
|
||||
SigIO = -5,
|
||||
}
|
||||
|
||||
impl SigCode {
|
||||
/// 为SigCode这个枚举类型实现从i32转换到枚举类型的转换函数
|
||||
#[allow(dead_code)]
|
||||
pub fn from_i32(x: i32) -> SigCode {
|
||||
match x {
|
||||
0 => Self::User,
|
||||
0x80 => Self::Kernel,
|
||||
-1 => Self::Queue,
|
||||
-2 => Self::Timer,
|
||||
-3 => Self::Mesgq,
|
||||
-4 => Self::AsyncIO,
|
||||
-5 => Self::SigIO,
|
||||
_ => panic!("signal code not valid"),
|
||||
}
|
||||
}
|
||||
}
|
19
kernel/src/arch/loongarch64/kprobe.rs
Normal file
19
kernel/src/arch/loongarch64/kprobe.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
|
||||
pub fn setup_single_step(frame: &mut TrapFrame, step_addr: usize) {
|
||||
todo!("la64: setup_single_step")
|
||||
}
|
||||
|
||||
pub fn clear_single_step(frame: &mut TrapFrame, return_addr: usize) {
|
||||
todo!("la64: clear_single_step")
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct KProbeContext {}
|
||||
|
||||
impl From<&TrapFrame> for KProbeContext {
|
||||
fn from(trap_frame: &TrapFrame) -> Self {
|
||||
todo!("from trap frame to kprobe context");
|
||||
}
|
||||
}
|
104
kernel/src/arch/loongarch64/link.ld
Normal file
104
kernel/src/arch/loongarch64/link.ld
Normal file
@ -0,0 +1,104 @@
|
||||
OUTPUT_FORMAT(
|
||||
"elf64-loongarch",
|
||||
"elf64-loongarch",
|
||||
"elf64-loongarch"
|
||||
)
|
||||
|
||||
OUTPUT_ARCH(loongarch)
|
||||
ENTRY(_start)
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
KERNEL_VMA = 0x9000000000200000;
|
||||
. = KERNEL_VMA;
|
||||
. = ALIGN(4096);
|
||||
boot_text_start_pa = .;
|
||||
.boot.text :
|
||||
{
|
||||
KEEP(*(.bootstrap))
|
||||
*(.bootstrap)
|
||||
*(.bootstrap.*)
|
||||
. = ALIGN(4096);
|
||||
*(.initial_pgtable_section)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
|
||||
. = ALIGN(4096);
|
||||
text_start_pa = .;
|
||||
__executable_start = .;
|
||||
.text (text_start_pa):
|
||||
{
|
||||
_text = .;
|
||||
|
||||
/* any files' .text */
|
||||
*(.text)
|
||||
|
||||
/* any files' .text.*, for example: rust .text._ZN* */
|
||||
*(.text.*)
|
||||
|
||||
_etext = .;
|
||||
__etext = .;
|
||||
}
|
||||
. = ALIGN(32768);
|
||||
data_start_pa = .;
|
||||
.data (data_start_pa):
|
||||
{
|
||||
_data = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
_edata = .;
|
||||
}
|
||||
|
||||
. = ALIGN(32768);
|
||||
|
||||
rodata_start_pa = .;
|
||||
.rodata (rodata_start_pa):
|
||||
{
|
||||
_rodata = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gcc_except_table .gcc_except_table.*)
|
||||
_erodata = .;
|
||||
}
|
||||
|
||||
. = ALIGN(32768);
|
||||
|
||||
init_proc_union_start_pa = .;
|
||||
.data.init_proc_union (init_proc_union_start_pa):
|
||||
{ *(.data.init_proc_union) }
|
||||
|
||||
. = ALIGN(32768);
|
||||
bss_start_pa = .;
|
||||
.bss (bss_start_pa):
|
||||
{
|
||||
_bss = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
_ebss = .;
|
||||
}
|
||||
|
||||
eh_frame = .;
|
||||
.eh_frame (eh_frame):
|
||||
{
|
||||
__eh_frame_hdr_start = .;
|
||||
*(.eh_frame_hdr)
|
||||
__eh_frame_hdr_end = .;
|
||||
__eh_frame_start = .;
|
||||
*(.eh_frame)
|
||||
*(.rela.eh_frame)
|
||||
__eh_frame_end = .;
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/DISCARD/ : {
|
||||
/* *(.eh_frame) */
|
||||
|
||||
}
|
||||
}
|
21
kernel/src/arch/loongarch64/loongarch64-unknown-none.json
Normal file
21
kernel/src/arch/loongarch64/loongarch64-unknown-none.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"arch": "loongarch64",
|
||||
"code-model": "medium",
|
||||
"crt-objects-fallback": "false",
|
||||
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
"features": "+f,+d",
|
||||
"linker": "rust-lld",
|
||||
"linker-flavor": "gnu-lld",
|
||||
"llvm-abiname": "lp64d",
|
||||
"llvm-target": "loongarch64-unknown-none",
|
||||
"max-atomic-width": 64,
|
||||
"metadata": {
|
||||
"description": "Freestanding/bare-metal LoongArch64",
|
||||
"host_tools": false,
|
||||
"std": false,
|
||||
"tier": 2
|
||||
},
|
||||
"panic-strategy": "abort",
|
||||
"relocation-model": "static",
|
||||
"target-pointer-width": "64"
|
||||
}
|
7
kernel/src/arch/loongarch64/mm/bump.rs
Normal file
7
kernel/src/arch/loongarch64/mm/bump.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::mm::{allocator::bump::BumpAllocator, MemoryManagementArch, PhysMemoryArea};
|
||||
|
||||
impl<MMA: MemoryManagementArch> BumpAllocator<MMA> {
|
||||
pub unsafe fn arch_remain_areas(_ret_areas: &mut [PhysMemoryArea], res_count: usize) -> usize {
|
||||
todo!("la64: arch_remain_areas")
|
||||
}
|
||||
}
|
207
kernel/src/arch/loongarch64/mm/mod.rs
Normal file
207
kernel/src/arch/loongarch64/mm/mod.rs
Normal file
@ -0,0 +1,207 @@
|
||||
pub mod bump;
|
||||
|
||||
use crate::mm::{
|
||||
allocator::page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage},
|
||||
page::EntryFlags,
|
||||
MemoryManagementArch, PhysAddr, VirtAddr, VmFlags,
|
||||
};
|
||||
|
||||
use crate::arch::MMArch;
|
||||
|
||||
pub type PageMapper = crate::mm::page::PageMapper<LoongArch64MMArch, LockedFrameAllocator>;
|
||||
|
||||
/// LoongArch64的内存管理架构结构体
|
||||
#[derive(Debug, Clone, Copy, Hash)]
|
||||
pub struct LoongArch64MMArch;
|
||||
|
||||
impl MemoryManagementArch for LoongArch64MMArch {
|
||||
const PAGE_FAULT_ENABLED: bool = false;
|
||||
|
||||
const PAGE_SHIFT: usize = 0;
|
||||
|
||||
const PAGE_ENTRY_SHIFT: usize = 0;
|
||||
|
||||
const PAGE_LEVELS: usize = 0;
|
||||
|
||||
const ENTRY_ADDRESS_SHIFT: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_DEFAULT_PAGE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_DEFAULT_TABLE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_PRESENT: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_READONLY: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_WRITEABLE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_READWRITE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_USER: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_WRITE_THROUGH: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_CACHE_DISABLE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_NO_EXEC: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_EXEC: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_DIRTY: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_ACCESSED: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_HUGE_PAGE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_GLOBAL: usize = 0;
|
||||
|
||||
const PHYS_OFFSET: usize = 0x9000_0000_0000_0000;
|
||||
|
||||
const KERNEL_LINK_OFFSET: usize = 0;
|
||||
|
||||
const USER_END_VADDR: crate::mm::VirtAddr = VirtAddr::new(0);
|
||||
|
||||
const USER_BRK_START: crate::mm::VirtAddr = VirtAddr::new(0);
|
||||
|
||||
const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0);
|
||||
|
||||
const FIXMAP_START_VADDR: crate::mm::VirtAddr = VirtAddr::new(0);
|
||||
|
||||
const FIXMAP_SIZE: usize = 0;
|
||||
|
||||
const MMIO_BASE: crate::mm::VirtAddr = VirtAddr::new(0);
|
||||
|
||||
const MMIO_SIZE: usize = 0;
|
||||
|
||||
const PAGE_NONE: usize = 0;
|
||||
|
||||
const PAGE_SHARED: usize = 0;
|
||||
|
||||
const PAGE_SHARED_EXEC: usize = 0;
|
||||
|
||||
const PAGE_COPY_NOEXEC: usize = 0;
|
||||
|
||||
const PAGE_COPY_EXEC: usize = 0;
|
||||
|
||||
const PAGE_COPY: usize = 0;
|
||||
|
||||
const PAGE_READONLY: usize = 0;
|
||||
|
||||
const PAGE_READONLY_EXEC: usize = 0;
|
||||
|
||||
const PAGE_READ: usize = 0;
|
||||
|
||||
const PAGE_READ_EXEC: usize = 0;
|
||||
|
||||
const PAGE_WRITE: usize = 0;
|
||||
|
||||
const PAGE_WRITE_EXEC: usize = 0;
|
||||
|
||||
const PAGE_EXEC: usize = 0;
|
||||
|
||||
const PROTECTION_MAP: [crate::mm::page::EntryFlags<Self>; 16] = protection_map();
|
||||
|
||||
unsafe fn init() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn invalidate_page(address: crate::mm::VirtAddr) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn invalidate_all() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn table(table_kind: crate::mm::PageTableKind) -> crate::mm::PhysAddr {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn set_table(table_kind: crate::mm::PageTableKind, table: crate::mm::PhysAddr) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn virt_is_valid(virt: crate::mm::VirtAddr) -> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn initial_page_table() -> crate::mm::PhysAddr {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn setup_new_usermapper() -> Result<crate::mm::ucontext::UserMapper, system_error::SystemError>
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn make_entry(paddr: crate::mm::PhysAddr, page_flags: usize) -> usize {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取内核地址默认的页面标志
|
||||
pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(_virt: VirtAddr) -> EntryFlags<A> {
|
||||
EntryFlags::from_data(LoongArch64MMArch::ENTRY_FLAG_DEFAULT_PAGE)
|
||||
.set_user(false)
|
||||
.set_execute(true)
|
||||
}
|
||||
|
||||
/// 全局的页帧分配器
|
||||
#[derive(Debug, Clone, Copy, Hash)]
|
||||
pub struct LockedFrameAllocator;
|
||||
|
||||
impl FrameAllocator for LockedFrameAllocator {
|
||||
unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
|
||||
todo!("LockedFrameAllocator::allocate")
|
||||
}
|
||||
|
||||
unsafe fn free(&mut self, address: PhysAddr, count: PageFrameCount) {
|
||||
todo!("LockedFrameAllocator::free")
|
||||
}
|
||||
|
||||
unsafe fn usage(&self) -> PageFrameUsage {
|
||||
todo!("LockedFrameAllocator::usage")
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取保护标志的映射表
|
||||
///
|
||||
///
|
||||
/// ## 返回值
|
||||
/// - `[usize; 16]`: 长度为16的映射表
|
||||
const fn protection_map() -> [EntryFlags<MMArch>; 16] {
|
||||
let mut map = [unsafe { EntryFlags::from_data(0) }; 16];
|
||||
unsafe {
|
||||
map[VmFlags::VM_NONE.bits()] = EntryFlags::from_data(MMArch::PAGE_NONE);
|
||||
map[VmFlags::VM_READ.bits()] = EntryFlags::from_data(MMArch::PAGE_READONLY);
|
||||
map[VmFlags::VM_WRITE.bits()] = EntryFlags::from_data(MMArch::PAGE_COPY);
|
||||
map[VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_COPY);
|
||||
map[VmFlags::VM_EXEC.bits()] = EntryFlags::from_data(MMArch::PAGE_READONLY_EXEC);
|
||||
map[VmFlags::VM_EXEC.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_READONLY_EXEC);
|
||||
map[VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_COPY_EXEC);
|
||||
map[VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_COPY_EXEC);
|
||||
map[VmFlags::VM_SHARED.bits()] = EntryFlags::from_data(MMArch::PAGE_NONE);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_READONLY);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_WRITE.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_SHARED);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_SHARED);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_READONLY_EXEC);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_READONLY_EXEC);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_SHARED_EXEC);
|
||||
map[VmFlags::VM_SHARED.bits()
|
||||
| VmFlags::VM_EXEC.bits()
|
||||
| VmFlags::VM_WRITE.bits()
|
||||
| VmFlags::VM_READ.bits()] = EntryFlags::from_data(MMArch::PAGE_SHARED_EXEC);
|
||||
}
|
||||
|
||||
map
|
||||
}
|
30
kernel/src/arch/loongarch64/mod.rs
Normal file
30
kernel/src/arch/loongarch64/mod.rs
Normal file
@ -0,0 +1,30 @@
|
||||
pub mod asm;
|
||||
pub mod cpu;
|
||||
pub mod elf;
|
||||
pub mod init;
|
||||
pub mod interrupt;
|
||||
pub mod ipc;
|
||||
pub mod kprobe;
|
||||
pub mod mm;
|
||||
pub mod msi;
|
||||
pub mod pci;
|
||||
pub mod pio;
|
||||
pub mod process;
|
||||
pub mod rand;
|
||||
pub mod sched;
|
||||
pub mod smp;
|
||||
pub mod syscall;
|
||||
pub mod time;
|
||||
|
||||
pub use self::elf::LoongArch64ElfArch as CurrentElfArch;
|
||||
pub use self::interrupt::LoongArch64InterruptArch as CurrentIrqArch;
|
||||
pub use self::ipc::signal::LoongArch64SignalArch as CurrentSignalArch;
|
||||
pub use self::mm::LoongArch64MMArch as MMArch;
|
||||
pub use self::pci::LoongArch64PciArch as PciArch;
|
||||
pub use self::pio::LoongArch64PortIOArch as CurrentPortIOArch;
|
||||
pub use self::sched::LoongArch64SchedArch as CurrentSchedArch;
|
||||
pub use self::smp::LoongArch64SMPArch as CurrentSMPArch;
|
||||
pub use self::time::LoongArch64TimeArch as CurrentTimeArch;
|
||||
|
||||
pub fn panic_pre_work() {}
|
||||
pub fn panic_post_work() {}
|
24
kernel/src/arch/loongarch64/msi.rs
Normal file
24
kernel/src/arch/loongarch64/msi.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use crate::driver::pci::pci_irq::TriggerMode;
|
||||
|
||||
/// 获得MSI Message Address
|
||||
///
|
||||
/// # 参数
|
||||
/// - `processor`: 目标CPU ID号
|
||||
///
|
||||
/// # 返回值
|
||||
/// MSI Message Address
|
||||
pub fn arch_msi_message_address(_processor: u16) -> u32 {
|
||||
unimplemented!("loongarch64::arch_msi_message_address()")
|
||||
}
|
||||
/// 获得MSI Message Data
|
||||
///
|
||||
/// # 参数
|
||||
/// - `vector`: 分配的中断向量号
|
||||
/// - `processor`: 目标CPU ID号
|
||||
/// - `trigger`: 申请中断的触发模式,MSI默认为边沿触发
|
||||
///
|
||||
/// # 返回值
|
||||
/// MSI Message Address
|
||||
pub fn arch_msi_message_data(_vector: u16, _processor: u16, _trigger: TriggerMode) -> u32 {
|
||||
unimplemented!("loongarch64::arch_msi_message_data()")
|
||||
}
|
20
kernel/src/arch/loongarch64/pci/mod.rs
Normal file
20
kernel/src/arch/loongarch64/pci/mod.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::{
|
||||
arch::TraitPciArch,
|
||||
driver::pci::pci::{BusDeviceFunction, PciAddr},
|
||||
mm::PhysAddr,
|
||||
};
|
||||
|
||||
pub struct LoongArch64PciArch;
|
||||
impl TraitPciArch for LoongArch64PciArch {
|
||||
fn read_config(_bus_device_function: &BusDeviceFunction, _offset: u8) -> u32 {
|
||||
unimplemented!("LoongArch64PciArch::read_config")
|
||||
}
|
||||
|
||||
fn write_config(_bus_device_function: &BusDeviceFunction, _offset: u8, _data: u32) {
|
||||
unimplemented!("LoongArch64PciArch pci_root_0().write_config")
|
||||
}
|
||||
|
||||
fn address_pci_to_physical(pci_address: PciAddr) -> crate::mm::PhysAddr {
|
||||
return PhysAddr::new(pci_address.data());
|
||||
}
|
||||
}
|
35
kernel/src/arch/loongarch64/pio.rs
Normal file
35
kernel/src/arch/loongarch64/pio.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use crate::arch::io::PortIOArch;
|
||||
|
||||
pub struct LoongArch64PortIOArch;
|
||||
|
||||
impl PortIOArch for LoongArch64PortIOArch {
|
||||
#[inline(always)]
|
||||
unsafe fn in8(_port: u16) -> u8 {
|
||||
unimplemented!("LoongArch64PortIOArch::in8")
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn in16(_port: u16) -> u16 {
|
||||
unimplemented!("LoongArch64PortIOArch::in16")
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn in32(_port: u16) -> u32 {
|
||||
unimplemented!("LoongArch64PortIOArch::in32")
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn out8(_port: u16, _data: u8) {
|
||||
unimplemented!("LoongArch64PortIOArch::out8")
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn out16(_port: u16, _data: u16) {
|
||||
unimplemented!("LoongArch64PortIOArch::out16")
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn out32(_port: u16, _data: u32) {
|
||||
unimplemented!("LoongArch64PortIOArch::out32")
|
||||
}
|
||||
}
|
31
kernel/src/arch/loongarch64/process/idle.rs
Normal file
31
kernel/src/arch/loongarch64/process/idle.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use core::hint::spin_loop;
|
||||
|
||||
use log::error;
|
||||
|
||||
use crate::{
|
||||
arch::CurrentIrqArch,
|
||||
exception::InterruptArch,
|
||||
process::{ProcessFlags, ProcessManager},
|
||||
sched::{SchedMode, __schedule},
|
||||
};
|
||||
|
||||
impl ProcessManager {
|
||||
/// 每个核的idle进程
|
||||
pub fn arch_idle_func() -> ! {
|
||||
loop {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
if pcb.flags().contains(ProcessFlags::NEED_SCHEDULE) {
|
||||
__schedule(SchedMode::SM_NONE);
|
||||
}
|
||||
if CurrentIrqArch::is_irq_enabled() {
|
||||
todo!("la64: arch_idle_func");
|
||||
// unsafe {
|
||||
// x86::halt();
|
||||
// }
|
||||
} else {
|
||||
error!("Idle process should not be scheduled with IRQs disabled.");
|
||||
spin_loop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
kernel/src/arch/loongarch64/process/kthread.rs
Normal file
27
kernel/src/arch/loongarch64/process/kthread.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use crate::process::{
|
||||
fork::CloneFlags,
|
||||
kthread::{KernelThreadCreateInfo, KernelThreadMechanism},
|
||||
Pid,
|
||||
};
|
||||
|
||||
impl KernelThreadMechanism {
|
||||
/// 伪造trapframe,创建内核线程
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 返回创建的内核线程的pid
|
||||
pub fn __inner_create(
|
||||
info: &Arc<KernelThreadCreateInfo>,
|
||||
clone_flags: CloneFlags,
|
||||
) -> Result<Pid, SystemError> {
|
||||
// WARNING: If create failed, we must drop the info manually or it will cause memory leak. (refcount will not decrease when create failed)
|
||||
let create_info: *const KernelThreadCreateInfo =
|
||||
KernelThreadCreateInfo::generate_unsafe_arc_ptr(info.clone());
|
||||
|
||||
todo!("la64:__inner_create()")
|
||||
}
|
||||
}
|
90
kernel/src/arch/loongarch64/process/mod.rs
Normal file
90
kernel/src/arch/loongarch64/process/mod.rs
Normal file
@ -0,0 +1,90 @@
|
||||
use alloc::sync::Arc;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::CurrentIrqArch,
|
||||
exception::InterruptArch,
|
||||
mm::VirtAddr,
|
||||
process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager},
|
||||
};
|
||||
|
||||
use super::interrupt::TrapFrame;
|
||||
|
||||
pub mod idle;
|
||||
pub mod kthread;
|
||||
pub mod syscall;
|
||||
|
||||
#[repr(align(32768))]
|
||||
pub union InitProcUnion {
|
||||
/// 用于存放idle进程的内核栈
|
||||
idle_stack: [u8; 32768],
|
||||
}
|
||||
|
||||
#[link_section = ".data.init_proc_union"]
|
||||
#[no_mangle]
|
||||
pub(super) static BSP_IDLE_STACK_SPACE: InitProcUnion = InitProcUnion {
|
||||
idle_stack: [0; 32768],
|
||||
};
|
||||
|
||||
pub unsafe fn arch_switch_to_user(trap_frame: TrapFrame) -> ! {
|
||||
// 以下代码不能发生中断
|
||||
CurrentIrqArch::interrupt_disable();
|
||||
|
||||
todo!("la64: arch_switch_to_user")
|
||||
}
|
||||
|
||||
/// PCB中与架构相关的信息
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[allow(dead_code)]
|
||||
#[repr(C)]
|
||||
pub struct ArchPCBInfo {}
|
||||
|
||||
impl ArchPCBInfo {
|
||||
/// 创建一个新的ArchPCBInfo
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `kstack`:内核栈的引用
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 返回一个新的ArchPCBInfo
|
||||
pub fn new(kstack: &KernelStack) -> Self {
|
||||
todo!("la64: ArchPCBInfo::new")
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessControlBlock {
|
||||
/// 获取当前进程的pcb
|
||||
pub fn arch_current_pcb() -> Arc<Self> {
|
||||
todo!("la64: arch_current_pcb")
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessManager {
|
||||
pub fn arch_init() {
|
||||
// do nothing
|
||||
}
|
||||
/// fork的过程中复制线程
|
||||
///
|
||||
/// 由于这个过程与具体的架构相关,所以放在这里
|
||||
pub fn copy_thread(
|
||||
current_pcb: &Arc<ProcessControlBlock>,
|
||||
new_pcb: &Arc<ProcessControlBlock>,
|
||||
clone_args: &KernelCloneArgs,
|
||||
current_trapframe: &TrapFrame,
|
||||
) -> Result<(), SystemError> {
|
||||
todo!("la64: copy_thread")
|
||||
}
|
||||
|
||||
/// 切换进程
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `prev`:上一个进程的pcb
|
||||
/// - `next`:下一个进程的pcb
|
||||
pub unsafe fn switch_process(prev: Arc<ProcessControlBlock>, next: Arc<ProcessControlBlock>) {
|
||||
assert!(!CurrentIrqArch::is_irq_enabled());
|
||||
todo!("la64: switch_process");
|
||||
}
|
||||
}
|
28
kernel/src/arch/loongarch64/process/syscall.rs
Normal file
28
kernel/src/arch/loongarch64/process/syscall.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::interrupt::TrapFrame,
|
||||
mm::VirtAddr,
|
||||
process::{
|
||||
exec::{BinaryLoaderResult, ExecParam},
|
||||
ProcessManager,
|
||||
},
|
||||
syscall::Syscall,
|
||||
};
|
||||
|
||||
impl Syscall {
|
||||
pub fn arch_do_execve(
|
||||
regs: &mut TrapFrame,
|
||||
param: &ExecParam,
|
||||
load_result: &BinaryLoaderResult,
|
||||
user_sp: VirtAddr,
|
||||
argv_ptr: VirtAddr,
|
||||
) -> Result<(), SystemError> {
|
||||
todo!("la64:arch_do_execve not unimplemented");
|
||||
}
|
||||
|
||||
/// ## 用于控制和查询与体系结构相关的进程特定选项
|
||||
pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> {
|
||||
todo!("la64:arch_prctl")
|
||||
}
|
||||
}
|
5
kernel/src/arch/loongarch64/rand.rs
Normal file
5
kernel/src/arch/loongarch64/rand.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use crate::libs::rand::soft_rand;
|
||||
|
||||
pub fn rand() -> usize {
|
||||
return soft_rand();
|
||||
}
|
17
kernel/src/arch/loongarch64/sched.rs
Normal file
17
kernel/src/arch/loongarch64/sched.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use crate::sched::SchedArch;
|
||||
|
||||
pub struct LoongArch64SchedArch;
|
||||
|
||||
impl SchedArch for LoongArch64SchedArch {
|
||||
fn enable_sched_local() {
|
||||
todo!("LoongArch64::enable_sched_local")
|
||||
}
|
||||
|
||||
fn disable_sched_local() {
|
||||
todo!("LoongArch64::disable_sched_local")
|
||||
}
|
||||
|
||||
fn initial_setup_sched_local() {
|
||||
todo!("LoongArch64::initial_setup_sched_local")
|
||||
}
|
||||
}
|
29
kernel/src/arch/loongarch64/smp/mod.rs
Normal file
29
kernel/src/arch/loongarch64/smp/mod.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use log::warn;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::smp::{
|
||||
cpu::{CpuHpCpuState, ProcessorId, SmpCpuManager},
|
||||
SMPArch,
|
||||
};
|
||||
|
||||
pub struct LoongArch64SMPArch;
|
||||
|
||||
impl SMPArch for LoongArch64SMPArch {
|
||||
#[inline(never)]
|
||||
fn prepare_cpus() -> Result<(), SystemError> {
|
||||
warn!("LoongArch64SMPArch::prepare_cpus() is not implemented");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_cpu(_cpu_id: ProcessorId, _hp_state: &CpuHpCpuState) -> Result<(), SystemError> {
|
||||
warn!("LoongArch64SMPArch::start_cpu() is not implemented");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl SmpCpuManager {
|
||||
pub fn arch_init(_boot_cpu: ProcessorId) {
|
||||
// todo: 读取所有可用的CPU
|
||||
todo!("la64:SmpCpuManager::arch_init()")
|
||||
}
|
||||
}
|
8
kernel/src/arch/loongarch64/syscall/mod.rs
Normal file
8
kernel/src/arch/loongarch64/syscall/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
pub mod nr;
|
||||
|
||||
/// 系统调用初始化
|
||||
pub fn arch_syscall_init() -> Result<(), SystemError> {
|
||||
todo!("la64:arch_syscall_init");
|
||||
}
|
307
kernel/src/arch/loongarch64/syscall/nr.rs
Normal file
307
kernel/src/arch/loongarch64/syscall/nr.rs
Normal file
@ -0,0 +1,307 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub const SYS_IO_SETUP: usize = 0;
|
||||
pub const SYS_IO_DESTROY: usize = 1;
|
||||
pub const SYS_IO_SUBMIT: usize = 2;
|
||||
pub const SYS_IO_CANCEL: usize = 3;
|
||||
pub const SYS_IO_GETEVENTS: usize = 4;
|
||||
pub const SYS_SETXATTR: usize = 5;
|
||||
pub const SYS_LSETXATTR: usize = 6;
|
||||
pub const SYS_FSETXATTR: usize = 7;
|
||||
pub const SYS_GETXATTR: usize = 8;
|
||||
pub const SYS_LGETXATTR: usize = 9;
|
||||
pub const SYS_FGETXATTR: usize = 10;
|
||||
pub const SYS_LISTXATTR: usize = 11;
|
||||
pub const SYS_LLISTXATTR: usize = 12;
|
||||
pub const SYS_FLISTXATTR: usize = 13;
|
||||
pub const SYS_REMOVEXATTR: usize = 14;
|
||||
pub const SYS_LREMOVEXATTR: usize = 15;
|
||||
pub const SYS_FREMOVEXATTR: usize = 16;
|
||||
pub const SYS_GETCWD: usize = 17;
|
||||
pub const SYS_LOOKUP_DCOOKIE: usize = 18;
|
||||
pub const SYS_EVENTFD2: usize = 19;
|
||||
pub const SYS_EPOLL_CREATE1: usize = 20;
|
||||
pub const SYS_EPOLL_CTL: usize = 21;
|
||||
pub const SYS_EPOLL_PWAIT: usize = 22;
|
||||
pub const SYS_DUP: usize = 23;
|
||||
pub const SYS_DUP3: usize = 24;
|
||||
pub const SYS_FCNTL: usize = 25;
|
||||
pub const SYS_INOTIFY_INIT1: usize = 26;
|
||||
pub const SYS_INOTIFY_ADD_WATCH: usize = 27;
|
||||
pub const SYS_INOTIFY_RM_WATCH: usize = 28;
|
||||
pub const SYS_IOCTL: usize = 29;
|
||||
pub const SYS_IOPRIO_SET: usize = 30;
|
||||
pub const SYS_IOPRIO_GET: usize = 31;
|
||||
pub const SYS_FLOCK: usize = 32;
|
||||
pub const SYS_MKNODAT: usize = 33;
|
||||
pub const SYS_MKDIRAT: usize = 34;
|
||||
pub const SYS_UNLINKAT: usize = 35;
|
||||
pub const SYS_SYMLINKAT: usize = 36;
|
||||
pub const SYS_LINKAT: usize = 37;
|
||||
pub const SYS_UMOUNT2: usize = 39;
|
||||
pub const SYS_MOUNT: usize = 40;
|
||||
pub const SYS_PIVOT_ROOT: usize = 41;
|
||||
pub const SYS_NFSSERVCTL: usize = 42;
|
||||
pub const SYS_STATFS: usize = 43;
|
||||
pub const SYS_FSTATFS: usize = 44;
|
||||
pub const SYS_TRUNCATE: usize = 45;
|
||||
pub const SYS_FTRUNCATE: usize = 46;
|
||||
pub const SYS_FALLOCATE: usize = 47;
|
||||
pub const SYS_FACCESSAT: usize = 48;
|
||||
pub const SYS_CHDIR: usize = 49;
|
||||
pub const SYS_FCHDIR: usize = 50;
|
||||
pub const SYS_CHROOT: usize = 51;
|
||||
pub const SYS_FCHMOD: usize = 52;
|
||||
pub const SYS_FCHMODAT: usize = 53;
|
||||
pub const SYS_FCHOWNAT: usize = 54;
|
||||
pub const SYS_FCHOWN: usize = 55;
|
||||
pub const SYS_OPENAT: usize = 56;
|
||||
pub const SYS_CLOSE: usize = 57;
|
||||
pub const SYS_VHANGUP: usize = 58;
|
||||
pub const SYS_PIPE2: usize = 59;
|
||||
pub const SYS_QUOTACTL: usize = 60;
|
||||
pub const SYS_GETDENTS64: usize = 61;
|
||||
pub const SYS_LSEEK: usize = 62;
|
||||
pub const SYS_READ: usize = 63;
|
||||
pub const SYS_WRITE: usize = 64;
|
||||
pub const SYS_READV: usize = 65;
|
||||
pub const SYS_WRITEV: usize = 66;
|
||||
pub const SYS_PREAD64: usize = 67;
|
||||
pub const SYS_PWRITE64: usize = 68;
|
||||
pub const SYS_PREADV: usize = 69;
|
||||
pub const SYS_PWRITEV: usize = 70;
|
||||
pub const SYS_SENDFILE: usize = 71;
|
||||
pub const SYS_PSELECT6: usize = 72;
|
||||
pub const SYS_PPOLL: usize = 73;
|
||||
pub const SYS_SIGNALFD4: usize = 74;
|
||||
pub const SYS_VMSPLICE: usize = 75;
|
||||
pub const SYS_SPLICE: usize = 76;
|
||||
pub const SYS_TEE: usize = 77;
|
||||
pub const SYS_READLINKAT: usize = 78;
|
||||
pub const SYS_SYNC: usize = 81;
|
||||
pub const SYS_FSYNC: usize = 82;
|
||||
pub const SYS_FDATASYNC: usize = 83;
|
||||
pub const SYS_SYNC_FILE_RANGE: usize = 84;
|
||||
pub const SYS_TIMERFD_CREATE: usize = 85;
|
||||
pub const SYS_TIMERFD_SETTIME: usize = 86;
|
||||
pub const SYS_TIMERFD_GETTIME: usize = 87;
|
||||
pub const SYS_UTIMENSAT: usize = 88;
|
||||
pub const SYS_ACCT: usize = 89;
|
||||
pub const SYS_CAPGET: usize = 90;
|
||||
pub const SYS_CAPSET: usize = 91;
|
||||
pub const SYS_PERSONALITY: usize = 92;
|
||||
pub const SYS_EXIT: usize = 93;
|
||||
pub const SYS_EXIT_GROUP: usize = 94;
|
||||
pub const SYS_WAITID: usize = 95;
|
||||
pub const SYS_SET_TID_ADDRESS: usize = 96;
|
||||
pub const SYS_UNSHARE: usize = 97;
|
||||
pub const SYS_FUTEX: usize = 98;
|
||||
pub const SYS_SET_ROBUST_LIST: usize = 99;
|
||||
pub const SYS_GET_ROBUST_LIST: usize = 100;
|
||||
pub const SYS_NANOSLEEP: usize = 101;
|
||||
pub const SYS_GETITIMER: usize = 102;
|
||||
pub const SYS_SETITIMER: usize = 103;
|
||||
pub const SYS_KEXEC_LOAD: usize = 104;
|
||||
pub const SYS_INIT_MODULE: usize = 105;
|
||||
pub const SYS_DELETE_MODULE: usize = 106;
|
||||
pub const SYS_TIMER_CREATE: usize = 107;
|
||||
pub const SYS_TIMER_GETTIME: usize = 108;
|
||||
pub const SYS_TIMER_GETOVERRUN: usize = 109;
|
||||
pub const SYS_TIMER_SETTIME: usize = 110;
|
||||
pub const SYS_TIMER_DELETE: usize = 111;
|
||||
pub const SYS_CLOCK_SETTIME: usize = 112;
|
||||
pub const SYS_CLOCK_GETTIME: usize = 113;
|
||||
pub const SYS_CLOCK_GETRES: usize = 114;
|
||||
pub const SYS_CLOCK_NANOSLEEP: usize = 115;
|
||||
pub const SYS_SYSLOG: usize = 116;
|
||||
pub const SYS_PTRACE: usize = 117;
|
||||
pub const SYS_SCHED_SETPARAM: usize = 118;
|
||||
pub const SYS_SCHED_SETSCHEDULER: usize = 119;
|
||||
pub const SYS_SCHED_GETSCHEDULER: usize = 120;
|
||||
pub const SYS_SCHED_GETPARAM: usize = 121;
|
||||
pub const SYS_SCHED_SETAFFINITY: usize = 122;
|
||||
pub const SYS_SCHED_GETAFFINITY: usize = 123;
|
||||
pub const SYS_SCHED_YIELD: usize = 124;
|
||||
pub const SYS_SCHED_GET_PRIORITY_MAX: usize = 125;
|
||||
pub const SYS_SCHED_GET_PRIORITY_MIN: usize = 126;
|
||||
pub const SYS_SCHED_RR_GET_INTERVAL: usize = 127;
|
||||
pub const SYS_RESTART_SYSCALL: usize = 128;
|
||||
pub const SYS_KILL: usize = 129;
|
||||
pub const SYS_TKILL: usize = 130;
|
||||
pub const SYS_TGKILL: usize = 131;
|
||||
pub const SYS_SIGALTSTACK: usize = 132;
|
||||
pub const SYS_RT_SIGSUSPEND: usize = 133;
|
||||
pub const SYS_RT_SIGACTION: usize = 134;
|
||||
pub const SYS_RT_SIGPROCMASK: usize = 135;
|
||||
pub const SYS_RT_SIGPENDING: usize = 136;
|
||||
pub const SYS_RT_SIGTIMEDWAIT: usize = 137;
|
||||
pub const SYS_RT_SIGQUEUEINFO: usize = 138;
|
||||
pub const SYS_RT_SIGRETURN: usize = 139;
|
||||
pub const SYS_SETPRIORITY: usize = 140;
|
||||
pub const SYS_GETPRIORITY: usize = 141;
|
||||
pub const SYS_REBOOT: usize = 142;
|
||||
pub const SYS_SETREGID: usize = 143;
|
||||
pub const SYS_SETGID: usize = 144;
|
||||
pub const SYS_SETREUID: usize = 145;
|
||||
pub const SYS_SETUID: usize = 146;
|
||||
pub const SYS_SETRESUID: usize = 147;
|
||||
pub const SYS_GETRESUID: usize = 148;
|
||||
pub const SYS_SETRESGID: usize = 149;
|
||||
pub const SYS_GETRESGID: usize = 150;
|
||||
pub const SYS_SETFSUID: usize = 151;
|
||||
pub const SYS_SETFSGID: usize = 152;
|
||||
pub const SYS_TIMES: usize = 153;
|
||||
pub const SYS_SETPGID: usize = 154;
|
||||
pub const SYS_GETPGID: usize = 155;
|
||||
pub const SYS_GETSID: usize = 156;
|
||||
pub const SYS_SETSID: usize = 157;
|
||||
pub const SYS_GETGROUPS: usize = 158;
|
||||
pub const SYS_SETGROUPS: usize = 159;
|
||||
pub const SYS_UNAME: usize = 160;
|
||||
pub const SYS_SETHOSTNAME: usize = 161;
|
||||
pub const SYS_SETDOMAINNAME: usize = 162;
|
||||
pub const SYS_GETRUSAGE: usize = 165;
|
||||
pub const SYS_UMASK: usize = 166;
|
||||
pub const SYS_PRCTL: usize = 167;
|
||||
pub const SYS_GETCPU: usize = 168;
|
||||
pub const SYS_GETTIMEOFDAY: usize = 169;
|
||||
pub const SYS_SETTIMEOFDAY: usize = 170;
|
||||
pub const SYS_ADJTIMEX: usize = 171;
|
||||
pub const SYS_GETPID: usize = 172;
|
||||
pub const SYS_GETPPID: usize = 173;
|
||||
pub const SYS_GETUID: usize = 174;
|
||||
pub const SYS_GETEUID: usize = 175;
|
||||
pub const SYS_GETGID: usize = 176;
|
||||
pub const SYS_GETEGID: usize = 177;
|
||||
pub const SYS_GETTID: usize = 178;
|
||||
pub const SYS_SYSINFO: usize = 179;
|
||||
pub const SYS_MQ_OPEN: usize = 180;
|
||||
pub const SYS_MQ_UNLINK: usize = 181;
|
||||
pub const SYS_MQ_TIMEDSEND: usize = 182;
|
||||
pub const SYS_MQ_TIMEDRECEIVE: usize = 183;
|
||||
pub const SYS_MQ_NOTIFY: usize = 184;
|
||||
pub const SYS_MQ_GETSETATTR: usize = 185;
|
||||
pub const SYS_MSGGET: usize = 186;
|
||||
pub const SYS_MSGCTL: usize = 187;
|
||||
pub const SYS_MSGRCV: usize = 188;
|
||||
pub const SYS_MSGSND: usize = 189;
|
||||
pub const SYS_SEMGET: usize = 190;
|
||||
pub const SYS_SEMCTL: usize = 191;
|
||||
pub const SYS_SEMTIMEDOP: usize = 192;
|
||||
pub const SYS_SEMOP: usize = 193;
|
||||
pub const SYS_SHMGET: usize = 194;
|
||||
pub const SYS_SHMCTL: usize = 195;
|
||||
pub const SYS_SHMAT: usize = 196;
|
||||
pub const SYS_SHMDT: usize = 197;
|
||||
pub const SYS_SOCKET: usize = 198;
|
||||
pub const SYS_SOCKETPAIR: usize = 199;
|
||||
pub const SYS_BIND: usize = 200;
|
||||
pub const SYS_LISTEN: usize = 201;
|
||||
pub const SYS_ACCEPT: usize = 202;
|
||||
pub const SYS_CONNECT: usize = 203;
|
||||
pub const SYS_GETSOCKNAME: usize = 204;
|
||||
pub const SYS_GETPEERNAME: usize = 205;
|
||||
pub const SYS_SENDTO: usize = 206;
|
||||
pub const SYS_RECVFROM: usize = 207;
|
||||
pub const SYS_SETSOCKOPT: usize = 208;
|
||||
pub const SYS_GETSOCKOPT: usize = 209;
|
||||
pub const SYS_SHUTDOWN: usize = 210;
|
||||
pub const SYS_SENDMSG: usize = 211;
|
||||
pub const SYS_RECVMSG: usize = 212;
|
||||
pub const SYS_READAHEAD: usize = 213;
|
||||
pub const SYS_BRK: usize = 214;
|
||||
pub const SYS_MUNMAP: usize = 215;
|
||||
pub const SYS_MREMAP: usize = 216;
|
||||
pub const SYS_ADD_KEY: usize = 217;
|
||||
pub const SYS_REQUEST_KEY: usize = 218;
|
||||
pub const SYS_KEYCTL: usize = 219;
|
||||
pub const SYS_CLONE: usize = 220;
|
||||
pub const SYS_EXECVE: usize = 221;
|
||||
pub const SYS_MMAP: usize = 222;
|
||||
pub const SYS_FADVISE64: usize = 223;
|
||||
pub const SYS_SWAPON: usize = 224;
|
||||
pub const SYS_SWAPOFF: usize = 225;
|
||||
pub const SYS_MPROTECT: usize = 226;
|
||||
pub const SYS_MSYNC: usize = 227;
|
||||
pub const SYS_MLOCK: usize = 228;
|
||||
pub const SYS_MUNLOCK: usize = 229;
|
||||
pub const SYS_MLOCKALL: usize = 230;
|
||||
pub const SYS_MUNLOCKALL: usize = 231;
|
||||
pub const SYS_MINCORE: usize = 232;
|
||||
pub const SYS_MADVISE: usize = 233;
|
||||
pub const SYS_REMAP_FILE_PAGES: usize = 234;
|
||||
pub const SYS_MBIND: usize = 235;
|
||||
pub const SYS_GET_MEMPOLICY: usize = 236;
|
||||
pub const SYS_SET_MEMPOLICY: usize = 237;
|
||||
pub const SYS_MIGRATE_PAGES: usize = 238;
|
||||
pub const SYS_MOVE_PAGES: usize = 239;
|
||||
pub const SYS_RT_TGSIGQUEUEINFO: usize = 240;
|
||||
pub const SYS_PERF_EVENT_OPEN: usize = 241;
|
||||
pub const SYS_ACCEPT4: usize = 242;
|
||||
pub const SYS_RECVMMSG: usize = 243;
|
||||
//pub const SYS_ARCH_SPECIFIC_SYSCALL: usize = 244;
|
||||
pub const SYS_WAIT4: usize = 260;
|
||||
pub const SYS_PRLIMIT64: usize = 261;
|
||||
pub const SYS_FANOTIFY_INIT: usize = 262;
|
||||
pub const SYS_FANOTIFY_MARK: usize = 263;
|
||||
pub const SYS_NAME_TO_HANDLE_AT: usize = 264;
|
||||
pub const SYS_OPEN_BY_HANDLE_AT: usize = 265;
|
||||
pub const SYS_CLOCK_ADJTIME: usize = 266;
|
||||
pub const SYS_SYNCFS: usize = 267;
|
||||
pub const SYS_SETNS: usize = 268;
|
||||
pub const SYS_SENDMMSG: usize = 269;
|
||||
pub const SYS_PROCESS_VM_READV: usize = 270;
|
||||
pub const SYS_PROCESS_VM_WRITEV: usize = 271;
|
||||
pub const SYS_KCMP: usize = 272;
|
||||
pub const SYS_FINIT_MODULE: usize = 273;
|
||||
pub const SYS_SCHED_SETATTR: usize = 274;
|
||||
pub const SYS_SCHED_GETATTR: usize = 275;
|
||||
pub const SYS_RENAMEAT2: usize = 276;
|
||||
pub const SYS_SECCOMP: usize = 277;
|
||||
pub const SYS_GETRANDOM: usize = 278;
|
||||
pub const SYS_MEMFD_CREATE: usize = 279;
|
||||
pub const SYS_BPF: usize = 280;
|
||||
pub const SYS_EXECVEAT: usize = 281;
|
||||
pub const SYS_USERFAULTFD: usize = 282;
|
||||
pub const SYS_MEMBARRIER: usize = 283;
|
||||
pub const SYS_MLOCK2: usize = 284;
|
||||
pub const SYS_COPY_FILE_RANGE: usize = 285;
|
||||
pub const SYS_PREADV2: usize = 286;
|
||||
pub const SYS_PWRITEV2: usize = 287;
|
||||
pub const SYS_PKEY_MPROTECT: usize = 288;
|
||||
pub const SYS_PKEY_ALLOC: usize = 289;
|
||||
pub const SYS_PKEY_FREE: usize = 290;
|
||||
pub const SYS_STATX: usize = 291;
|
||||
pub const SYS_IO_PGETEVENTS: usize = 292;
|
||||
pub const SYS_RSEQ: usize = 293;
|
||||
pub const SYS_KEXEC_FILE_LOAD: usize = 294;
|
||||
pub const SYS_PIDFD_SEND_SIGNAL: usize = 424;
|
||||
pub const SYS_IO_URING_SETUP: usize = 425;
|
||||
pub const SYS_IO_URING_ENTER: usize = 426;
|
||||
pub const SYS_IO_URING_REGISTER: usize = 427;
|
||||
pub const SYS_OPEN_TREE: usize = 428;
|
||||
pub const SYS_MOVE_MOUNT: usize = 429;
|
||||
pub const SYS_FSOPEN: usize = 430;
|
||||
pub const SYS_FSCONFIG: usize = 431;
|
||||
pub const SYS_FSMOUNT: usize = 432;
|
||||
pub const SYS_FSPICK: usize = 433;
|
||||
pub const SYS_PIDFD_OPEN: usize = 434;
|
||||
pub const SYS_CLONE3: usize = 435;
|
||||
pub const SYS_CLOSE_RANGE: usize = 436;
|
||||
pub const SYS_OPENAT2: usize = 437;
|
||||
pub const SYS_PIDFD_GETFD: usize = 438;
|
||||
pub const SYS_FACCESSAT2: usize = 439;
|
||||
pub const SYS_PROCESS_MADVISE: usize = 440;
|
||||
pub const SYS_EPOLL_PWAIT2: usize = 441;
|
||||
pub const SYS_MOUNT_SETATTR: usize = 442;
|
||||
pub const SYS_QUOTACTL_FD: usize = 443;
|
||||
pub const SYS_LANDLOCK_CREATE_RULESET: usize = 444;
|
||||
pub const SYS_LANDLOCK_ADD_RULE: usize = 445;
|
||||
pub const SYS_LANDLOCK_RESTRICT_SELF: usize = 446;
|
||||
pub const SYS_PROCESS_MRELEASE: usize = 448;
|
||||
pub const SYS_FUTEX_WAITV: usize = 449;
|
||||
pub const SYS_SET_MEMPOLICY_HOME_NODE: usize = 450;
|
||||
|
||||
// ===以下是为了代码一致性,才定义的调用号===
|
||||
|
||||
pub const SYS_GETDENTS: usize = SYS_GETDENTS64;
|
24
kernel/src/arch/loongarch64/time.rs
Normal file
24
kernel/src/arch/loongarch64/time.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use crate::time::{clocksource::HZ, TimeArch};
|
||||
|
||||
/// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
|
||||
pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
|
||||
|
||||
pub struct LoongArch64TimeArch;
|
||||
|
||||
impl TimeArch for LoongArch64TimeArch {
|
||||
fn get_cycles() -> usize {
|
||||
todo!("LoongArch64TimeArch::get_cycles")
|
||||
}
|
||||
|
||||
fn cal_expire_cycles(ns: usize) -> usize {
|
||||
todo!("LoongArch64TimeArch::cal_expire_cycles")
|
||||
}
|
||||
|
||||
fn cycles2ns(cycles: usize) -> usize {
|
||||
todo!("LoongArch64TimeArch::cycles2ns")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn time_init() {
|
||||
todo!("la64:time_init");
|
||||
}
|
@ -13,6 +13,11 @@ pub mod riscv64;
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub use self::riscv64::*; // 公开riscv64架构下的函数,使外界接口统一
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
pub mod loongarch64;
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
pub use self::loongarch64::*; // 公开loongarch64架构下的函数,使外界接口统一
|
||||
|
||||
pub mod io;
|
||||
|
||||
/// TraitPciArch Pci架构相关函数,任何架构都应独立实现trait里的函数
|
||||
|
@ -95,9 +95,7 @@ impl From<i32> for Signal {
|
||||
|
||||
impl Into<SigSet> for Signal {
|
||||
fn into(self) -> SigSet {
|
||||
SigSet {
|
||||
bits: (1 << (self as usize - 1) as u64),
|
||||
}
|
||||
self.into_sigset()
|
||||
}
|
||||
}
|
||||
impl Signal {
|
||||
|
@ -1,13 +1,5 @@
|
||||
use crate::libs::rand::soft_rand;
|
||||
|
||||
pub fn rand() -> usize {
|
||||
static mut SEED: u64 = 0xdead_beef_cafe_babe;
|
||||
let mut buf = [0u8; size_of::<usize>()];
|
||||
for x in buf.iter_mut() {
|
||||
unsafe {
|
||||
// from musl
|
||||
SEED = SEED.wrapping_mul(0x5851_f42d_4c95_7f2d);
|
||||
*x = (SEED >> 33) as u8;
|
||||
}
|
||||
}
|
||||
let x: usize = unsafe { core::mem::transmute(buf) };
|
||||
return x;
|
||||
return soft_rand();
|
||||
}
|
||||
|
@ -1,10 +1,26 @@
|
||||
use crate::debug::traceback::lookup_kallsyms;
|
||||
use crate::libs::spinlock::SpinLock;
|
||||
use core::ffi::c_void;
|
||||
use unwinding::abi::{UnwindContext, UnwindReasonCode, _Unwind_Backtrace, _Unwind_GetIP};
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(not(target_arch = "loongarch64"))]
|
||||
{
|
||||
use unwinding::abi::{UnwindContext, UnwindReasonCode, _Unwind_Backtrace, _Unwind_GetIP};
|
||||
use core::ffi::c_void;
|
||||
use crate::debug::traceback::lookup_kallsyms;
|
||||
}
|
||||
}
|
||||
|
||||
static GLOBAL_LOCK: SpinLock<()> = SpinLock::new(());
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
pub fn print_stack_trace() {
|
||||
let _lock = GLOBAL_LOCK.lock();
|
||||
println!("This Arch does not support stack trace printing.");
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "loongarch64"))]
|
||||
pub fn print_stack_trace() {
|
||||
static GLOBAL_LOCK: SpinLock<()> = SpinLock::new(());
|
||||
let _lock = GLOBAL_LOCK.lock();
|
||||
println!("Rust Panic Backtrace:");
|
||||
struct CallbackData {
|
||||
|
@ -63,6 +63,7 @@ pub fn panic(info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "loongarch64"))]
|
||||
if info.can_unwind() {
|
||||
let guard = Box::new(PanicGuard::new());
|
||||
hook::print_stack_trace();
|
||||
@ -79,6 +80,7 @@ pub fn panic(info: &PanicInfo) -> ! {
|
||||
/// The wrapper of `unwinding::panic::begin_panic`. If the panic is
|
||||
/// caught, it will return the result of the function.
|
||||
/// If the panic is not caught, it will return an error.
|
||||
#[cfg(not(target_arch = "loongarch64"))]
|
||||
pub fn kernel_catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, SystemError> {
|
||||
let res = unwinding::panic::catch_unwind(f);
|
||||
match res {
|
||||
@ -90,6 +92,7 @@ pub fn kernel_catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, SystemError>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "loongarch64"))]
|
||||
#[allow(unused)]
|
||||
pub fn test_unwind() {
|
||||
struct UnwindTest;
|
||||
|
@ -43,6 +43,9 @@ use super::{uart_manager, UartDriver, UartManager, UartPort, TTY_SERIAL_DEFAULT_
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod serial8250_pio;
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
mod serial8250_la64;
|
||||
|
||||
static mut SERIAL8250_ISA_DEVICES: Option<Arc<Serial8250ISADevices>> = None;
|
||||
static mut SERIAL8250_ISA_DRIVER: Option<Arc<Serial8250ISADriver>> = None;
|
||||
|
||||
@ -75,8 +78,11 @@ impl Serial8250Manager {
|
||||
/// 初始化串口设备(在内存管理初始化之前)
|
||||
pub fn early_init(&self) -> Result<(), SystemError> {
|
||||
// todo: riscv64: 串口设备初始化
|
||||
#[cfg(not(target_arch = "riscv64"))]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
serial8250_pio_port_early_init()?;
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
serial8250_la64::early_la64_seria8250_init()?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@ -127,7 +133,7 @@ impl Serial8250Manager {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
#[cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))]
|
||||
fn serial_tty_init(&self) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
@ -564,4 +570,9 @@ pub fn send_to_default_serial8250_port(s: &[u8]) {
|
||||
{
|
||||
crate::arch::driver::sbi::console_putstr(s);
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
serial8250_la64::send_to_default_serial8250_la64_port(s);
|
||||
}
|
||||
}
|
||||
|
69
kernel/src/driver/serial/serial8250/serial8250_la64.rs
Normal file
69
kernel/src/driver/serial/serial8250/serial8250_la64.rs
Normal file
@ -0,0 +1,69 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::MMArch,
|
||||
libs::spinlock::SpinLock,
|
||||
mm::{MemoryManagementArch, PhysAddr, VirtAddr},
|
||||
};
|
||||
|
||||
const UART_PADDR_COM1: PhysAddr = PhysAddr::new(0x01FE001E0);
|
||||
|
||||
static mut UART_PORT_COM1: Option<SpinLock<Serial8250LA64Port>> = None;
|
||||
|
||||
struct Serial8250LA64Port {
|
||||
base_address: VirtAddr,
|
||||
}
|
||||
|
||||
impl Serial8250LA64Port {
|
||||
pub fn new(base_address: PhysAddr) -> Self {
|
||||
Self {
|
||||
base_address: unsafe { MMArch::phys_2_virt(base_address).unwrap() },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn putchar(&mut self, c: u8) {
|
||||
let ptr = self.base_address.as_ptr() as *mut u8;
|
||||
loop {
|
||||
unsafe {
|
||||
if ptr.add(5).read_volatile() & (1 << 5) != 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
ptr.add(0).write_volatile(c);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getchar(&mut self) -> Option<u8> {
|
||||
let ptr = self.base_address.as_ptr() as *mut u8;
|
||||
unsafe {
|
||||
if ptr.add(5).read_volatile() & 1 == 0 {
|
||||
// The DR bit is 0, meaning no data
|
||||
None
|
||||
} else {
|
||||
// The DR bit is 1, meaning data!
|
||||
Some(ptr.add(0).read_volatile())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub(super) fn early_la64_seria8250_init() -> Result<(), SystemError> {
|
||||
let port = Serial8250LA64Port::new(UART_PADDR_COM1);
|
||||
unsafe {
|
||||
UART_PORT_COM1 = Some(SpinLock::new(port));
|
||||
}
|
||||
send_to_default_serial8250_la64_port(b"[DragonOS] loongarch64 debug uart port initialized!\n");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn send_to_default_serial8250_la64_port(s: &[u8]) {
|
||||
if let Some(com) = unsafe { UART_PORT_COM1.as_ref() } {
|
||||
let mut cg = com.lock_irqsave();
|
||||
for c in s.iter() {
|
||||
cg.putchar(*c);
|
||||
}
|
||||
}
|
||||
}
|
@ -155,7 +155,7 @@ impl VideoRefreshManager {
|
||||
}
|
||||
|
||||
/// 在riscv64平台下暂时不支持
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
#[cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))]
|
||||
pub unsafe fn video_init() -> Result<(), SystemError> {
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ impl BootParams {
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
return Some(self.arch.arch_fdt());
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "loongarch64"))]
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ impl BootParams {
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
return Some(self.arch.fdt_paddr);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "loongarch64"))]
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ fn do_start_kernel() {
|
||||
#[inline(never)]
|
||||
fn init_before_mem_init() {
|
||||
serial_early_init().expect("serial early init failed");
|
||||
|
||||
let video_ok = unsafe { VideoRefreshManager::video_init().is_ok() };
|
||||
scm_init(video_ok);
|
||||
|
||||
|
206
kernel/src/ipc/generic_signal.rs
Normal file
206
kernel/src/ipc/generic_signal.rs
Normal file
@ -0,0 +1,206 @@
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
use crate::arch::ipc::signal::{SigSet, MAX_SIG_NUM};
|
||||
|
||||
/// 信号处理的栈的栈指针的最小对齐
|
||||
#[allow(dead_code)]
|
||||
pub const GENERIC_STACK_ALIGN: u64 = 16;
|
||||
/// 信号最大值
|
||||
#[allow(dead_code)]
|
||||
pub const GENERIC_MAX_SIG_NUM: usize = 64;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Eq, PartialEq, FromPrimitive)]
|
||||
#[repr(usize)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[atomic_enum]
|
||||
pub enum GenericSignal {
|
||||
INVALID = 0,
|
||||
SIGHUP = 1,
|
||||
SIGINT,
|
||||
SIGQUIT,
|
||||
SIGILL,
|
||||
SIGTRAP,
|
||||
/// SIGABRT和SIGIOT共用这个号码
|
||||
SIGABRT_OR_IOT,
|
||||
SIGBUS,
|
||||
SIGFPE,
|
||||
SIGKILL,
|
||||
SIGUSR1,
|
||||
|
||||
SIGSEGV = 11,
|
||||
SIGUSR2,
|
||||
SIGPIPE,
|
||||
SIGALRM,
|
||||
SIGTERM,
|
||||
SIGSTKFLT,
|
||||
SIGCHLD,
|
||||
SIGCONT,
|
||||
SIGSTOP,
|
||||
SIGTSTP,
|
||||
|
||||
SIGTTIN = 21,
|
||||
SIGTTOU,
|
||||
SIGURG,
|
||||
SIGXCPU,
|
||||
SIGXFSZ,
|
||||
SIGVTALRM,
|
||||
SIGPROF,
|
||||
SIGWINCH,
|
||||
/// SIGIO和SIGPOLL共用这个号码
|
||||
SIGIO_OR_POLL,
|
||||
SIGPWR,
|
||||
|
||||
SIGSYS = 31,
|
||||
|
||||
SIGRTMIN = 32,
|
||||
SIGRTMAX = 64,
|
||||
}
|
||||
|
||||
impl GenericSignal {
|
||||
/// 判断一个数字是否为可用的信号
|
||||
#[inline]
|
||||
pub fn is_valid(&self) -> bool {
|
||||
return (*self) as usize <= MAX_SIG_NUM;
|
||||
}
|
||||
|
||||
/// const convertor between `Signal` and `SigSet`
|
||||
pub const fn into_sigset(self) -> SigSet {
|
||||
SigSet::from_bits_truncate(1 << (self as usize - 1))
|
||||
}
|
||||
|
||||
/// 判断一个信号是不是实时信号
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// - `true` 这个信号是实时信号
|
||||
/// - `false` 这个信号不是实时信号
|
||||
#[inline]
|
||||
pub fn is_rt_signal(&self) -> bool {
|
||||
return (*self) as usize >= Self::SIGRTMIN.into();
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GenericSignal> for usize {
|
||||
fn from(val: GenericSignal) -> Self {
|
||||
val as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for GenericSignal {
|
||||
fn from(value: usize) -> Self {
|
||||
<Self as FromPrimitive>::from_usize(value).unwrap_or(GenericSignal::INVALID)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i32> for GenericSignal {
|
||||
fn from(value: i32) -> Self {
|
||||
if value < 0 {
|
||||
log::error!("Try to convert an invalid number to GenericSignal");
|
||||
return GenericSignal::INVALID;
|
||||
} else {
|
||||
return Self::from(value as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GenericSignal> for GenericSigSet {
|
||||
fn from(val: GenericSignal) -> Self {
|
||||
GenericSigSet {
|
||||
bits: (1 << (val as usize - 1) as u64),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// SIGCHLD si_codes
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, ToPrimitive)]
|
||||
#[allow(dead_code)]
|
||||
pub enum GenericSigChildCode {
|
||||
/// child has exited
|
||||
///
|
||||
/// CLD_EXITED
|
||||
Exited = 1,
|
||||
/// child was killed
|
||||
///
|
||||
/// CLD_KILLED
|
||||
Killed = 2,
|
||||
/// child terminated abnormally
|
||||
///
|
||||
/// CLD_DUMPED
|
||||
Dumped = 3,
|
||||
/// traced child has trapped
|
||||
///
|
||||
/// CLD_TRAPPED
|
||||
Trapped = 4,
|
||||
/// child has stopped
|
||||
///
|
||||
/// CLD_STOPPED
|
||||
Stopped = 5,
|
||||
/// stopped child has continued
|
||||
///
|
||||
/// CLD_CONTINUED
|
||||
Continued = 6,
|
||||
}
|
||||
|
||||
impl From<GenericSigChildCode> for i32 {
|
||||
fn from(value: GenericSigChildCode) -> Self {
|
||||
value as i32
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// 请注意,sigset 这个bitmap, 第0位表示sig=1的信号。也就是说,Signal-1才是sigset_t中对应的位
|
||||
#[derive(Default)]
|
||||
pub struct GenericSigSet:u64 {
|
||||
const SIGHUP = 1<<0;
|
||||
const SIGINT = 1<<1;
|
||||
const SIGQUIT = 1<<2;
|
||||
const SIGILL = 1<<3;
|
||||
const SIGTRAP = 1<<4;
|
||||
/// SIGABRT和SIGIOT共用这个号码
|
||||
const SIGABRT_OR_IOT = 1<<5;
|
||||
const SIGBUS = 1<<6;
|
||||
const SIGFPE = 1<<7;
|
||||
const SIGKILL = 1<<8;
|
||||
const SIGUSR = 1<<9;
|
||||
const SIGSEGV = 1<<10;
|
||||
const SIGUSR2 = 1<<11;
|
||||
const SIGPIPE = 1<<12;
|
||||
const SIGALRM = 1<<13;
|
||||
const SIGTERM = 1<<14;
|
||||
const SIGSTKFLT= 1<<15;
|
||||
const SIGCHLD = 1<<16;
|
||||
const SIGCONT = 1<<17;
|
||||
const SIGSTOP = 1<<18;
|
||||
const SIGTSTP = 1<<19;
|
||||
const SIGTTIN = 1<<20;
|
||||
const SIGTTOU = 1<<21;
|
||||
const SIGURG = 1<<22;
|
||||
const SIGXCPU = 1<<23;
|
||||
const SIGXFSZ = 1<<24;
|
||||
const SIGVTALRM= 1<<25;
|
||||
const SIGPROF = 1<<26;
|
||||
const SIGWINCH = 1<<27;
|
||||
/// SIGIO和SIGPOLL共用这个号码
|
||||
const SIGIO_OR_POLL = 1<<28;
|
||||
const SIGPWR = 1<<29;
|
||||
const SIGSYS = 1<<30;
|
||||
const SIGRTMIN = 1<<31;
|
||||
// TODO 写上实时信号
|
||||
const SIGRTMAX = 1 << (GENERIC_MAX_SIG_NUM-1);
|
||||
}
|
||||
|
||||
#[repr(C,align(8))]
|
||||
#[derive(Default)]
|
||||
pub struct GenericSigFlags:u32{
|
||||
const SA_NOCLDSTOP = 1;
|
||||
const SA_NOCLDWAIT = 2;
|
||||
const SA_SIGINFO = 4;
|
||||
const SA_ONSTACK = 0x08000000;
|
||||
const SA_RESTART = 0x10000000;
|
||||
const SA_NODEFER = 0x40000000;
|
||||
const SA_RESETHAND = 0x80000000;
|
||||
const SA_RESTORER =0x04000000;
|
||||
const SA_ALL = Self::SA_NOCLDSTOP.bits()|Self::SA_NOCLDWAIT.bits()|Self::SA_NODEFER.bits()|Self::SA_ONSTACK.bits()|Self::SA_RESETHAND.bits()|Self::SA_RESTART.bits()|Self::SA_SIGINFO.bits()|Self::SA_RESTORER.bits();
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
pub mod generic_signal;
|
||||
pub mod pipe;
|
||||
pub mod shm;
|
||||
pub mod signal;
|
||||
|
@ -1,13 +1,16 @@
|
||||
#![no_main] // <1>
|
||||
#![no_std]
|
||||
#![feature(alloc_error_handler)]
|
||||
#![feature(asm_goto)]
|
||||
#![feature(new_zeroed_alloc)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(arbitrary_self_types)]
|
||||
#![feature(concat_idents)]
|
||||
#![feature(const_for)]
|
||||
#![feature(const_size_of_val)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(c_variadic)]
|
||||
#![feature(c_void_variant)]
|
||||
#![feature(extract_if)]
|
||||
#![feature(fn_align)]
|
||||
@ -18,8 +21,6 @@
|
||||
#![feature(slice_ptr_get)]
|
||||
#![feature(sync_unsafe_cell)]
|
||||
#![feature(vec_into_raw_parts)]
|
||||
#![feature(c_variadic)]
|
||||
#![feature(asm_goto)]
|
||||
#![feature(linkage)]
|
||||
#![feature(panic_can_unwind)]
|
||||
#![allow(static_mut_refs, non_local_definitions, internal_features)]
|
||||
|
@ -106,6 +106,19 @@ impl ElfLoader {
|
||||
return self.inner_probe_common(param, ehdr);
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
pub fn probe_loongarch(
|
||||
&self,
|
||||
param: &ExecParam,
|
||||
ehdr: &FileHeader<AnyEndian>,
|
||||
) -> Result<(), ExecError> {
|
||||
// 判断架构是否匹配
|
||||
if ElfMachine::from(ehdr.e_machine) != ElfMachine::LoongArch {
|
||||
return Err(ExecError::WrongArchitecture);
|
||||
}
|
||||
return self.inner_probe_common(param, ehdr);
|
||||
}
|
||||
|
||||
/// 设置用户堆空间,映射[start, end)区间的虚拟地址,并把brk指针指向end
|
||||
///
|
||||
/// ## 参数
|
||||
@ -512,7 +525,14 @@ impl BinaryLoader for ElfLoader {
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
return self.probe_riscv(param, &ehdr);
|
||||
|
||||
#[cfg(not(any(target_arch = "x86_64", target_arch = "riscv64")))]
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
return self.probe_loongarch(param, &ehdr);
|
||||
|
||||
#[cfg(not(any(
|
||||
target_arch = "x86_64",
|
||||
target_arch = "riscv64",
|
||||
target_arch = "loongarch64"
|
||||
)))]
|
||||
compile_error!("BinaryLoader: Unsupported architecture");
|
||||
}
|
||||
|
||||
|
@ -5,3 +5,19 @@ bitflags! {
|
||||
const GRND_INSECURE = 0x0004;
|
||||
}
|
||||
}
|
||||
|
||||
// 软件实现的随机数生成器
|
||||
#[allow(dead_code)]
|
||||
pub fn soft_rand() -> usize {
|
||||
static mut SEED: u64 = 0xdead_beef_cafe_babe;
|
||||
let mut buf = [0u8; size_of::<usize>()];
|
||||
for x in buf.iter_mut() {
|
||||
unsafe {
|
||||
// from musl
|
||||
SEED = SEED.wrapping_mul(0x5851_f42d_4c95_7f2d);
|
||||
*x = (SEED >> 33) as u8;
|
||||
}
|
||||
}
|
||||
let x: usize = unsafe { core::mem::transmute(buf) };
|
||||
return x;
|
||||
}
|
||||
|
@ -202,7 +202,6 @@ impl<T> RwLock<T> {
|
||||
return (self.lock.load(Ordering::Relaxed) & WRITER) / WRITER;
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
/// @brief 尝试获得WRITER守卫
|
||||
@ -216,7 +215,6 @@ impl<T> RwLock<T> {
|
||||
return r;
|
||||
} //当架构为arm时,有些代码需要作出调整compare_exchange=>compare_exchange_weak
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn try_write_irqsave(&self) -> Option<RwLockWriteGuard<T>> {
|
||||
@ -233,7 +231,6 @@ impl<T> RwLock<T> {
|
||||
return r;
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
#[allow(dead_code)]
|
||||
fn inner_try_write(&self) -> Option<RwLockWriteGuard<T>> {
|
||||
let res: bool = self
|
||||
|
@ -488,7 +488,6 @@ impl MmioBuddyMemPool {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
// 计算前导0
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
let mut size_exp: u32 = 63 - size.leading_zeros();
|
||||
// debug!("create_mmio: size_exp: {}", size_exp);
|
||||
// 记录最终申请的空间大小
|
||||
|
@ -927,6 +927,11 @@ impl<Arch: MemoryManagementArch> PageEntry<Arch> {
|
||||
let ppn = ((self.data & (!((1 << 10) - 1))) >> 10) & ((1 << 54) - 1);
|
||||
super::allocator::page_frame::PhysPageFrame::from_ppn(ppn).phys_address()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
todo!("la64: PageEntry::address")
|
||||
}
|
||||
};
|
||||
|
||||
if self.present() {
|
||||
@ -1055,6 +1060,11 @@ impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
|
||||
// riscv64指向下一级页表的页表项,不应设置R/W/X权限位
|
||||
Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE)
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@ -1070,6 +1080,11 @@ impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
|
||||
{
|
||||
r
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
todo!("loongarch64: new_page_table")
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1147,6 +1162,11 @@ impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
|
||||
.update_flags(Arch::ENTRY_FLAG_WRITEABLE, false);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
todo!("la64: set_write")
|
||||
}
|
||||
}
|
||||
|
||||
/// 当前页表项是否可写
|
||||
@ -1280,6 +1300,11 @@ impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
|
||||
.set_execute(true)
|
||||
.set_page_global(true)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
todo!("la64: mmio_flags()")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,9 @@ impl PerCpu {
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub const MAX_CPU_NUM: u32 = 64;
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
pub const MAX_CPU_NUM: u32 = 128;
|
||||
|
||||
/// # 初始化PerCpu
|
||||
///
|
||||
/// 该函数应该在内核初始化时调用一次。
|
||||
|
@ -97,6 +97,11 @@ impl ProcessManager {
|
||||
}
|
||||
return VirtAddr::new(stack_ptr);
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
todo!("la64: stack_ptr() not implemented yet")
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取idle进程数组的引用
|
||||
|
@ -64,6 +64,9 @@ impl PosixOldUtsName {
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
const MACHINE: &[u8] = b"riscv64";
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
const MACHINE: &[u8] = b"longarch64";
|
||||
|
||||
let mut r = Self {
|
||||
sysname: [0; 65],
|
||||
nodename: [0; 65],
|
||||
|
@ -16,7 +16,7 @@ impl SchedClock {
|
||||
return CurrentTimeArch::cycles2ns(CurrentTimeArch::get_cycles()) as u64;
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
#[cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))]
|
||||
{
|
||||
return CurrentTimeArch::cycles2ns(CurrentTimeArch::get_cycles()) as u64;
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ use core::{
|
||||
|
||||
use crate::{
|
||||
arch::{ipc::signal::SigSet, syscall::nr::*},
|
||||
debug::panic::kernel_catch_unwind,
|
||||
filesystem::vfs::syscall::{PosixStatfs, PosixStatx},
|
||||
ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
|
||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||
@ -78,11 +77,13 @@ impl Syscall {
|
||||
/// 系统调用分发器,用于分发系统调用。
|
||||
///
|
||||
/// 与[handle]不同,这个函数会捕获系统调用处理函数的panic,返回错误码。
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
pub fn catch_handle(
|
||||
syscall_num: usize,
|
||||
args: &[usize],
|
||||
frame: &mut TrapFrame,
|
||||
) -> Result<usize, SystemError> {
|
||||
use crate::debug::panic::kernel_catch_unwind;
|
||||
let res = kernel_catch_unwind(|| Self::handle(syscall_num, args, frame))?;
|
||||
res
|
||||
}
|
||||
@ -669,6 +670,8 @@ impl Syscall {
|
||||
SYS_GETPGID => Self::getpgid(Pid::new(args[0])).map(|pid| pid.into()),
|
||||
|
||||
SYS_GETPPID => Self::getppid().map(|pid| pid.into()),
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
SYS_FSTAT => {
|
||||
let fd = args[0] as i32;
|
||||
let kstat: *mut PosixKstat = args[1] as *mut PosixKstat;
|
||||
@ -1130,6 +1133,7 @@ impl Syscall {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
SYS_NEWFSTATAT => {
|
||||
// todo: 这个系统调用还没有实现
|
||||
|
||||
@ -1228,6 +1232,7 @@ impl Syscall {
|
||||
let flags = args[4] as u32;
|
||||
Self::sys_perf_event_open(attr, pid, cpu, group_fd, flags)
|
||||
}
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
SYS_SETRLIMIT => Ok(0),
|
||||
SYS_RESTART_SYSCALL => Self::restart_syscall(),
|
||||
SYS_RT_SIGPENDING => Self::rt_sigpending(args[0], args[1]),
|
||||
|
@ -86,7 +86,7 @@ impl PosixTimeSpec {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
#[cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))]
|
||||
{
|
||||
return PosixTimeSpec::new(0, 0);
|
||||
}
|
||||
|
1
tools/.gitignore
vendored
1
tools/.gitignore
vendored
@ -5,5 +5,6 @@ arch/i386/efi/grub/*
|
||||
arch/x86_64/efi/grub/*
|
||||
|
||||
*.tar.gz
|
||||
*.tar.xz
|
||||
build/*
|
||||
target/
|
@ -1 +1 @@
|
||||
v1.9
|
||||
v1.10
|
7
tools/bootstrap.sh
Normal file → Executable file
7
tools/bootstrap.sh
Normal file → Executable file
@ -252,6 +252,9 @@ rustInstall() {
|
||||
rustup target add riscv64gc-unknown-linux-musl --toolchain $RUST_VERSION-riscv64gc-unknown-linux-gnu
|
||||
rustup target add riscv64gc-unknown-linux-musl --toolchain $RUST_VERSION_OLD-riscv64gc-unknown-linux-gnu
|
||||
|
||||
rustup target add loongarch64-unknown-none --toolchain $RUST_VERSION-x86_64-unknown-linux-gnu
|
||||
rustup target add loongarch64-unknown-none --toolchain $RUST_VERSION_OLD-x86_64-unknown-linux-gnu
|
||||
|
||||
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
|
||||
rustup component add rust-src
|
||||
rustup component add llvm-tools-preview
|
||||
@ -269,6 +272,8 @@ install_python_pkg()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
############# 脚本开始 ##############
|
||||
# 读取参数及选项,使用 -help 参数查看详细选项
|
||||
while true; do
|
||||
@ -341,7 +346,7 @@ cargo install dadk || exit 1
|
||||
bashpath=$(cd `dirname $0`; pwd)
|
||||
|
||||
# 编译安装musl交叉编译工具链
|
||||
$SHELL ${bashpath}/install_musl_gcc.sh || (echo "musl交叉编译工具链安装失败" && exit 1)
|
||||
$SHELL ${bashpath}/install_cross_gcc.sh || (echo "musl交叉编译工具链安装失败" && exit 1)
|
||||
# 编译安装grub
|
||||
$SHELL ${bashpath}/grub_auto_install.sh || (echo "grub安装失败" && exit 1)
|
||||
|
||||
|
0
tools/build_gcc_toolchain.sh
Normal file → Executable file
0
tools/build_gcc_toolchain.sh
Normal file → Executable file
2
tools/build_in_docker.sh
Normal file → Executable file
2
tools/build_in_docker.sh
Normal file → Executable file
@ -1,6 +1,6 @@
|
||||
docker rm -f dragonos-build || echo "No existed container"
|
||||
cpu_count=$(cat /proc/cpuinfo |grep "processor"|wc -l)
|
||||
docker run --rm --privileged=true --cap-add SYS_ADMIN --cap-add MKNOD -v $(pwd):/data -v /dev:/dev -v dragonos-build-cargo:/root/.cargo/registry --name dragonos-build -i dragonos/dragonos-dev:v1.9 bash << EOF
|
||||
docker run --rm --privileged=true --cap-add SYS_ADMIN --cap-add MKNOD -v $(pwd):/data -v /dev:/dev -v dragonos-build-cargo:/root/.cargo/registry --name dragonos-build -i dragonos/dragonos-dev:v1.10 bash << EOF
|
||||
source ~/.cargo/env
|
||||
source ~/.bashrc
|
||||
cd /data
|
||||
|
0
tools/change_rust_src.sh
Normal file → Executable file
0
tools/change_rust_src.sh
Normal file → Executable file
0
tools/check_arch.sh
Normal file → Executable file
0
tools/check_arch.sh
Normal file → Executable file
0
tools/configure_network.sh
Normal file → Executable file
0
tools/configure_network.sh
Normal file → Executable file
0
tools/docker-entrypoint.sh
Normal file → Executable file
0
tools/docker-entrypoint.sh
Normal file → Executable file
0
tools/dump_kernel.sh
Normal file → Executable file
0
tools/dump_kernel.sh
Normal file → Executable file
0
tools/grub_auto_install.sh
Normal file → Executable file
0
tools/grub_auto_install.sh
Normal file → Executable file
0
tools/init_rust_toolchain.sh
Normal file → Executable file
0
tools/init_rust_toolchain.sh
Normal file → Executable file
32
tools/install_musl_gcc.sh → tools/install_cross_gcc.sh
Normal file → Executable file
32
tools/install_musl_gcc.sh → tools/install_cross_gcc.sh
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#! /bin/bash
|
||||
|
||||
#########################################################################
|
||||
# 这个脚本用于安装musl交叉编译工具链
|
||||
# 该脚本会自动下载musl交叉编译工具链,并将其添加到PATH中
|
||||
@ -12,8 +14,13 @@ MUSL_GCC_VERSION="9.4.0"
|
||||
MUSL_GCC_X86_64_TAR=
|
||||
MUSL_GCC_RISCV64_TAR=
|
||||
|
||||
LA64_GCC_VERSION="loongarch64-cross-14.2.0"
|
||||
LA64_GCC_TAR="${LA64_GCC_VERSION}.tar.xz"
|
||||
|
||||
MUSL_GCC_X86_64_DOWNLOAD_URL=""
|
||||
MUSL_GCC_RISCV64_DOWNLOAD_URL=""
|
||||
LA64_GCC_DOWNLOAD_URL="https://mirrors.dragonos.org.cn/pub/third_party/toolchain/gcc/${LA64_GCC_TAR}"
|
||||
|
||||
if [ $USE_GITHUB -eq 1 ]; then
|
||||
echo "Download from github"
|
||||
|
||||
@ -21,7 +28,6 @@ if [ $USE_GITHUB -eq 1 ]; then
|
||||
MUSL_GCC_RISCV64_TAR=riscv64-linux-musl-cross-gcc-${MUSL_GCC_VERSION}.tar.xz
|
||||
MUSL_GCC_X86_64_DOWNLOAD_URL="https://github.com/DragonOS-Community/musl-cross-make/releases/download/${MUSL_GCC_VERSION}-${MUSL_GCC_DATE}/${MUSL_GCC_X86_64_TAR}"
|
||||
MUSL_GCC_RISCV64_DOWNLOAD_URL="https://github.com/DragonOS-Community/musl-cross-make/releases/download/${MUSL_GCC_VERSION}-${MUSL_GCC_DATE}/${MUSL_GCC_RISCV64_TAR}"
|
||||
https://github.com/DragonOS-Community/musl-cross-make/releases/download/9.4.0-231114/riscv64-linux-musl-cross-gcc-9.4.0.tar.xz
|
||||
else
|
||||
echo "Download from mirrors.dragonos.org.cn"
|
||||
MUSL_GCC_X86_64_TAR="x86_64-linux-musl-cross-gcc-${MUSL_GCC_VERSION}-${MUSL_GCC_DATE}.tar.xz"
|
||||
@ -50,6 +56,7 @@ get_shell_rc_file()
|
||||
trap_handler(){
|
||||
rm -f $MUSL_GCC_X86_64_TAR
|
||||
rm -f $MUSL_GCC_RISCV64_TAR
|
||||
rm -f $LA64_GCC_TAR
|
||||
}
|
||||
|
||||
trap trap_handler EXIT
|
||||
@ -59,6 +66,20 @@ trap trap_handler SIGINT
|
||||
SHELL_RC=$(get_shell_rc_file)
|
||||
source $SHELL_RC
|
||||
|
||||
install_loongarch64_gcc()
|
||||
{
|
||||
echo "正在安装 loongarch64-unknown-linux-gnu 工具链"
|
||||
|
||||
wget ${LA64_GCC_DOWNLOAD_URL} || exit 1
|
||||
echo "正在解压 loongarch64-unknown-linux-gnu 工具链"
|
||||
tar xf $LA64_GCC_TAR -C $INSTALL_POS || exit 1
|
||||
echo "正在将 loongarch64-unknown-linux-gnu 工具链添加到 PATH 环境变量中"
|
||||
echo "export PATH=\$PATH:$INSTALL_POS/${LA64_GCC_VERSION}/bin" >> $SHELL_RC
|
||||
|
||||
echo "loongarch64-unknown-linux-gnu 工具链已成功安装!请运行 source $SHELL_RC 以使更改生效!"
|
||||
rm -rf $LA64_GCC_TAR || exit 1
|
||||
}
|
||||
|
||||
# 下载musl交叉编译工具链
|
||||
|
||||
# 如果x86_64-linux-musl-gcc或x86_64-linux-musl-g++不存在,则下载
|
||||
@ -68,7 +89,7 @@ if [ ! -n "$(which x86_64-linux-musl-gcc)" ] || [ ! -n "$(which x86_64-linux-mus
|
||||
echo "下载完成"
|
||||
echo "开始解压x86_64-linux-musl-gcc"
|
||||
tar xvf $MUSL_GCC_X86_64_TAR -C $INSTALL_POS || exit 1
|
||||
echo "PATH=\$PATH:$INSTALL_POS/x86_64-linux-musl-cross-gcc-${MUSL_GCC_VERSION}/bin" >> $SHELL_RC
|
||||
echo "export PATH=\$PATH:$INSTALL_POS/x86_64-linux-musl-cross-gcc-${MUSL_GCC_VERSION}/bin" >> $SHELL_RC
|
||||
echo "安装完成"
|
||||
echo "开始清理x86_64-linux-musl-gcc的下载缓存"
|
||||
rm -rf $MUSL_GCC_X86_64_TAR || exit 1
|
||||
@ -93,6 +114,13 @@ else
|
||||
echo "riscv64-linux-musl-gcc已经安装"
|
||||
fi
|
||||
|
||||
if [ ! -n "$(which loongarch64-unknown-linux-gnu-gcc)" ] || [ ! -n "$(which loongarch64-unknown-linux-gnu-g++)" ]; then
|
||||
install_loongarch64_gcc || exit 1
|
||||
else
|
||||
echo "loongarch64-unknown-linux-gnu-gcc已经安装"
|
||||
fi
|
||||
|
||||
|
||||
source $SHELL_RC
|
||||
|
||||
echo "musl交叉编译工具链安装完成,请运行 source $SHELL_RC 以使musl交叉编译工具链在当前窗口生效!"
|
3
tools/qemu/.gitignore
vendored
Normal file
3
tools/qemu/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/source_packages
|
||||
/build_dir
|
||||
*.log
|
155
tools/qemu/build-qemu-la64-for-ubuntu.sh
Executable file
155
tools/qemu/build-qemu-la64-for-ubuntu.sh
Executable file
@ -0,0 +1,155 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
# 默认参数
|
||||
QEMU_VERSION="9.2.1"
|
||||
TARGET_LIST="loongarch64-softmmu"
|
||||
USE_MIRROR=0
|
||||
DEST_DIR="${HOME}/opt/qemu-${QEMU_VERSION}"
|
||||
SOURCE_PACKAGES_DIR="$SCRIPT_DIR/source_packages"
|
||||
BUILD_DIR="$SCRIPT_DIR/build_dir"
|
||||
|
||||
SUDO=sudo
|
||||
FORCE=0
|
||||
|
||||
# 检查是否为root用户
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
SUDO=""
|
||||
fi
|
||||
|
||||
# 参数解析
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--version)
|
||||
QEMU_VERSION="$2"
|
||||
shift 2
|
||||
DEST_DIR="${HOME}/opt/qemu-${QEMU_VERSION}" # 更新默认路径
|
||||
;;
|
||||
--target-list)
|
||||
TARGET_LIST="$2"
|
||||
shift 2
|
||||
;;
|
||||
--use-mirror)
|
||||
USE_MIRROR=1
|
||||
shift
|
||||
;;
|
||||
--dest-dir)
|
||||
DEST_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
-f|--force)
|
||||
FORCE=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "未知参数: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 检查是否已存在qemu-system-loongarch64
|
||||
QEMU_BINARY="${DEST_DIR}/bin/qemu-system-loongarch64"
|
||||
if [ -f "$QEMU_BINARY" ] && [ "$FORCE" -eq 0 ]; then
|
||||
echo "检测到已存在 qemu-system-loongarch64 在 ${QEMU_BINARY}"
|
||||
echo "如需强制重新构建,请使用 -f 或 --force 参数"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 依赖检查函数
|
||||
check_dependency() {
|
||||
if ! dpkg -l | grep -q "^ii $1 "; then
|
||||
echo "安装依赖: $1"
|
||||
${SUDO} apt-get install -y "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# 镜像源设置
|
||||
if [[ $USE_MIRROR -eq 1 ]]; then
|
||||
echo "使用国内镜像源..."
|
||||
# APT镜像
|
||||
${SUDO} sed -i \
|
||||
's|//.*archive.ubuntu.com|//mirrors.ustc.edu.cn|g' \
|
||||
/etc/apt/sources.list
|
||||
|
||||
# PyPI镜像
|
||||
PIP_MIRROR="https://pypi.mirrors.ustc.edu.cn/simple"
|
||||
else
|
||||
PIP_MIRROR="https://pypi.org/simple"
|
||||
fi
|
||||
|
||||
# 更新源
|
||||
${SUDO} apt-get update
|
||||
|
||||
# 安装基础依赖
|
||||
check_dependency build-essential
|
||||
check_dependency ninja-build
|
||||
check_dependency meson
|
||||
check_dependency pkg-config
|
||||
check_dependency libglib2.0-dev
|
||||
check_dependency libslirp-dev
|
||||
check_dependency wget
|
||||
check_dependency git
|
||||
|
||||
# Python环境配置
|
||||
if ! command -v python3 &> /dev/null; then
|
||||
${SUDO} apt-get install -y python3 python3-pip
|
||||
elif ! command -v pip3 &> /dev/null; then
|
||||
${SUDO} apt-get install -y python3-pip
|
||||
fi
|
||||
|
||||
if ! pip3 show tomli &> /dev/null; then
|
||||
pip3 install --user -i $PIP_MIRROR tomli
|
||||
fi
|
||||
|
||||
# 创建目录结构
|
||||
mkdir -p "$DEST_DIR"
|
||||
mkdir -p $SOURCE_PACKAGES_DIR
|
||||
mkdir -p $BUILD_DIR
|
||||
|
||||
# 下载源码包
|
||||
QEMU_TAR="qemu-${QEMU_VERSION}.tar.xz"
|
||||
QEMU_SRC_DIR="$SOURCE_PACKAGES_DIR/qemu-${QEMU_VERSION}"
|
||||
|
||||
if [ ! -f "$SOURCE_PACKAGES_DIR/${QEMU_TAR}" ]; then
|
||||
echo "正在下载QEMU源码包..."
|
||||
wget "https://download.qemu.org/${QEMU_TAR}" -O "$SOURCE_PACKAGES_DIR/${QEMU_TAR}"
|
||||
fi
|
||||
|
||||
# 解压源码
|
||||
if [ ! -d "${QEMU_SRC_DIR}" ]; then
|
||||
echo "解压QEMU源码..."
|
||||
tar xf "$SOURCE_PACKAGES_DIR/${QEMU_TAR}" -C $SOURCE_PACKAGES_DIR
|
||||
fi
|
||||
|
||||
# 配置构建目录
|
||||
BUILD_DIR="$BUILD_DIR/qemu-${QEMU_VERSION}_${TARGET_LIST//,/}"
|
||||
mkdir -p "${BUILD_DIR}"
|
||||
|
||||
pushd $(pwd)
|
||||
|
||||
cd "${BUILD_DIR}"
|
||||
|
||||
# 运行配置
|
||||
echo "配置编译参数..."
|
||||
"${QEMU_SRC_DIR}/configure" \
|
||||
--prefix="$DEST_DIR" \
|
||||
--enable-slirp \
|
||||
--target-list="$TARGET_LIST" \
|
||||
--enable-kvm
|
||||
|
||||
# 编译和安装
|
||||
echo "开始编译(使用$(nproc)线程)..."
|
||||
make -j "$(nproc)"
|
||||
make install
|
||||
|
||||
popd
|
||||
# 清理
|
||||
rm -rf "./${BUILD_DIR}"
|
||||
rm -rf "${QEMU_SRC_DIR}"
|
||||
|
||||
echo -e "\n编译完成!安装路径: ${DEST_DIR}"
|
||||
echo -e "运行以下命令使用QEMU:"
|
||||
echo -e " 或者将其添加到你的shell配置文件中(例如~/.bashrc或~/.zshrc):"
|
||||
echo "export PATH=\"${DEST_DIR}/bin:\$PATH\""
|
36
tools/run-qemu.sh
Normal file → Executable file
36
tools/run-qemu.sh
Normal file → Executable file
@ -6,6 +6,16 @@ check_dependencies()
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$(which ${QEMU})" ]; then
|
||||
if [ "$ARCH" == "loongarch64" ]; then
|
||||
echo -e "\nPlease install qemu-system-loongarch64 first!"
|
||||
echo -e "\nYou can install it by running: (if you are using ubuntu)"
|
||||
echo -e " ${ROOT_PATH}/tools/qemu/build-qemu-la64-for-ubuntu.sh"
|
||||
echo -e ""
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if brctl is installed
|
||||
if [ -z "$(which brctl)" ]; then
|
||||
echo "Please install bridge-utils first!"
|
||||
@ -26,7 +36,6 @@ check_dependencies()
|
||||
|
||||
}
|
||||
|
||||
check_dependencies
|
||||
|
||||
# 进行启动前检查
|
||||
flag_can_run=1
|
||||
@ -38,6 +47,8 @@ allflags=
|
||||
# 设置ARCH环境变量,如果没有设置,就默认为x86_64
|
||||
export ARCH=${ARCH:=x86_64}
|
||||
echo "ARCH=${ARCH}"
|
||||
|
||||
|
||||
#ARCH="i386"
|
||||
# 请根据自己的需要,在-d 后方加入所需的 trace 事件
|
||||
|
||||
@ -67,7 +78,7 @@ RISCV64_UBOOT_PATH="arch/riscv64/u-boot-${UBOOT_VERSION}-riscv64"
|
||||
|
||||
DISK_NAME="disk-image-${ARCH}.img"
|
||||
|
||||
QEMU=qemu-system-${ARCH}
|
||||
QEMU=$(which qemu-system-${ARCH})
|
||||
QEMU_DISK_IMAGE="../bin/${DISK_NAME}"
|
||||
QEMU_MEMORY="512M"
|
||||
QEMU_MEMORY_BACKEND="dragonos-qemu-shm.ram"
|
||||
@ -85,6 +96,9 @@ QEMU_ACCELARATE=""
|
||||
QEMU_ARGUMENT=" -no-reboot "
|
||||
QEMU_DEVICES=""
|
||||
|
||||
|
||||
check_dependencies
|
||||
|
||||
# 设置无图形界面模式
|
||||
QEMU_NOGRAPHIC=false
|
||||
|
||||
@ -93,6 +107,7 @@ KERNEL_CMDLINE=" "
|
||||
BIOS_TYPE=""
|
||||
#这个变量为true则使用virtio磁盘
|
||||
VIRTIO_BLK_DEVICE=true
|
||||
|
||||
# 如果qemu_accel不为空
|
||||
if [ -n "${qemu_accel}" ]; then
|
||||
QEMU_ACCELARATE=" -machine accel=${qemu_accel} "
|
||||
@ -111,10 +126,15 @@ if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then
|
||||
QEMU_DEVICES_DISK="-device virtio-blk-pci,drive=disk -device pci-bridge,chassis_nr=1,id=pci.1 -device pcie-root-port "
|
||||
fi
|
||||
|
||||
else
|
||||
elif [ ${ARCH} == "riscv64" ]; then
|
||||
QEMU_MACHINE=" -machine virt,memory-backend=${QEMU_MEMORY_BACKEND} -cpu sifive-u54 "
|
||||
QEMU_DEVICES_DISK="-device virtio-blk-device,drive=disk "
|
||||
|
||||
elif [ ${ARCH} == "loongarch64" ]; then
|
||||
QEMU_MACHINE=" -machine virt"
|
||||
QEMU_DEVICES_DISK="-device virtio-blk-pci,drive=disk -device pci-bridge,chassis_nr=1,id=pci.1 -device pcie-root-port "
|
||||
else
|
||||
echo "Unsupported architecture: ${ARCH}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ${ARCH} == "riscv64" ]; then
|
||||
@ -153,7 +173,9 @@ if [ ${QEMU_NOGRAPHIC} == true ]; then
|
||||
QEMU_SERIAL=" -serial chardev:mux -monitor chardev:mux -chardev stdio,id=mux,mux=on,signal=off,logfile=${QEMU_SERIAL_LOG_FILE} "
|
||||
|
||||
# 添加 virtio console 设备
|
||||
if [${ARCH} == "x86_64" ]; then
|
||||
if [ ${ARCH} == "x86_64" ]; then
|
||||
QEMU_DEVICES+=" -device virtio-serial -device virtconsole,chardev=mux "
|
||||
elif [ ${ARCH} == "loongarch64" ]; then
|
||||
QEMU_DEVICES+=" -device virtio-serial -device virtconsole,chardev=mux "
|
||||
elif [ ${ARCH} == "riscv64" ]; then
|
||||
QEMU_DEVICES+=" -device virtio-serial-device -device virtconsole,chardev=mux "
|
||||
@ -165,6 +187,8 @@ if [ ${QEMU_NOGRAPHIC} == true ]; then
|
||||
|
||||
if [ ${ARCH} == "x86_64" ]; then
|
||||
QEMU_ARGUMENT+=" -kernel ../bin/kernel/kernel.elf "
|
||||
elif [ ${ARCH} == "loongarch64" ]; then
|
||||
QEMU_ARGUMENT+=" -kernel ../bin/kernel/kernel.elf "
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -245,6 +269,8 @@ else
|
||||
# 如果是riscv64架构,就与efi启动一样
|
||||
install_riscv_uboot
|
||||
sudo ${QEMU} -kernel ${RISCV64_UBOOT_PATH}/u-boot.bin ${QEMU_ARGUMENT} -append "${KERNEL_CMDLINE}"
|
||||
elif [ ${ARCH} == loongarch64 ] ;then
|
||||
sudo ${QEMU} ${QEMU_ARGUMENT}
|
||||
else
|
||||
echo "不支持的架构: ${ARCH}"
|
||||
fi
|
||||
|
0
tools/write_disk_image.sh
Normal file → Executable file
0
tools/write_disk_image.sh
Normal file → Executable file
@ -2,7 +2,7 @@ user_sub_dirs = apps
|
||||
|
||||
DADK_VERSION=$(shell dadk -V | awk 'END {print $$2}')
|
||||
# 最小的DADK版本
|
||||
MIN_DADK_VERSION = 0.2.0
|
||||
MIN_DADK_VERSION = 0.3.0
|
||||
DADK_CACHE_DIR = $(ROOT_PATH)/bin/dadk_cache
|
||||
|
||||
ECHO:
|
||||
@ -17,7 +17,7 @@ ifeq ("$(DADK_VERSION)", "")
|
||||
@echo "\nYou can install dadk by running the following command:"
|
||||
@echo "\n\tcargo install dadk"
|
||||
@echo "\nOr you can install dadk from source by running the following command:"
|
||||
@echo "\n\tcargo install --git https://git.mirrors.dragonos.org.cn/DragonOS-Community/DADK.git --tag v$(MIN_DADK_VERSION)"
|
||||
@echo "\n\tcargo install --git https://git.mirrors.dragonos.org.cn/DragonOS-Community/DADK.git --tag v$(MIN_DADK_VERSION)" --locked
|
||||
@echo "\n"
|
||||
@echo "Auto installing dadk..."
|
||||
cargo install dadk
|
||||
@ -28,7 +28,7 @@ else
|
||||
ifneq ($(shell printf '%s\n%s' "$(DADK_VERSION)" "$(MIN_DADK_VERSION)" | sort -V | head -n1), $(MIN_DADK_VERSION))
|
||||
@echo "dadk version is too low, please update to $(MIN_DADK_VERSION) or higher version"
|
||||
@echo "Updating dadk..."
|
||||
cargo install --git https://git.mirrors.dragonos.org.cn/DragonOS-Community/DADK.git --tag v$(MIN_DADK_VERSION) || (echo "dadk update failed" && exit 1)
|
||||
cargo install --git https://git.mirrors.dragonos.org.cn/DragonOS-Community/DADK.git --tag v$(MIN_DADK_VERSION) --locked || (echo "dadk update failed" && exit 1)
|
||||
@echo "dadk updated"
|
||||
endif
|
||||
endif
|
||||
|
Reference in New Issue
Block a user