Skip to main content

kernel/arch/x86_64/boot/
entry.rs

1// SPDX-License-Identifier: GPL-3.0-only
2//! x86_64 Boot Entrypoint
3//!
4//! Authors: MarioS271
5
6use crate::drivers::tty::uart::{Uart, UartOps};
7use crate::knotice;
8use crate::lib::panic::kernel_panic;
9use crate::lib::panic_codes::PanicCode;
10use crate::lib::types::boot_info::{BootInfo, FramebufferInfo, KernelCmdline, KernelSectionInfo};
11use crate::state::simple_state::SIMPLE_STATE;
12use limine::BaseRevision;
13use limine::request::{ExecutableAddressRequest, ExecutableCmdlineRequest, FramebufferRequest, HhdmRequest, MemmapRequest, RsdpRequest};
14
15unsafe extern "C" {
16    /// Symbol which is located at the start of the kernel
17    pub static __kernel_start: u8;
18    /// Symbol which is located at the end of the kernel
19    pub static __kernel_end: u8;
20
21    /// Symbol which is located one byte after the end of the `.text` section
22    pub static __kernel_text_end: u8;
23    /// Symbol which is located one byte after the end of the `.rodata` section
24    pub static __kernel_rodata_end: u8;
25}
26
27#[used]
28pub static LIMINE_BASE_REVISION: BaseRevision = BaseRevision::with_revision(3);
29
30pub static LIMINE_KERNEL_ADDR_REQUEST: ExecutableAddressRequest = ExecutableAddressRequest::new();
31pub static LIMINE_HHDM_REQUEST: HhdmRequest = HhdmRequest::new();
32pub static LIMINE_RSDP_REQUEST: RsdpRequest = RsdpRequest::new();
33pub static LIMINE_CMDLINE_REQUEST: ExecutableCmdlineRequest = ExecutableCmdlineRequest::new();
34pub static LIMINE_FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
35pub static LIMINE_MEMMAP_REQUEST: MemmapRequest = MemmapRequest::new();
36
37#[unsafe(no_mangle)]
38pub extern "C" fn kernel_entry() -> ! {
39    // Stage 0a
40    crate::state::kstate::KSTATE.init();
41
42    // Stage 0b
43    // Safety: we are in a non-SMP/non-threading context
44    unsafe {
45        SIMPLE_STATE.init_uart(
46            Uart::com1()
47        );
48    };
49
50    // Safety: uart was correctly initialized above
51    // The return value is disregarded because COM1 is guaranteed to not be initialized
52    let _ = unsafe { SIMPLE_STATE.uart().lock().init() };
53
54    knotice!(
55        "Ferrite Kernel {}, on x86_64 booted via limine",
56        env!("CARGO_PKG_VERSION"),
57    );
58
59    let kernel_phys_start = LIMINE_KERNEL_ADDR_REQUEST
60        .response()
61        .map(|r| r.physical_base)
62        .unwrap_or_else(
63            || kernel_panic(
64                PanicCode::InitFailure,
65                "Limine didn't respond to the kernel address request"
66            )
67        );
68
69    let hhdm_offset = LIMINE_HHDM_REQUEST
70        .response()
71        .map(|r| r.offset)
72        .unwrap_or_else(
73            || kernel_panic(
74                PanicCode::InitFailure,
75                "Limine didn't respond to the HHDM offset request"
76            )
77        );
78
79    let rsdp_addr = LIMINE_RSDP_REQUEST
80        .response()
81        .map(|r| r.address as u64);
82
83    let raw_cmdline = LIMINE_CMDLINE_REQUEST
84        .response()
85        .map(|r| r.cmdline())
86        .unwrap_or_else(
87            || kernel_panic(
88                PanicCode::InitFailure,
89                "Limine didn't respond to the cmdline request"
90            )
91        );
92
93    let framebuffer = LIMINE_FRAMEBUFFER_REQUEST
94        .response()
95        .and_then(|r| r.framebuffers().first())
96        .map(|fb| FramebufferInfo {
97            addr: fb.address() as *mut u32,
98            pixels_per_row: fb.pitch / 4,
99            width: fb.width,
100            height: fb.height,
101            bpp: fb.bpp
102        })
103        .unwrap_or_else(
104            || kernel_panic(
105                PanicCode::InitFailure,
106                "Limine didn't respond to the framebuffer request"
107            )
108        );
109
110    let mut cmdline = KernelCmdline::default();
111    if !raw_cmdline.is_empty() {
112        cmdline.parse_in_cmd_line(raw_cmdline);
113    }
114
115    let boot_info = BootInfo {
116        hhdm_offset,
117        rsdp_addr,
118        kernel_sections: KernelSectionInfo {
119            kernel_phys_start,
120            kernel_start: &raw const __kernel_start as u64,
121            kernel_text_end: &raw const __kernel_text_end as u64,
122            kernel_rodata_end: &raw const __kernel_rodata_end as u64,
123            kernel_end: &raw const __kernel_end as u64
124        },
125        cmdline,
126        framebuffer
127    };
128
129    crate::kernel_main(boot_info);
130}