Compare commits

..

No commits in common. "8ca901ef508e9c684d9fb9c67ae707e4a962e6de" and "845559a9f577a01f2ed3d579672f75792fae3e40" have entirely different histories.

8 changed files with 117 additions and 360 deletions

Binary file not shown.

View File

@ -40,8 +40,8 @@ overhead_percentage=20
overhead_size=$((bootloader_size * overhead_percentage / 100)) overhead_size=$((bootloader_size * overhead_percentage / 100))
total_size=$((bootloader_size + overhead_size)) total_size=$((bootloader_size + overhead_size))
# Ensure the size is at least 100MB # Ensure the size is at least 4MB
minimum_size=$((100 * 1024 * 1024)) minimum_size=$((4 * 1024 * 1024))
# Calculate the final size, which should be the maximum of total_size or minimum_size # Calculate the final size, which should be the maximum of total_size or minimum_size
final_size=$(( total_size > minimum_size ? total_size : minimum_size )) final_size=$(( total_size > minimum_size ? total_size : minimum_size ))
@ -66,10 +66,6 @@ mount_directory=$(mktemp --tmpdir="$script_directory" -d)
sudo mount -v "${loop_device}p1" "$mount_directory" sudo mount -v "${loop_device}p1" "$mount_directory"
sudo mkdir -pv "${mount_directory}/EFI/BOOT/" sudo mkdir -pv "${mount_directory}/EFI/BOOT/"
sudo cp -vf "$bootloader" "${mount_directory}/EFI/BOOT/BOOTX64.EFI" sudo cp -vf "$bootloader" "${mount_directory}/EFI/BOOT/BOOTX64.EFI"
# Create the startup.nsh script
echo -e "FS0:\ncd EFI\\BOOT\nBOOTX64.EFI" | sudo tee "${mount_directory}/startup.nsh"
sudo umount -v "${mount_directory}" sudo umount -v "${mount_directory}"
echo "Partition and formatting ✓" echo "Partition and formatting ✓"

View File

