Replace bootloader with limine

This commit is contained in:
Yuke Peng 2023-03-05 22:19:23 -08:00 committed by Tate, Hongliang Tian
parent 78e72fd94a
commit 0435902579
21 changed files with 364 additions and 214 deletions

View File

@ -4,15 +4,15 @@ version = "0.1.0"
edition = "2021"
[dependencies]
bootloader = {version="0.10.12"}
jinux-frame = {path = "framework/jinux-frame"}
jinux-std = {path = "services/libs/jinux-std"}
component = {path = "services/comp-sys/component"}
limine = "0.1.10"
jinux-frame = { path = "framework/jinux-frame" }
jinux-std = { path = "services/libs/jinux-std" }
component = { path = "services/comp-sys/component" }
[workspace]
members = [
"jinux-boot",
"boot",
"framework/jinux-frame",
"framework/pod",
"framework/pod-derive",
@ -28,11 +28,5 @@ members = [
"services/libs/cpio-decoder",
]
exclude = [
"services/comp-sys/controlled",
"services/comp-sys/cargo-component",
]
exclude = ["services/comp-sys/controlled", "services/comp-sys/cargo-component"]
[package.metadata.bootloader]
map-physical-memory = true
physical-memory-offset = "0xFFFF800000000000"

View File

@ -5,7 +5,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bootloader-locator = "0.0.4" # for locating the `bootloader` dependency on disk
locate-cargo-manifest = "0.2.0" # for locating the kernel's `Cargo.toml`
runner-utils = "0.0.2"
anyhow = "1.0.32"
[features]
default = ["limine"]
limine= []

View File

@ -0,0 +1,18 @@
# For a detailed description of the limine.cfg format, see CONFIG.md in the Limine repo:
# https://github.com/limine-bootloader/limine/blob/trunk/CONFIG.md
TIMEOUT=1
SERIAL=yes
VERBOSE=yes
# The name of kernel
: Jinux
PROTOCOL=limine
# Tell Limine where to look for the kernel.
# The runner (.cargo/runner.sh) will use the name of the package from Cargo.toml,
# so change this path if you change that.
KERNEL_PATH=boot:///jinux
# The path to the module
MODULE_PATH=boot:///ramdisk.cpio

View File

@ -0,0 +1,81 @@
ENTRY(_start)
OUTPUT_ARCH(i386:x86-64)
OUTPUT_FORMAT(elf64-x86-64)
KERNEL_BASE = 0xffffffff80000000;
SECTIONS {
. = KERNEL_BASE + SIZEOF_HEADERS;
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rela : { *(.rela*) }
.rodata : { *(.rodata .rodata.*) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.eh_frame_hdr : {
PROVIDE(__eh_frame_hdr = .);
KEEP(*(.eh_frame_hdr))
PROVIDE(__eh_frame_hdr_end = .);
}
.eh_frame : {
PROVIDE(__eh_frame = .);
KEEP(*(.eh_frame))
PROVIDE(__eh_frame_end = .);
}
.gcc_except_table : { KEEP(*(.gcc_except_table .gcc_except_table.*)) }
. += CONSTANT(MAXPAGESIZE);
.plt : { *(.plt .plt.*) }
.text : { *(.text .text.*) }
. += CONSTANT(MAXPAGESIZE);
.tdata : { *(.tdata .tdata.*) }
.tbss : { *(.tbss .tbss.*) }
.data.rel.ro : { *(.data.rel.ro .data.rel.ro.*) }
.dynamic : { *(.dynamic) }
. = ALIGN(4K);
sinit_array = .;
.init_array : {
*(.init_array .init_array.*)
}
einit_array = .;
. = DATA_SEGMENT_RELRO_END(0, .);
.got : { *(.got .got.*) }
.got.plt : { *(.got.plt .got.plt.*) }
.data : { *(.data .data.*) }
.bss : { *(.bss .bss.*) *(COMMON) }
. = DATA_SEGMENT_END(.);
.comment 0 : { *(.comment) }
.debug 0 : { *(.debug) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_frame 0 : { *(.debug_frame) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_line 0 : { *(.debug_line) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_str 0 : { *(.debug_str) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.debug_weaknames 0 : { *(.debug_weaknames) }
.line 0 : { *(.line) }
.shstrtab 0 : { *(.shstrtab) }
.strtab 0 : { *(.strtab) }
.symtab 0 : { *(.symtab) }
}

View File

@ -0,0 +1,37 @@
#! /bin/sh
set -xe
LIMINE_GIT_URL="https://github.com/limine-bootloader/limine.git"
# Cargo passes the path to the built executable as the first argument.
KERNEL=$1
# Clone the `limine` repository if we don't have it yet.
if [ ! -d target/limine ]; then
git clone $LIMINE_GIT_URL --depth=1 --branch v4.x-branch-binary target/limine
fi
cd target/limine
make
cd -
# Copy the needed files into an ISO image.
mkdir -p target/iso_root
cp $KERNEL boot/limine/conf/limine.cfg target/iso_root
cp target/limine/limine.sys target/iso_root
cp target/limine/limine-cd.bin target/iso_root
cp target/limine/limine-cd-efi.bin target/iso_root
# Copy ramdisk
cp ramdisk/build/ramdisk.cpio target/iso_root
xorriso -as mkisofs \
-b limine-cd.bin \
-no-emul-boot -boot-load-size 4 -boot-info-table \
--efi-boot limine-cd-efi.bin \
-efi-boot-part --efi-boot-image --protective-msdos-label \
target/iso_root -o $KERNEL.iso
# For the image to be bootable on BIOS systems, we must run `limine-deploy` on it.
target/limine/limine-deploy $KERNEL.iso

View File

@ -25,7 +25,7 @@ const RUN_ARGS: &[&str] = &["-s"];
const TEST_ARGS: &[&str] = &[];
const TEST_TIMEOUT_SECS: u64 = 10;
fn main() -> anyhow::Result<()> {
let mut args = std::env::args().skip(1); // skip executable name
let mut args = std::env::args().skip(1);
let kernel_binary_path = {
let path = PathBuf::from(args.next().unwrap());
path.canonicalize().unwrap()
@ -40,25 +40,31 @@ fn main() -> anyhow::Result<()> {
false
};
let bios = create_disk_images(&kernel_binary_path);
#[cfg(feature = "limine")]
call_limine_build_script(&kernel_binary_path).unwrap();
// add .iso
let kernel_iso_path = {
let a = kernel_binary_path.parent().unwrap();
a.join("jinux.iso")
};
// let bios = create_disk_images(&kernel_binary_path);
if no_boot {
println!("Created disk image at `{}`", bios.display());
println!("Created disk image at `{}`", kernel_iso_path.display());
return Ok(());
}
#[cfg(windows)]
let mut run_cmd = Command::new("qemu-system-x86_64.exe");
#[cfg(not(windows))]
let mut run_cmd = Command::new("qemu-system-x86_64");
run_cmd
.arg("-drive")
.arg(format!("format=raw,file={}", bios.display()));
let binary_kind = runner_utils::binary_kind(&kernel_binary_path);
let mut args = COMMON_ARGS.clone().to_vec();
args.push("-drive");
let binding = create_fs_image(kernel_binary_path.as_path())?;
args.push(binding.as_str());
run_cmd.arg(kernel_iso_path.to_str().unwrap());
if binary_kind.is_test() {
args.append(&mut TEST_ARGS.to_vec());
run_cmd.args(args);
@ -80,6 +86,16 @@ fn main() -> anyhow::Result<()> {
Ok(())
}
fn call_limine_build_script(path: &PathBuf) -> anyhow::Result<()> {
let mut cmd = Command::new("boot/limine/scripts/limine-build.sh");
cmd.arg(path.to_str().unwrap());
let exit_status = cmd.status()?;
if !exit_status.success() {
std::process::exit(exit_status.code().unwrap_or(1));
}
Ok(())
}
fn create_fs_image(path: &Path) -> anyhow::Result<String> {
let mut fs_img_path = path.parent().unwrap().to_str().unwrap().to_string();
#[cfg(windows)]
@ -106,46 +122,6 @@ fn create_fs_image(path: &Path) -> anyhow::Result<String> {
))
}
pub fn create_disk_images(kernel_binary_path: &Path) -> PathBuf {
let bootloader_manifest_path = bootloader_locator::locate_bootloader("bootloader").unwrap();
let kernel_manifest_path = locate_cargo_manifest::locate_manifest().unwrap();
let mut build_cmd = Command::new(env!("CARGO"));
build_cmd.current_dir(bootloader_manifest_path.parent().unwrap());
build_cmd.arg("builder");
build_cmd
.arg("--kernel-manifest")
.arg(&kernel_manifest_path);
build_cmd.arg("--kernel-binary").arg(&kernel_binary_path);
build_cmd
.arg("--target-dir")
.arg(kernel_manifest_path.parent().unwrap().join("target"));
build_cmd
.arg("--out-dir")
.arg(kernel_binary_path.parent().unwrap());
build_cmd.arg("--quiet");
// println!("current dir = {:?}", build_cmd.get_current_dir());
// println!("args = {:?}", build_cmd.get_args());
if !build_cmd.status().unwrap().success() {
panic!("build failed");
}
let kernel_binary_name = kernel_binary_path.file_name().unwrap().to_str().unwrap();
let disk_image = kernel_binary_path
.parent()
.unwrap()
.join(format!("boot-bios-{}.img", kernel_binary_name));
if !disk_image.exists() {
panic!(
"Disk image does not exist at {} after bootloader build",
disk_image.display()
);
}
disk_image
}
fn run_test_command(mut cmd: Command) -> anyhow::Result<ExitStatus> {
let status = runner_utils::run_with_timeout(&mut cmd, Duration::from_secs(TEST_TIMEOUT_SECS))?;
Ok(status)

20
src/build.rs Normal file
View File

@ -0,0 +1,20 @@
use std::{env, error::Error};
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
limine_build_script()?;
Ok(())
}
fn limine_build_script() -> Result<(), Box<dyn Error + Send + Sync>> {
// Get the name of the package.
let kernel_name = env::var("CARGO_PKG_NAME")?;
// Tell rustc to pass the linker script to the linker.
println!("cargo:rustc-link-arg-bin={kernel_name}=--script=boot/limine/conf/linker.ld");
// Have cargo rerun this script if the linker script or CARGO_PKG_ENV changes.
println!("cargo:rerun-if-changed=boot/limine/conf/linker.ld");
println!("cargo:rerun-if-env-changed=CARGO_PKG_NAME");
Ok(())
}

View File

@ -9,23 +9,20 @@ edition = "2021"
bitflags = "1.3"
x86_64 = "0.14.2"
spin = "0.9.4"
volatile = {version="0.4.5", features = ["unstable"] }
volatile = { version = "0.4.5", features = ["unstable"] }
buddy_system_allocator = "0.6"
linked_list_allocator = "0.9.0"
bootloader = {version="0.10.12"}
font8x8 = { version = "0.2.5", default-features = false, features = ["unicode"]}
font8x8 = { version = "0.2.5", default-features = false, features = [
"unicode",
] }
uart_16550 = "0.2.0"
pod = {path = "../pod"}
acpi= "4.1.1"
pod = { path = "../pod" }
acpi = "4.1.1"
intrusive-collections = "0.9.5"
log= "0.4"
[dependencies.lazy_static]
version = "1.0"
features = ["spin_no_std"]
log = "0.4"
limine = { version = "0.1.10", features = ["into-uuid"] }
lazy_static = { version = "1.0", features = ["spin_no_std"] }
[features]
default = ["serial_print"]
serial_print = []

View File

@ -0,0 +1,26 @@
use crate::config::{self, PAGE_SIZE};
use limine::{LimineBootInfoRequest, LimineHhdmRequest, LimineStackSizeRequest};
use log::info;
pub(crate) fn init() {
if let Some(bootinfo) = BOOTLOADER_INFO_REQUEST.get_response().get() {
info!(
"booted by {} v{}",
bootinfo.name.to_str().unwrap().to_str().unwrap(),
bootinfo.version.to_str().unwrap().to_str().unwrap(),
);
}
let response = HHDM_REQUEST
.get_response()
.get()
.expect("Not found HHDM Features");
assert_eq!(config::PHYS_OFFSET as u64, response.offset);
}
static BOOTLOADER_INFO_REQUEST: LimineBootInfoRequest = LimineBootInfoRequest::new(0);
static HHDM_REQUEST: LimineHhdmRequest = LimineHhdmRequest::new(0);
static STACK_REQUEST: LimineStackSizeRequest = {
let a = LimineStackSizeRequest::new(0);
// 64 * 4096(PAGE_SIZE)
a.stack_size(64 * PAGE_SIZE as u64)
};

View File

@ -0,0 +1,9 @@
mod limine;
pub(crate) const MEMORY_MAP_MAX_COUNT: usize = 30;
pub(crate) const MODULE_MAX_COUNT: usize = 10;
/// init bootloader
pub(crate) fn init() {
limine::init();
}

View File

@ -6,7 +6,8 @@ pub const USER_STACK_SIZE: usize = PAGE_SIZE * 4;
pub const KERNEL_STACK_SIZE: usize = PAGE_SIZE * 64;
pub const KERNEL_HEAP_SIZE: usize = 0x2_000_000;
pub const KERNEL_OFFSET: usize = 0xffffff00_00000000;
pub const KERNEL_OFFSET: usize = 0xffffffff80000000;
pub const PHYS_OFFSET: usize = 0xFFFF800000000000;
pub const ENTRY_COUNT: usize = 512;

View File

@ -1,17 +1,45 @@
use bootloader::boot_info::PixelFormat;
use alloc::slice;
use core::fmt;
use font8x8::UnicodeFonts;
use limine::{LimineFramebufferRequest, LimineMemoryMapEntryType};
use spin::Mutex;
use volatile::Volatile;
pub(crate) static WRITER: Mutex<Option<Writer>> = Mutex::new(None);
use crate::mm;
pub fn init(framebuffer: &'static mut bootloader::boot_info::FrameBuffer) {
let mut writer = Writer {
info: framebuffer.info(),
buffer: Volatile::new(framebuffer.buffer_mut()),
pub(crate) static WRITER: Mutex<Option<Writer>> = Mutex::new(None);
static FRAMEBUFFER_REUEST: LimineFramebufferRequest = LimineFramebufferRequest::new(0);
pub(crate) fn init() {
let mut writer = {
let response = FRAMEBUFFER_REUEST
.get_response()
.get()
.expect("Not found framebuffer");
assert_eq!(response.framebuffer_count, 1);
let mut writer = None;
let mut size = 0;
for i in mm::MEMORY_REGIONS.get().unwrap().iter() {
if i.typ == LimineMemoryMapEntryType::Framebuffer {
size = i.len as usize;
}
}
for i in response.framebuffers() {
let buffer_mut = unsafe {
let start = i.address.as_ptr().unwrap().addr();
slice::from_raw_parts_mut(start as *mut u8, size)
};
writer = Some(Writer {
buffer: Volatile::new(buffer_mut),
x_pos: 0,
y_pos: 0,
bytes_per_pixel: i.bpp as usize,
width: i.width as usize,
height: i.height as usize,
})
}
writer.unwrap()
};
writer.clear();
@ -23,7 +51,11 @@ pub fn init(framebuffer: &'static mut bootloader::boot_info::FrameBuffer) {
pub(crate) struct Writer {
buffer: Volatile<&'static mut [u8]>,
info: bootloader::boot_info::FrameBufferInfo,
bytes_per_pixel: usize,
width: usize,
height: usize,
x_pos: usize,
y_pos: usize,
}
@ -46,17 +78,17 @@ impl Writer {
}
fn shift_lines_up(&mut self) {
let offset = self.info.stride * self.info.bytes_per_pixel * 8;
let offset = self.bytes_per_pixel * 8;
self.buffer.copy_within(offset.., 0);
self.y_pos -= 8;
}
fn width(&self) -> usize {
self.info.horizontal_resolution
self.width
}
fn height(&self) -> usize {
self.info.vertical_resolution
self.height
}
fn write_char(&mut self, c: char) {
@ -89,17 +121,13 @@ impl Writer {
}
fn write_pixel(&mut self, x: usize, y: usize, on: bool) {
let pixel_offset = y * self.info.stride + x;
let pixel_offset = y + x;
let color = if on {
match self.info.pixel_format {
PixelFormat::RGB => [0x33, 0xff, 0x66, 0],
PixelFormat::BGR => [0x66, 0xff, 0x33, 0],
_other => [0xff, 0xff, 0xff, 0],
}
[0x33, 0xff, 0x66, 0]
} else {
[0, 0, 0, 0]
};
let bytes_per_pixel = self.info.bytes_per_pixel;
let bytes_per_pixel = self.bytes_per_pixel;
let byte_offset = pixel_offset * bytes_per_pixel;
self.buffer
.index_mut(byte_offset..(byte_offset + bytes_per_pixel))

View File

@ -7,13 +7,8 @@ pub mod serial;
pub use self::io_port::IoPort;
/// first step to init device, call before the memory allocator init
pub(crate) fn first_init(framebuffer: &'static mut bootloader::boot_info::FrameBuffer) {
framebuffer::init(framebuffer);
serial::init();
}
/// second step to init device, call after the memory allocator init
pub(crate) fn second_init() {
/// Call after the memory allocator init
pub(crate) fn init() {
framebuffer::init();
serial::register_serial_input_irq_handler(|trap| {});
}

View File

@ -1,8 +1,9 @@
use core::ptr::NonNull;
use crate::mm::address::phys_to_virt;
use crate::{config, mm::address::phys_to_virt};
use acpi::{AcpiHandler, AcpiTables};
use lazy_static::lazy_static;
use limine::LimineRsdpRequest;
use log::info;
use spin::Mutex;
@ -34,12 +35,19 @@ impl AcpiHandler for AcpiMemoryHandler {
fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) {}
}
pub fn init(rsdp: u64) {
let a = unsafe { AcpiTables::from_rsdp(AcpiMemoryHandler {}, rsdp as usize).unwrap() };
*ACPI_TABLES.lock() = a;
static RSDP_REQUEST: LimineRsdpRequest = LimineRsdpRequest::new(0);
let c = ACPI_TABLES.lock();
for (signature, sdt) in c.sdts.iter() {
pub fn init() {
let response = RSDP_REQUEST
.get_response()
.get()
.expect("Need RSDP address");
let rsdp = response.address.as_ptr().unwrap().addr() - config::PHYS_OFFSET;
*ACPI_TABLES.lock() =
unsafe { AcpiTables::from_rsdp(AcpiMemoryHandler {}, rsdp as usize).unwrap() };
let lock = ACPI_TABLES.lock();
for (signature, sdt) in lock.sdts.iter() {
info!("ACPI found signature:{:?}", signature);
}
info!("acpi init complete");

View File

@ -14,8 +14,8 @@ use log::info;
pub use timer::TimerCallback;
pub(crate) use timer::{add_timeout_list, TICK};
pub(crate) fn init(rsdp: Option<u64>) {
acpi::init(rsdp.unwrap());
pub(crate) fn init() {
acpi::init();
timer::init();
if apic::has_apic() {
ioapic::init();

View File

@ -9,9 +9,11 @@
#![feature(core_intrinsics)]
#![feature(new_uninit)]
#![feature(link_llvm_intrinsics)]
#![feature(strict_provenance)]
extern crate alloc;
mod boot;
pub(crate) mod cell;
pub mod config;
pub mod cpu;
@ -31,21 +33,13 @@ mod util;
pub mod vm;
pub(crate) mod x86_64_util;
use core::{mem, panic::PanicInfo};
pub use driver::ack as apic_ack;
pub use self::error::Error;
pub use self::prelude::Result;
pub(crate) use self::sync::up::UPSafeCell;
pub use trap::interrupt_ack;
pub use x86_64_util::{disable_interrupts, enable_interrupts, hlt};
use alloc::vec::Vec;
use bootloader::{
boot_info::{FrameBuffer, MemoryRegionKind},
BootInfo,
};
use core::{mem, panic::PanicInfo};
pub use device::serial::receive_char;
pub use limine::LimineModuleRequest;
pub use mm::address::{align_down, align_up, is_aligned, virt_to_phys};
pub use mm::page_table::translate_not_offset_virtual_address;
pub use trap::{allocate_irq, IrqAllocateHandle, TrapFrame};
@ -54,6 +48,7 @@ pub use util::AlignExt;
pub use x86_64::registers::rflags::read as get_rflags;
pub use x86_64::registers::rflags::RFlags;
use x86_64_util::enable_common_cpu_features;
pub use x86_64_util::{disable_interrupts, enable_interrupts, hlt};
static mut IRQ_CALLBACK_LIST: Vec<IrqCallbackHandle> = Vec::new();
@ -67,40 +62,26 @@ pub use crate::console_print as print;
#[cfg(feature = "serial_print")]
pub use crate::console_println as println;
pub fn init(boot_info: &'static mut BootInfo) {
pub fn init() {
device::serial::init();
logger::init();
let siz = boot_info.framebuffer.as_ref().unwrap() as *const FrameBuffer as usize;
let mut memory_init = false;
// memory
device::first_init(boot_info.framebuffer.as_mut().unwrap());
device::framebuffer::WRITER.lock().as_mut().unwrap().clear();
for region in boot_info.memory_regions.iter() {
if region.kind == MemoryRegionKind::Usable {
let start: u64 = region.start;
let size: u64 = region.end - region.start;
println!(
"[kernel] physical frames start = {:x}, size = {:x}",
start, size
);
mm::init(start, size);
memory_init = true;
break;
}
}
if !memory_init {
panic!("memory init failed");
}
boot::init();
mm::init();
trap::init();
device::second_init();
driver::init(boot_info.rsdp_addr.into_option());
device::init();
driver::init();
enable_common_cpu_features();
register_irq_common_callback();
invoke_c_init_funcs();
}
fn register_irq_common_callback() {
unsafe {
for i in 0..256 {
IRQ_CALLBACK_LIST.push(IrqLine::acquire(i as u8).on_active(general_handler))
}
let value = x86_64_util::cpuid(1);
}
invoke_c_init_funcs();
}
fn invoke_c_init_funcs() {

View File

@ -1,40 +0,0 @@
ENTRY(_start)
KERNEL_BEGIN = 0xffffff0000000000;
SECTIONS {
. = KERNEL_BEGIN;
.rodata ALIGN(4K): {
*(.rodata .rodata.*)
}
.got ALIGN(4K):{
*(.got .got.*)
}
. = ALIGN(4K);
sinit_array = .;
.init_array : {
*(.init_array .init_array.*)
}
einit_array = .;
.text ALIGN(4K): {
*(.text .text.*)
}
.data ALIGN(4K): {
*(.data .data.*)
*(.sdata .sdata.*)
}
.got ALIGN(4K): {
*(.got .got.*)
}
.bss ALIGN(4K): {
*(.bss .bss.*)
*(.sbss .sbss.*)
}
}

View File

@ -6,16 +6,18 @@ mod heap_allocator;
mod memory_set;
pub(crate) mod page_table;
use core::sync::atomic::AtomicUsize;
pub use self::{
frame_allocator::PhysFrame,
memory_set::{MapArea, MemorySet},
page_table::PageTable,
};
use address::PhysAddr;
use address::VirtAddr;
use crate::x86_64_util;
pub use self::{frame_allocator::*, memory_set::*, page_table::*};
pub(crate) static ORIGINAL_CR3: AtomicUsize = AtomicUsize::new(0);
use alloc::vec::Vec;
use limine::LimineMemmapRequest;
use log::debug;
use spin::Once;
bitflags::bitflags! {
/// Possible flags for a page table entry.
@ -39,12 +41,36 @@ bitflags::bitflags! {
}
}
pub(crate) fn init(start: u64, size: u64) {
/// Only available inside jinux-frame
pub(crate) static MEMORY_REGIONS: Once<Vec<&limine::LimineMemmapEntry>> = Once::new();
static MEMMAP_REQUEST: LimineMemmapRequest = LimineMemmapRequest::new(0);
pub(crate) fn init() {
heap_allocator::init();
frame_allocator::init(start as usize, size as usize);
let mut memory_regions = Vec::new();
let response = MEMMAP_REQUEST
.get_response()
.get()
.expect("Not found memory region information");
for i in response.memmap() {
debug!("Found memory region:{:x?}", **i);
memory_regions.push(&**i);
}
let mut biggest_region_size = 0;
let mut biggest_region_start = 0;
for i in memory_regions.iter() {
if i.len > biggest_region_size {
biggest_region_size = i.len;
biggest_region_start = i.base;
}
}
if biggest_region_size == 0 {
panic!("Cannot find usable memory region");
}
// TODO: pass the memory regions to the frame allocator. The frame allocator should use multiple usable area
frame_allocator::init(biggest_region_start as usize, biggest_region_size as usize);
page_table::init();
ORIGINAL_CR3.store(
x86_64_util::get_cr3_raw(),
core::sync::atomic::Ordering::Relaxed,
)
MEMORY_REGIONS.call_once(|| memory_regions);
}

View File

@ -120,15 +120,6 @@ struct IDT {
entries: [[usize; 2]; 256],
}
#[inline]
pub fn interrupt_ack() {
if crate::driver::apic::has_apic() {
crate::driver::apic::ack();
} else {
crate::driver::pic::ack();
}
}
impl IDT {
const fn default() -> Self {
Self {

View File

@ -1,21 +1,24 @@
#![no_std]
#![no_main]
#![feature(custom_test_frameworks)]
#![forbid(unsafe_code)]
// The no_mangle macro need to remove the `forbid(unsafe_code)` macro. The bootloader needs the _start function
// to be no mangle so that it can jump into the entry point.
// #![forbid(unsafe_code)]
#![test_runner(jinux_frame::test_runner)]
#![reexport_test_harness_main = "test_main"]
extern crate jinux_frame;
use bootloader::{entry_point, BootInfo};
use core::panic::PanicInfo;
use jinux_frame::println;
use limine::LimineBootInfoRequest;
entry_point!(kernel_main);
static BOOTLOADER_INFO: LimineBootInfoRequest = LimineBootInfoRequest::new(0);
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
#[no_mangle]
pub extern "C" fn _start() -> ! {
#[cfg(test)]
test_main();
jinux_frame::init(boot_info);
jinux_frame::init();
println!("[kernel] finish init jinux_frame");
component::init_all(component::parse_metadata!()).unwrap();
jinux_std::init();

View File

@ -10,9 +10,6 @@
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"pre-link-args": {
"ld.lld": [
"-Tframework/jinux-frame/src/linker.ld"
]
},
"panic-strategy": "abort",
"disable-redzone": true,