The limine.pas file contains the types and constants described in the Limine Protocol.
The limine.inc file contains the requests which are enabled using define directives. Why?
How do I add the requests to a specific section?
FreePascal does not provide a way to specify section names. Exported symbols use the
_limine_request_prefix allowing the linker script to target any that are enabled.
Example linker script section:
.limine_requests : {
KEEP(*(.data.*_limine_request_*))
} :limine_requestsTo set specific Limine request values you will need to enable C-style macros:
{$macro on}
{$define LIMINE_<...> := value}
{$macro off}Set a specific base revision:
{$macro on}
{$define LIMINE_BASE_REVISION := 4}
{$macro off}
{$I limine.inc}Set the entry point:
{$macro on}
{$define LIMINE_ENTRY_POINT := @procedure_name}
{$macro off}
{$define LIMINE_REQUEST_ENTRY_POINT}
{$I limine.inc}Add internal modules:
{$macro on}
{$define LIMINE_MODULE_COUNT := <count of internal module pointers>}
{$define LIMINE_MODULE_ARRAY := @array_of_internal_module_pointers}
{$macro off}
{$define LIMINE_REQUEST_MODULE}
{$I limine.inc}Set multiprocessor flags:
{$macro on}
{$define LIMINE_MULTIPROCESSOR_FLAGS := LIMINE_MULTIPROCESSOR_REQUEST_X86_64_X2APIC}
{$macro off}
{$define LIMINE_REQUEST_MULTIPROCESSOR}
{$I limine.inc}Set paging mode:
{$macro on}
{$define LIMINE_PAGING_MODE_REVISION := 1}
{$define LIMINE_PAGING_MODE := LIMINE_PAGING_MODE_X86_64_DEFAULT}
{$define LIMINE_PAGING_MODE_MIN := LIMINE_PAGING_MODE_X86_64_4LVL}
{$define LIMINE_PAGING_MODE_MAX := LIMINE_PAGING_MODE_X86_64_5LVL}
{$macro off}
{$define LIMINE_REQUEST_PAGING_MODE}
{$I limine.inc}Set stack size:
{$macro on}
{$define LIMINE_STACK_SIZE := <size in bytes>}
{$macro off}
{$define LIMINE_REQUEST_STACK_SIZE}
{$I limine.inc}Define the request macros prior to including limine.inc to request features:
{$define LIMINE_REQUEST_BOOTLOADER_INFO}
{$define LIMINE_REQUEST_BOOTLOADER_PERFORMANCE}
{$define LIMINE_REQUEST_DATE_AT_BOOT}
{$define LIMINE_REQUEST_DEVICE_TREE_BLOB}
{$define LIMINE_REQUEST_EFI_MEMORY_MAP}
{$define LIMINE_REQUEST_EFI_SYSTEM_TABLE}
{$define LIMINE_REQUEST_ENTRY_POINT}
{$define LIMINE_REQUEST_EXECUTABLE_ADDRESS}
{$define LIMINE_REQUEST_EXECUTABLE_CMDLINE}
{$define LIMINE_REQUEST_EXECUTABLE_FILE}
{$define LIMINE_REQUEST_FIRMWARE_TYPE}
{$define LIMINE_REQUEST_FLANTERM_FB_INIT_PARAMS}
{$define LIMINE_REQUEST_FRAMEBUFFER}
{$define LIMINE_REQUEST_HHDM}
{$define LIMINE_REQUEST_KEEP_IOMMU}
{$define LIMINE_REQUEST_MEMORY_MAP}
{$define LIMINE_REQUEST_MODULE}
{$define LIMINE_REQUEST_MULTIPROCESSOR}
{$define LIMINE_REQUEST_PAGING_MODE}
{$define LIMINE_REQUEST_RISCV_BSP_HARTID}
{$define LIMINE_REQUEST_RSDP}
{$define LIMINE_REQUEST_SMBIOS}
{$define LIMINE_REQUEST_STACK_SIZE}Available external names for requests:
_limine_request_bootloader_info_limine_request_bootloader_performance_limine_request_date_at_boot_limine_request_device_tree_blob_limine_request_efi_memory_map_limine_request_efi_system_table_limine_request_entry_point_limine_request_executable_address_limine_request_executable_cmdline_limine_request_executable_file_limine_request_firmware_type_limine_request_flanterm_fb_init_params_limine_request_framebuffer_limine_request_hhdm_limine_request_keep_iommu_limine_request_memory_map_limine_request_module_limine_request_multiprocessor_limine_request_paging_mode_limine_request_riscv_bsp_hartid_limine_request_rsdp_limine_request_smbios_limine_request_stack_size
Corresponding types for requests:
TLimineBootloaderInfoRequestTLimineBootloaderPerformanceRequestTLimineDateAtBootRequestTLimineDeviceTreeBlobRequestTLimineEfiMemoryMapRequestTLimineEfiSystemTableRequestTLimineEntryPointRequestTLimineExecutableAddressRequestTLimineExecutableCmdLineRequestTLimineExecutableFileRequestTLimineFirmwareTypeRequestTLimineFlantermFbInitParamsRequestTLimineFramebufferRequestTLimineHhdmRequestTLimineKeepIommuRequestTLimineMemoryMapRequestTLimineModuleRequestTLimineMultiprocessorRequestTLiminePagingModeRequestTLimineRiscvBspHartIdRequestTLimineRsdpRequestTLimineSmbiosRequestTLimineStackSizeRequest
Example definition for Framebuffer request:
var
Framebuffer: TLimineFramebufferRequest; external name '_limine_request_framebuffer';FreePascal does not support parameterized C-style macros.
Assigning values to records at compile-time is also limited. Static initialization of records requires literal values.
This is possible:
const
FramebufferRequest: TLimineFramebufferRequest = (
Id: (
QWord($C7B1DD30DF4C8B88),
QWord($0A82E883A194F07B),
QWord($9D5827DCD881DD75),
QWord($A3148604F6FAB11B)
);
Revision: 0;
Response: nil;
); export name '_limine_request_framebuffer';While this is not:
const
FramebufferRequest: TLimineFramebufferRequest = (
Id: LIMINE_FRAMEBUFFER_REQUEST_ID;
Revision: 0;
Response: nil;
); export name '_limine_request_framebuffer';FreePascal does support basic C-style macros for assigning values.
{$macro on}
{$define LIMINE_BASE_REVISION := 4}
{$macro off}The C-style macros allow this to work:
const
{$macro on}
FramebufferRequest: TLimineFramebufferRequest = (
Id: LIMINE_FRAMEBUFFER_REQUEST_ID;
Revision: 0;
Response: nil;
); export name '_limine_request_framebuffer';
{$macro off}It still requires limine.inc to be included, but the requests can be explicitly defined.
Using these macros with
limine.incwas the most convenient way I found to make this work. It may change if I find a better alternative.