@ -9,103 +9,6 @@ use crate::types::Handle;
**/ **/
#[repr(C)] #[repr(C)]
pub struct BootServicesTable { pub struct BootServicesTable {
pub efi_table_header: TableHeader, efi_table_header: TableHeader,
pub raise_tpl: RaiseTpl, load_image: extern "efiapi" fn(boot_policy: bool, parent_image_hanle: Handle),
pub restore_tpl: RestoreTpl,
pub allocate_pages: AllocatePages,
pub free_pages: FreePages,
pub get_memory_map: GetMemoryMap,
pub allocate_pool: AllocatePool,
pub free_pool: FreePool,
pub create_event: CreateEvent,
pub set_timer: SetTimer,
pub wait_for_event: WaitForEvent,
pub signal_event: SignalEvent,
pub close_event: CloseEvent,
pub check_event: CheckEvent,
pub install_protocol_interface: InstallProtocolInterface,
pub reinstall_protocol_interface: ReinstallProtocolInterface,
pub uninstall_protocol_interface: UninstallProtocolInterface,
pub handle_protocol: HandleProtocol,
pub reserved: Reserved,
pub register_protocol_notify: RegisterProtocolNotify,
pub locate_handle: LocateHandle,
pub locate_device_path: LocateDevicePath,
pub install_configuration_table: InstallConfigurationTable,
pub load_image: LoadImage,
pub start_image: StartImage,
pub exit: Exit,
pub unload_image: UnloadImage,
pub exit_boot_services: ExitBootServices,
pub get_next_monotonic_count: GetNextMonotonicCount,
pub stall: Stall,
pub set_watchdog_timer: SetWatchdogTimer,
pub connect_controller: ConnectController,
pub disconnect_contoller: DisconnectController,
pub open_protocol: OpenProtocol,
pub close_protocol: CloseProtocol,
pub open_protocol_information: OpenProtocolInformation,
pub protocol_per_handle: ProtocolPerHandle,
pub locate_handle_buffer: LocateHandleBuffer,
pub locate_protocol: LocateProtocol,
pub install_multiple_protocol_interfaces: InstallMultipleProtocolInterfaces,
pub uninstall_multiple_protocol_interfaces: UninstallMultipleProtocolInterfaces,
pub calculate_crc_32: CalculateCrc32,
pub copy_mem: CopyMem,
pub set_mem: SetMem,
pub create_event_ex: CreateEventEx,
}
pub type RaiseTpl = extern "efiapi" fn() -> Status;
pub type RestoreTpl = extern "efiapi" fn() -> Status;
pub type AllocatePages = extern "efiapi" fn() -> Status;
pub type FreePages = extern "efiapi" fn() -> Status;
pub type GetMemoryMap = extern "efiapi" fn() -> Status;
pub type AllocatePool = extern "efiapi" fn() -> Status;
pub type FreePool = extern "efiapi" fn() -> Status;
pub type CreateEvent = extern "efiapi" fn() -> Status;
pub type SetTimer = extern "efiapi" fn() -> Status;
pub type WaitForEvent = extern "efiapi" fn() -> Status;
pub type SignalEvent = extern "efiapi" fn() -> Status;
pub type CloseEvent = extern "efiapi" fn() -> Status;
pub type CheckEvent = extern "efiapi" fn() -> Status;
pub type InstallProtocolInterface = extern "efiapi" fn() -> Status;
pub type ReinstallProtocolInterface = extern "efiapi" fn() -> Status;
pub type UninstallProtocolInterface = extern "efiapi" fn() -> Status;
pub type HandleProtocol = extern "efiapi" fn() -> Status;
pub type Reserved = extern "efiapi" fn() -> Status;
pub type RegisterProtocolNotify = extern "efiapi" fn() -> Status;
pub type LocateHandle = extern "efiapi" fn() -> Status;
pub type LocateDevicePath = extern "efiapi" fn() -> Status;
pub type InstallConfigurationTable = extern "efiapi" fn() -> Status;
pub type LoadImage = extern "efiapi" fn() -> Status;
pub type StartImage = extern "efiapi" fn() -> Status;
pub type Exit = extern "efiapi" fn(
image_handle: Handle,
exit_status: Status,
exit_data_size: usize,
*const u16
) -> Status;
pub type UnloadImage = extern "efiapi" fn() -> Status;
pub type ExitBootServices = extern "efiapi" fn() -> Status;
pub type GetNextMonotonicCount = extern "efiapi" fn() -> Status;
pub type Stall = extern "efiapi" fn() -> Status;
pub type SetWatchdogTimer = extern "efiapi" fn() -> Status;
pub type ConnectController = extern "efiapi" fn() -> Status;
pub type DisconnectController = extern "efiapi" fn() -> Status;
pub type OpenProtocol = extern "efiapi" fn() -> Status;
pub type CloseProtocol = extern "efiapi" fn() -> Status;
pub type OpenProtocolInformation = extern "efiapi" fn() -> Status;
pub type ProtocolPerHandle = extern "efiapi" fn() -> Status;
pub type LocateHandleBuffer = extern "efiapi" fn() -> Status;
pub type LocateProtocol = extern "efiapi" fn() -> Status;
pub type InstallMultipleProtocolInterfaces = extern "efiapi" fn() -> Status;
pub type UninstallMultipleProtocolInterfaces = extern "efiapi" fn() -> Status;
pub type CalculateCrc32 = extern "efiapi" fn() -> Status;
pub type CopyMem = extern "efiapi" fn() -> Status;
pub type SetMem = extern "efiapi" fn() -> Status;
pub type CreateEventEx = extern "efiapi" fn() -> Status;
impl BootServicesTable {
pub const BOOT_SERVICES_SIGNATURE: u64 = 0x56524553544f4f42;
} }

19
src/functions.rs Normal file
View File

@ -0,0 +1,19 @@
use crate::structs::{MemoryDescriptor, Status, TPL};
// Task Priority Services
pub type raise_tpl = fn(efi_tpl: TPL) -> Status;
pub type restore_tpl = fn() -> ();
// Memory Services
pub type allocate_pages = fn() -> ();
pub type free_pages = fn() -> ();
pub type allocate_pool = fn() -> ();
pub type free_pool = fn() -> ();
pub type get_memory_map = extern "efiapi" fn(
memory_map_size: *mut usize,
memory_map: *mut MemoryDescriptor,
map_key: *mut usize,
descriptor_size: *mut usize,
descriptor_version: *mut u32,
) -> Status;

View File

@ -1,63 +1,31 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
pub mod boot_services; pub mod functions;
pub mod simple_text_output;
pub mod structs; pub mod structs;
pub mod system_table; pub mod system_table;
pub mod types; pub mod types;
pub mod boot_services;
pub mod simple_text_output;
use core::{panic::PanicInfo, ptr::null}; use core::panic::PanicInfo;
use boot_services::BootServicesTable;
use simple_text_output::SimpleTextOutputProtocol;
use structs::Status;
use system_table::SystemTable; use system_table::SystemTable;
use types::Handle; use types::Handle;
#[no_mangle] #[no_mangle]
#[export_name = "efi_main"] #[export_name = "efi_main"]
extern "efiapi" fn efi_main(image_handle: Handle, system_table_ptr: *mut SystemTable) -> usize { extern "efiapi" fn efi_main(image_handle: Handle, system_table: *mut SystemTable) -> usize {
if system_table_ptr.is_null() { unsafe {
return usize::from(Status::OutOfResources); let system_table_ref: &SystemTable = &*system_table;
let console_out: *mut structs::SimpleTextOutputProtocol = system_table_ref.console_out;
} }
loop {};
let system_table: &SystemTable = initialize_system_table(system_table_ptr); 0 // EFI_SUCCESS
let console_out: Option<&SimpleTextOutputProtocol> = initialize_console_out(system_table);
let boot_services_table: Option<&BootServicesTable> = initialize_boot_services(system_table);
if let Some(console_out) = console_out {
(console_out.clear_screen)(console_out);
}
if let Some(boot_services_table) = boot_services_table {
(boot_services_table.exit)(image_handle, Status::Success, 0, null());
}
usize::from(Status::Success) // EFI_SUCCESS
} }
fn initialize_system_table(system_table_ptr: *mut SystemTable) -> &'static SystemTable {
unsafe { &*system_table_ptr }
}
fn initialize_console_out(system_table: &SystemTable) -> Option<&SimpleTextOutputProtocol> {
let console_out = system_table.console_out;
if !console_out.is_null() {
unsafe { Some(&*console_out) }
} else {
None
}
}
fn initialize_boot_services(system_table: &SystemTable) -> Option<&BootServicesTable> {
if !system_table.boot_services_table_pointer.is_null() {
unsafe { Some(&*system_table.boot_services_table_pointer)}
} else {
None
}
}
#[panic_handler] #[panic_handler]
fn panic(_info: &PanicInfo) -> ! { fn panic(_info: &PanicInfo) -> ! {
loop {} loop {}
} }

View File

@ -1,29 +1,8 @@
use crate::structs::{Status, GUID}; use crate::structs::Status;
use crate::types::Char16; use crate::types::Char16;
#[repr(C)] #[repr(C)]
pub struct SimpleTextOutputProtocol { pub struct SimpleTextOutputProtocol {}
pub reset: text_reset,
pub output_string: text_string,
pub test_string: text_test_string,
pub query_mode: text_query_mode,
pub set_mode: text_set_mode,
pub set_attribute: text_set_attribute,
pub clear_screen: text_clear_screen,
pub set_cursor_position: text_set_cursor_position,
pub enable_cursor: text_enable_cursor,
pub mode: *mut SimpleTextOutputMode,
}
impl SimpleTextOutputProtocol {
pub const SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID: GUID = GUID {
data1: 0x387477c2,
data2: 0x69c7,
data3: 0x11d2,
data4: [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b],
};
}
pub type text_reset = pub type text_reset =
extern "efiapi" fn(this: &SimpleTextOutputProtocol, extended_verification: bool) -> Status; extern "efiapi" fn(this: &SimpleTextOutputProtocol, extended_verification: bool) -> Status;
@ -41,47 +20,33 @@ pub type text_set_mode =
extern "efiapi" fn(this: &SimpleTextOutputProtocol, mode_number: usize) -> Status; extern "efiapi" fn(this: &SimpleTextOutputProtocol, mode_number: usize) -> Status;
pub type text_set_attribute = pub type text_set_attribute =
extern "efiapi" fn(this: &SimpleTextOutputProtocol, Attribute: usize) -> Status; extern "efiapi" fn(this: &SimpleTextOutputProtocol, Attribute: usize) -> Status;
pub type text_clear_screen = extern "efiapi" fn(this: &SimpleTextOutputProtocol) -> Status;
pub type text_set_cursor_position =
extern "efiapi" fn(this: &SimpleTextOutputProtocol, column: usize, row: usize) -> Status;
pub type text_enable_cursor =
extern "efiapi" fn(this: &SimpleTextOutputProtocol, visible: bool) -> Status;
#[repr(C)] #[repr(C)]
pub enum Attribute { pub enum Attribute {
Black = 0x00, Black = 0x00 ,
Blue = 0x01, Blue = 0x01 ,
Green = 0x02, Green = 0x02 ,
Cyan = 0x03, Cyan = 0x03 ,
Red = 0x04, Red = 0x04 ,
Magenta = 0x05, Magenta = 0x05 ,
Brown = 0x06, Brown = 0x06 ,
LightGray = 0x07, LightGray = 0x07 ,
Bright = 0x08, Bright = 0x08 ,
// DarkGray = 0x08 , // DarkGray = 0x08 ,
LightBlue = 0x09, LightBlue = 0x09 ,
LightGreen = 0x0a, LightGreen = 0x0a ,
LightCyan = 0x0b, LightCyan = 0x0b ,
LightRed = 0x0c, LightRed = 0x0c ,
LightMagenta = 0x0d, LightMagenta = 0x0d ,
Yellow = 0x0e, Yellow = 0x0e ,
White = 0x0f, White = 0x0f ,
// BackgroundBlack = 0x00 , // BackgroundBlack = 0x00 ,
BackgroundBlue = 0x10, BackgroundBlue = 0x10 ,
BackgroundGreen = 0x20, BackgroundGreen = 0x20 ,
BackgroundCyan = 0x30, BackgroundCyan = 0x30 ,
BackgroundRed = 0x40, BackgroundRed = 0x40 ,
BackgroundMagenta = 0x50, BackgroundMagenta = 0x50 ,
BackgroundBrown = 0x60, BackgroundBrown = 0x60 ,
BackgroundLightGray = 0x70, BackgroundLightGray = 0x70 ,
}
#[repr(C)]
pub struct SimpleTextOutputMode {
max_mode: i32,
mode: i32,
attribute: i32,
cursor_column: i32,
cursor_row: i32,
cursor_visible: bool,
} }

View File

@ -35,146 +35,53 @@ pub struct TableHeader {
reserved: u32, reserved: u32,
} }
#[repr(u64)] #[repr(C)]
pub enum Status { pub enum Status {
Success = 0, Success,
LoadError = 1, LoadError,
InvalidParameter = 2, InvalidParameter,
Unsupported = 3, Unsupported,
BadBufferSize = 4, BadBufferSize,
BufferTooSmall = 5, BufferTooSmall,
NotReady = 6, NotReady,
DeviceError = 7, DeviceError,
WriteProtected = 8, WriteProtected,
OutOfResources = 9, OutOfResources,
VolumeCorrupted = 10, VolumeCorrupted,
VolumeFull = 11, VolumeFull,
NoMedia = 12, NoMedia,
MediaChanged = 13, MediaChanged,
NotFound = 14, NotFound,
AccessDenied = 15, AccessDenied,
NoResponse = 16, NoResponce,
NoMapping = 17, NoMapping,
Timeout = 18, Timeout,
NotStarted = 19, NotStarted,
AlreadyStarted = 20, AlreadyStarted,
Aborted = 21, Aborted,
IcmpError = 22, IcmpError,
TftpError = 23, TftpError,
ProtocolError = 24, ProtocolError,
IncompatibleVersion = 25, IncompatibleVersion,
SecurityViolation = 26, SecurityViolation,
CrcError = 27, CrcError,
EndOfMedia = 28, EndOfMedia,
EndOfFile = 31, EndOfFile,
InvalidLanguage = 32, InvalidLanguage,
CompromisedData = 33, CompromisedData,
IpAddressConflict = 34, IpAddressConflict,
HttpError = 35, HttpError,
} }
impl From<u64> for Status {
fn from(value: u64) -> Self {
match value {
0 => Status::Success,
1 => Status::LoadError,
2 => Status::InvalidParameter,
3 => Status::Unsupported,
4 => Status::BadBufferSize,
5 => Status::BufferTooSmall,
6 => Status::NotReady,
7 => Status::DeviceError,
8 => Status::WriteProtected,
9 => Status::OutOfResources,
10 => Status::VolumeCorrupted,
11 => Status::VolumeFull,
12 => Status::NoMedia,
13 => Status::MediaChanged,
14 => Status::NotFound,
15 => Status::AccessDenied,
16 => Status::NoResponse,
17 => Status::NoMapping,
18 => Status::Timeout,
19 => Status::NotStarted,
20 => Status::AlreadyStarted,
21 => Status::Aborted,
22 => Status::IcmpError,
23 => Status::TftpError,
24 => Status::ProtocolError,
25 => Status::IncompatibleVersion,
26 => Status::SecurityViolation,
27 => Status::CrcError,
28 => Status::EndOfMedia,
31 => Status::EndOfFile,
32 => Status::InvalidLanguage,
33 => Status::CompromisedData,
34 => Status::IpAddressConflict,
35 => Status::HttpError,
_ => Status::Unsupported, // Default case
}
}
}
impl From<Status> for u64 {
fn from(status: Status) -> Self {
status as u64
}
}
impl From<Status> for usize {
fn from(status: Status) -> Self {
status as usize
}
}
// #[repr(u64)]
// pub enum Status {
// Success,
// LoadError,
// InvalidParameter,
// Unsupported,
// BadBufferSize,
// BufferTooSmall,
// NotReady,
// DeviceError,
// WriteProtected,
// OutOfResources,
// VolumeCorrupted,
// VolumeFull,
// NoMedia,
// MediaChanged,
// NotFound,
// AccessDenied,
// NoResponce,
// NoMapping,
// Timeout,
// NotStarted,
// AlreadyStarted,
// Aborted,
// IcmpError,
// TftpError,
// ProtocolError,
// IncompatibleVersion,
// SecurityViolation,
// CrcError,
// EndOfMedia,
// EndOfFile,
// InvalidLanguage,
// CompromisedData,
// IpAddressConflict,
// HttpError,
// }
#[repr(C)] #[repr(C)]
pub struct TPL {} pub struct TPL {}
#[repr(C)] #[repr(C)]
pub struct GUID { pub struct EFIGUID {
pub data1: u32, data1: u32,
pub data2: u16, data2: u16,
pub data3: u16, data3: u16,
pub data4: [u8; 8], data4: [u8; 8],
} }
#[repr(C)] #[repr(C)]

View File

@ -1,7 +1,6 @@
use crate::boot_services::BootServicesTable; use crate::boot_services::BootServicesTable;
use crate::structs::*; use crate::structs::*;
use crate::types::Handle; use crate::types::Handle;
use crate::simple_text_output::SimpleTextOutputProtocol;
#[repr(C)] #[repr(C)]
pub struct SystemTable { pub struct SystemTable {
@ -42,21 +41,21 @@ pub struct ImageEntryPoint {
system_table_pointer: *const i32, // A pointer to the EFI System Table. system_table_pointer: *const i32, // A pointer to the EFI System Table.
} }
#[repr(C)]
pub struct SystemTableRevisions;
#[repr(u32)] impl SystemTableRevisions {
pub enum SystemTableRevisions { pub const EFI_1_90_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (90));
EFI_2_100_SYSTEM_TABLE_REVISION = (2 << 16) | 100, pub const EFI_1_80_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (80));
EFI_1_90_SYSTEM_TABLE_REVISION = ((2 << 16) | (90)), pub const EFI_1_70_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (70));
EFI_1_80_SYSTEM_TABLE_REVISION = ((2 << 16) | (80)), pub const EFI_1_60_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (60));
EFI_1_70_SYSTEM_TABLE_REVISION = ((2 << 16) | (70)), pub const EFI_1_50_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (50));
EFI_1_60_SYSTEM_TABLE_REVISION = ((2 << 16) | (60)), pub const EFI_1_40_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (40));
EFI_1_50_SYSTEM_TABLE_REVISION = ((2 << 16) | (50)), pub const EFI_1_31_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (31));
EFI_1_40_SYSTEM_TABLE_REVISION = ((2 << 16) | (40)), pub const EFI_1_30_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (30));
EFI_1_31_SYSTEM_TABLE_REVISION = ((2 << 16) | (31)), pub const EFI_1_20_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (20));
EFI_1_30_SYSTEM_TABLE_REVISION = ((2 << 16) | (30)), pub const EFI_1_10_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (10));
EFI_1_20_SYSTEM_TABLE_REVISION = ((2 << 16) | (20)), pub const EFI_1_00_SYSTEM_TABLE_REVISION: u32 = ((2 << 16) | (00));
EFI_1_10_SYSTEM_TABLE_REVISION = ((2 << 16) | (10)), pub const EFI_0_10_SYSTEM_TABLE_REVISION: u32 = ((1 << 16) | (10));
EFI_1_00_SYSTEM_TABLE_REVISION = ((2 << 16) | (00)), pub const EFI_0_02_SYSTEM_TABLE_REVISION: u32 = ((1 << 16) | (02));
EFI_0_10_SYSTEM_TABLE_REVISION = ((1 << 16) | (10)), }
EFI_0_02_SYSTEM_TABLE_REVISION = ((1 << 16) | (02)),
}