2021-11-26 07:18:08 +03:00
/**
* @ brief Main bootloader logic .
*
* Does all the heavy lifting after configuration options have
* been selected by the user . Loads the kernel and ramdisk ,
* sets up multiboot structures , and jumps to the kernel .
*
* @ copyright
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE . md
* Copyright ( C ) 2018 - 2021 K . Lange
*/
2021-06-14 05:11:37 +03:00
# include <stdint.h>
# include <stddef.h>
# include "multiboot.h"
# include "text.h"
# include "util.h"
# include "menu.h"
# include "elf.h"
# include "options.h"
# include "iso9660.h"
2021-09-07 05:45:58 +03:00
# include "kbd.h"
2021-06-14 05:11:37 +03:00
2021-10-26 10:13:50 +03:00
extern void draw_logo ( int ) ;
2021-06-14 05:11:37 +03:00
char * kernel_load_start = 0 ;
mboot_mod_t modules_mboot [ 1 ] = {
{ 0 , 0 , 0 , 1 }
} ;
2021-09-07 05:45:58 +03:00
static struct multiboot multiboot_header = {
2021-06-14 05:11:37 +03:00
/* flags; */ MULTIBOOT_FLAG_CMDLINE | MULTIBOOT_FLAG_MODS | MULTIBOOT_FLAG_MEM | MULTIBOOT_FLAG_MMAP | MULTIBOOT_FLAG_LOADER ,
/* mem_lower; */ 0x100000 ,
/* mem_upper; */ 0x640000 ,
/* boot_device; */ 0 ,
/* cmdline; */ 0 ,
/* mods_count; */ 1 ,
/* mods_addr; */ 0 ,
/* num; */ 0 ,
/* size; */ 0 ,
/* addr; */ 0 ,
/* shndx; */ 0 ,
/* mmap_length; */ 0 ,
/* mmap_addr; */ 0 ,
/* drives_length; */ 0 ,
/* drives_addr; */ 0 ,
/* config_table; */ 0 ,
/* boot_loader_name; */ 0 ,
/* apm_table; */ 0 ,
/* vbe_control_info; */ 0 ,
/* vbe_mode_info; */ 0 ,
/* vbe_mode; */ 0 ,
/* vbe_interface_seg; */ 0 ,
/* vbe_interface_off; */ 0 ,
/* vbe_interface_len; */ 0 ,
} ;
static uintptr_t ramdisk_off = 0 ;
static uintptr_t ramdisk_len = 0 ;
uintptr_t final_offset = 0 ;
2021-09-07 05:45:58 +03:00
uintptr_t _xmain = 0 ;
2023-12-07 04:36:18 +03:00
int disable_kaslr = 0 ;
2021-06-14 05:11:37 +03:00
2023-11-10 10:34:54 +03:00
static inline uint64_t read_tsc ( void ) {
uint32_t lo , hi ;
asm volatile ( " rdtsc " : " =a " ( lo ) , " =d " ( hi ) ) ;
return ( ( uint64_t ) hi < < 32 ) | ( uint64_t ) lo ;
}
2021-10-20 05:59:14 +03:00
static int load_aout ( uint32_t * hdr ) {
uintptr_t base_offset = ( uintptr_t ) hdr - ( uintptr_t ) kernel_load_start ;
uintptr_t hdr_offset = hdr [ 3 ] - base_offset ;
2023-11-10 10:34:54 +03:00
uint32_t rando = 0 ;
2023-12-07 04:36:18 +03:00
size_t xtra = 0 ;
if ( ! disable_kaslr ) {
asm volatile ( " rdtsc " : " =a " ( rando ) , " =d " ( ( uint32_t ) { 0 } ) ) ;
xtra = ( rando & 0xFF ) < < 12 ;
}
2021-10-20 05:59:14 +03:00
2023-11-10 09:40:41 +03:00
memcpy ( ( void * ) ( uintptr_t ) hdr [ 4 ] + xtra , kernel_load_start + ( hdr [ 4 ] - hdr_offset ) , ( hdr [ 5 ] - hdr [ 4 ] ) ) ;
memset ( ( void * ) ( uintptr_t ) hdr [ 5 ] + xtra , 0 , ( hdr [ 6 ] - hdr [ 5 ] ) ) ;
_xmain = ( uintptr_t ) hdr [ 7 ] + xtra ;
2021-10-20 05:59:14 +03:00
2023-11-10 09:40:41 +03:00
if ( hdr [ 6 ] + xtra > final_offset ) final_offset = hdr [ 6 ] + xtra ;
2021-10-20 05:59:14 +03:00
final_offset = ( final_offset & ~ ( 0xFFF ) ) + ( ( final_offset & 0xFFF ) ? 0x1000 : 0 ) ;
2021-06-14 05:11:37 +03:00
2021-10-20 05:59:14 +03:00
return 1 ;
}
static int load_elf32 ( Elf32_Header * header ) {
2021-06-14 05:11:37 +03:00
if ( header - > e_ident [ 0 ] ! = ELFMAG0 | |
header - > e_ident [ 1 ] ! = ELFMAG1 | |
header - > e_ident [ 2 ] ! = ELFMAG2 | |
header - > e_ident [ 3 ] ! = ELFMAG3 ) {
print_ ( " Not a valid ELF32. \n " ) ;
return 0 ;
}
uintptr_t entry = ( uintptr_t ) header - > e_entry ;
for ( uintptr_t x = 0 ; x < ( uint32_t ) header - > e_phentsize * header - > e_phnum ; x + = header - > e_phentsize ) {
Elf32_Phdr * phdr = ( Elf32_Phdr * ) ( kernel_load_start + header - > e_phoff + x ) ;
if ( phdr - > p_type = = PT_LOAD ) {
memcpy ( ( uint8_t * ) ( uintptr_t ) phdr - > p_vaddr , kernel_load_start + phdr - > p_offset , phdr - > p_filesz ) ;
uintptr_t r = phdr - > p_filesz ;
while ( r < phdr - > p_memsz ) {
* ( char * ) ( phdr - > p_vaddr + r ) = 0 ;
r + + ;
}
if ( phdr - > p_vaddr + r > final_offset ) final_offset = phdr - > p_vaddr + r ;
}
}
_xmain = entry ;
/* Round final offset */
final_offset = ( final_offset & ~ ( 0xFFF ) ) + ( ( final_offset & 0xFFF ) ? 0x1000 : 0 ) ;
2021-06-14 06:06:31 +03:00
print ( " Loaded with end at 0x " ) ; print_hex ( final_offset ) ; print ( " \n " ) ;
2021-06-14 05:11:37 +03:00
return 1 ;
}
2021-10-20 05:59:14 +03:00
static int load_kernel ( void ) {
clear ( ) ;
/* Check for Multiboot header */
for ( uintptr_t x = 0 ; x < 8192 ; x + = 4 ) {
uint32_t * check = ( uint32_t * ) ( kernel_load_start + x ) ;
if ( * check = = 0x1BADB002 ) {
if ( check [ 1 ] & ( 1 < < 16 ) ) {
return load_aout ( check ) ;
} else {
return load_elf32 ( ( void * ) kernel_load_start ) ;
}
}
}
return 0 ;
}
2021-09-07 05:45:58 +03:00
static void relocate_ramdisk ( mboot_mod_t * mboot_mods ) {
2021-06-14 05:11:37 +03:00
char * dest = ( char * ) final_offset ;
char * src = ( char * ) ramdisk_off ;
for ( size_t s = 0 ; s < ramdisk_len ; + + s ) {
dest [ s ] = src [ s ] ;
}
2021-09-07 05:45:58 +03:00
mboot_mods - > mod_start = final_offset ;
mboot_mods - > mod_end = final_offset + ramdisk_len ;
2021-06-14 05:11:37 +03:00
final_offset + = ramdisk_len ;
final_offset = ( final_offset & ~ ( 0xFFF ) ) + ( ( final_offset & 0xFFF ) ? 0x1000 : 0 ) ;
}
2021-09-07 05:45:58 +03:00
# ifdef EFI_PLATFORM
# include <efi.h>
extern EFI_GRAPHICS_OUTPUT_PROTOCOL * GOP ;
/* EFI boot uses simple filesystem driver */
static EFI_GUID efi_simple_file_system_protocol_guid =
{ 0x0964e5b22 , 0x6459 , 0x11d2 , 0x8e , 0x39 , 0x00 , 0xa0 , 0xc9 , 0x69 , 0x72 , 0x3b } ;
static EFI_GUID efi_loaded_image_protocol_guid =
{ 0x5B1B31A1 , 0x9562 , 0x11d2 , { 0x8E , 0x3F , 0x00 , 0xA0 , 0xC9 , 0x69 , 0x72 , 0x3B } } ;
extern EFI_SYSTEM_TABLE * ST ;
extern EFI_HANDLE ImageHandleIn ;
extern char do_the_nasty [ ] ;
static void finish_boot ( void ) {
/* Set up multiboot header */
struct multiboot * finalHeader = ( void * ) ( uintptr_t ) final_offset ;
memcpy ( ( void * ) final_offset , & multiboot_header , sizeof ( struct multiboot ) ) ;
final_offset + = sizeof ( struct multiboot ) ;
finalHeader - > flags | = MULTIBOOT_FLAG_FB ;
finalHeader - > framebuffer_addr = GOP - > Mode - > FrameBufferBase ;
finalHeader - > framebuffer_pitch = GOP - > Mode - > Info - > PixelsPerScanLine * 4 ;
finalHeader - > framebuffer_width = GOP - > Mode - > Info - > HorizontalResolution ;
finalHeader - > framebuffer_height = GOP - > Mode - > Info - > VerticalResolution ;
finalHeader - > framebuffer_bpp = 32 ;
/* Copy in command line */
memcpy ( ( void * ) final_offset , cmdline , strlen ( cmdline ) + 1 ) ;
finalHeader - > cmdline = ( uintptr_t ) final_offset ;
final_offset + = strlen ( cmdline ) + 1 ;
/* Copy bootloader name */
memcpy ( ( void * ) final_offset , VERSION_TEXT , strlen ( VERSION_TEXT ) + 1 ) ;
finalHeader - > boot_loader_name = ( uintptr_t ) final_offset ;
final_offset + = strlen ( VERSION_TEXT ) + 1 ;
/* Copy module pointers */
memcpy ( ( void * ) final_offset , modules_mboot , sizeof ( modules_mboot ) ) ;
finalHeader - > mods_addr = ( uintptr_t ) final_offset ;
final_offset + = sizeof ( modules_mboot ) ;
/* Realign for memory map */
final_offset = ( final_offset & ~ ( 0xFFF ) ) + ( ( final_offset & 0xFFF ) ? 0x1000 : 0 ) ;
/* Write memory map */
mboot_memmap_t * mmap = ( void * ) final_offset ;
memset ( ( void * ) final_offset , 0x00 , 1024 ) ;
finalHeader - > mmap_addr = ( uint32_t ) ( uintptr_t ) mmap ;
{
EFI_STATUS e ;
UINTN mapSize = 0 , mapKey , descriptorSize ;
UINT32 descriptorVersion ;
e = uefi_call_wrapper ( ST - > BootServices - > GetMemoryMap , 5 , & mapSize , NULL , & mapKey , & descriptorSize , NULL ) ;
EFI_MEMORY_DESCRIPTOR * efi_memory = ( void * ) ( final_offset ) ;
final_offset + = mapSize ;
while ( ( uintptr_t ) final_offset & 0x3ff ) final_offset + + ;
e = uefi_call_wrapper ( ST - > BootServices - > GetMemoryMap , 5 , & mapSize , efi_memory , & mapKey , & descriptorSize , NULL ) ;
if ( EFI_ERROR ( e ) ) {
print_ ( " EFI error. \n " ) ;
while ( 1 ) { } ;
}
uint64_t upper_mem = 0 ;
int descriptors = mapSize / descriptorSize ;
for ( int i = 0 ; i < descriptors ; + + i ) {
EFI_MEMORY_DESCRIPTOR * d = efi_memory ;
mmap - > size = sizeof ( uint64_t ) * 2 + sizeof ( uint32_t ) ;
mmap - > base_addr = d - > PhysicalStart ;
mmap - > length = d - > NumberOfPages * 4096 ;
switch ( d - > Type ) {
case EfiConventionalMemory :
case EfiLoaderCode :
case EfiLoaderData :
case EfiBootServicesCode :
case EfiBootServicesData :
case EfiRuntimeServicesCode :
case EfiRuntimeServicesData :
mmap - > type = 1 ;
break ;
case EfiReservedMemoryType :
case EfiUnusableMemory :
case EfiMemoryMappedIO :
case EfiMemoryMappedIOPortSpace :
case EfiPalCode :
case EfiACPIMemoryNVS :
case EfiACPIReclaimMemory :
default :
mmap - > type = 2 ;
break ;
}
if ( mmap - > type = = 1 & & mmap - > base_addr > = 0x100000 ) {
upper_mem + = mmap - > length ;
}
mmap = ( mboot_memmap_t * ) ( ( uintptr_t ) mmap + mmap - > size + sizeof ( uint32_t ) ) ;
efi_memory = ( EFI_MEMORY_DESCRIPTOR * ) ( ( char * ) efi_memory + descriptorSize ) ;
}
finalHeader - > mmap_length = ( uintptr_t ) mmap - finalHeader - > mmap_addr ;
finalHeader - > mem_lower = 1024 ;
finalHeader - > mem_upper = upper_mem / 1024 ;
}
relocate_ramdisk ( ( void * ) ( uintptr_t ) finalHeader - > mods_addr ) ;
{
EFI_STATUS e ;
UINTN mapSize = 0 , mapKey , descriptorSize ;
UINT32 descriptorVersion ;
uefi_call_wrapper ( ST - > BootServices - > GetMemoryMap , 5 , & mapSize , NULL , & mapKey , & descriptorSize , NULL ) ;
e = uefi_call_wrapper ( ST - > BootServices - > ExitBootServices , 2 , ImageHandleIn , mapKey ) ;
if ( e ! = EFI_SUCCESS ) {
print_ ( " Exit services failed. \n " ) ;
print_hex_ ( e ) ;
while ( 1 ) { } ;
}
}
2023-01-05 09:39:44 +03:00
/* Jump to entry with register arguments */
2021-09-07 05:45:58 +03:00
__asm__ __volatile__ (
2023-01-05 09:39:44 +03:00
" jmp %0 " : : " r " ( _xmain ) , " a " ( MULTIBOOT_EAX_MAGIC ) , " b " ( finalHeader ) ) ;
2021-09-07 05:45:58 +03:00
__builtin_unreachable ( ) ;
}
void boot ( void ) {
UINTN count ;
EFI_HANDLE * handles ;
EFI_LOADED_IMAGE * loaded_image ;
EFI_FILE_IO_INTERFACE * efi_simple_filesystem ;
EFI_FILE * root ;
EFI_STATUS status ;
uefi_call_wrapper ( ST - > BootServices - > SetWatchdogTimer , 4 , 0 , 0 , 0 , NULL ) ;
clear_ ( ) ;
2021-10-26 10:13:50 +03:00
draw_logo ( 0 ) ;
2021-09-07 05:45:58 +03:00
for ( unsigned int i = 0 ; i < ST - > NumberOfTableEntries ; + + i ) {
2023-02-17 02:20:43 +03:00
/* ACPI 1 table pointer. */
2021-09-07 05:45:58 +03:00
if ( ST - > ConfigurationTable [ i ] . VendorGuid . Data1 = = 0xeb9d2d30 & &
ST - > ConfigurationTable [ i ] . VendorGuid . Data2 = = 0x2d88 & &
ST - > ConfigurationTable [ i ] . VendorGuid . Data3 = = 0x11d3 ) {
multiboot_header . config_table = ( uintptr_t ) ST - > ConfigurationTable [ i ] . VendorTable & 0xFFFFffff ;
break ;
}
2023-02-17 02:20:43 +03:00
/* ACPI 2 table pointer. */
if ( ST - > ConfigurationTable [ i ] . VendorGuid . Data1 = = 0x8868e871 & &
ST - > ConfigurationTable [ i ] . VendorGuid . Data2 = = 0xe4f1 & &
ST - > ConfigurationTable [ i ] . VendorGuid . Data3 = = 0x11d3 ) {
multiboot_header . config_table = ( uintptr_t ) ST - > ConfigurationTable [ i ] . VendorTable & 0xFFFFffff ;
break ;
}
2021-09-07 05:45:58 +03:00
}
status = uefi_call_wrapper ( ST - > BootServices - > HandleProtocol ,
3 , ImageHandleIn , & efi_loaded_image_protocol_guid ,
( void * * ) & loaded_image ) ;
if ( EFI_ERROR ( status ) ) {
print_ ( " Could not obtain loaded_image_protocol \n " ) ;
while ( 1 ) { } ;
}
print ( " Found loaded image... \n " ) ;
status = uefi_call_wrapper ( ST - > BootServices - > HandleProtocol ,
3 , loaded_image - > DeviceHandle , & efi_simple_file_system_protocol_guid ,
( void * * ) & efi_simple_filesystem ) ;
if ( EFI_ERROR ( status ) ) {
print_ ( " Could not obtain simple_file_system_protocol. \n " ) ;
while ( 1 ) { } ;
}
status = uefi_call_wrapper ( efi_simple_filesystem - > OpenVolume ,
2 , efi_simple_filesystem , & root ) ;
if ( EFI_ERROR ( status ) ) {
print_ ( " Could not open volume. \n " ) ;
while ( 1 ) { } ;
}
EFI_FILE * file ;
CHAR16 kernel_name [ 16 ] = { 0 } ;
{
char * c = kernel_path ;
char * ascii = c ;
int i = 0 ;
while ( * ascii ) {
kernel_name [ i ] = * ascii ;
i + + ;
ascii + + ;
}
if ( kernel_name [ i - 1 ] = = L ' . ' ) {
kernel_name [ i - 1 ] = 0 ;
}
}
/* Load kernel */
status = uefi_call_wrapper ( root - > Open ,
5 , root , & file , kernel_name , EFI_FILE_MODE_READ , 0 ) ;
if ( EFI_ERROR ( status ) ) {
print_ ( " Error opening kernel. \n " ) ;
while ( 1 ) { } ;
}
# define KERNEL_LOAD_START 0x4000000ULL
kernel_load_start = ( char * ) KERNEL_LOAD_START ;
{
EFI_PHYSICAL_ADDRESS addr = KERNEL_LOAD_START ;
EFI_ALLOCATE_TYPE type = AllocateAddress ;
EFI_MEMORY_TYPE memtype = EfiLoaderData ;
UINTN pages = 8192 ;
EFI_STATUS status = 0 ;
status = uefi_call_wrapper ( ST - > BootServices - > AllocatePages , 4 , type , memtype , pages , & addr ) ;
if ( EFI_ERROR ( status ) ) {
print_ ( " Could not allocate space to load boot payloads: " ) ;
print_hex_ ( status ) ;
print_ ( " " ) ;
print_hex_ ( addr ) ;
while ( 1 ) { } ;
}
}
unsigned int offset = 0 ;
UINTN bytes = 134217728 ;
status = uefi_call_wrapper ( file - > Read ,
3 , file , & bytes , ( void * ) KERNEL_LOAD_START ) ;
if ( EFI_ERROR ( status ) ) {
print_ ( " Error loading kernel. \n " ) ;
while ( 1 ) { } ;
}
offset + = bytes ;
while ( offset % 4096 ) offset + + ;
{
char * c = ramdisk_path ;
CHAR16 name [ 16 ] = { 0 } ;
char * ascii = c ;
int i = 0 ;
while ( * ascii ) {
name [ i ] = * ascii ;
i + + ;
ascii + + ;
}
if ( name [ i - 1 ] = = L ' . ' ) {
name [ i - 1 ] = = 0 ;
}
bytes = 134217728 ;
status = uefi_call_wrapper ( root - > Open ,
5 , root , & file , name , EFI_FILE_MODE_READ , 0 ) ;
if ( ! EFI_ERROR ( status ) ) {
status = uefi_call_wrapper ( file - > Read ,
3 , file , & bytes , ( void * ) ( uintptr_t ) ( KERNEL_LOAD_START + offset ) ) ;
if ( ! EFI_ERROR ( status ) ) {
ramdisk_off = KERNEL_LOAD_START + offset ;
ramdisk_len = bytes ;
} else {
print_ ( " Failed to read ramdisk \n " ) ;
}
} else {
print_ ( " Error opening " ) ; print_ ( c ) ; print_ ( " \n " ) ;
}
}
load_kernel ( ) ;
finish_boot ( ) ;
}
# else
struct mmap_entry {
uint64_t base ;
uint64_t len ;
uint32_t type ;
uint32_t reserved ;
} ;
extern unsigned short mmap_ent ;
extern unsigned short lower_mem ;
2021-06-14 05:11:37 +03:00
static void finish_boot ( void ) {
print ( " Setting up memory map... \n " ) ;
print_hex ( mmap_ent ) ;
print ( " \n " ) ;
memset ( kernel_load_start , 0x00 , 1024 ) ;
mboot_memmap_t * mmap = ( void * ) final_offset ;
multiboot_header . mmap_addr = ( uintptr_t ) mmap ;
multiboot_header . mods_addr = ( uintptr_t ) & modules_mboot ;
multiboot_header . boot_loader_name = ( uintptr_t ) VERSION_TEXT ;
struct mmap_entry * e820 = ( void * ) 0x5000 ;
uint64_t upper_mem = 0 ;
for ( int i = 0 ; i < mmap_ent ; + + i ) {
print ( " entry " ) ; print_hex ( i ) ;
print ( " " ) ; print_hex ( ( uint32_t ) ( e820 [ i ] . base > > 32ULL ) ) ; print_hex ( ( uint32_t ) e820 [ i ] . base ) ;
print ( " " ) ; print_hex ( ( uint32_t ) ( e820 [ i ] . len > > 32ULL ) ) ; print_hex ( ( uint32_t ) e820 [ i ] . len ) ;
print ( " " ) ; print_hex ( e820 [ i ] . type ) ; print ( " \n " ) ;
mmap - > size = sizeof ( uint64_t ) * 2 + sizeof ( uintptr_t ) ;
mmap - > base_addr = e820 [ i ] . base ;
mmap - > length = e820 [ i ] . len ;
mmap - > type = e820 [ i ] . type ;
if ( mmap - > type = = 1 & & mmap - > base_addr > = 0x100000 ) {
upper_mem + = mmap - > length ;
}
mmap = ( mboot_memmap_t * ) ( ( uintptr_t ) mmap + mmap - > size + sizeof ( uintptr_t ) ) ;
}
multiboot_header . mmap_length = ( uintptr_t ) mmap - multiboot_header . mmap_addr ;
print ( " lower " ) ; print_hex ( lower_mem ) ; print ( " KB \n " ) ;
multiboot_header . mem_lower = 1024 ;
print ( " upper " ) ;
print_hex ( upper_mem > > 32 ) ;
print_hex ( upper_mem ) ;
print ( " \n " ) ;
multiboot_header . mem_upper = upper_mem / 1024 ;
2021-06-14 06:06:31 +03:00
print ( " Jumping to kernel... \n " ) ;
2021-06-14 05:11:37 +03:00
uint32_t foo [ 3 ] ;
2021-09-07 05:45:58 +03:00
foo [ 0 ] = MULTIBOOT_EAX_MAGIC ;
foo [ 1 ] = ( unsigned int ) & multiboot_header ; ;
2021-06-14 05:11:37 +03:00
foo [ 2 ] = _xmain ;
__asm__ __volatile__ (
" mov %%cr0,%%eax \n "
/* Disable paging */
" and $0x7FFeFFFF, %%eax \n "
" mov %%eax,%%cr0 \n "
/* Ensure PAE is not enabled */
" mov %%cr4,%%eax \n "
" and $0xffffffdf, %%eax \n "
" mov %%eax,%%cr4 \n "
" mov %1,%%eax \n "
" mov %2,%%ebx \n "
" jmp *%0 " : : " g " ( foo [ 2 ] ) , " g " ( foo [ 0 ] ) , " g " ( foo [ 1 ] ) : " eax " , " ebx "
) ;
}
2021-10-19 14:29:44 +03:00
extern void do_bios_call ( uint32_t function , uint32_t arg1 ) ;
2021-10-19 14:10:59 +03:00
extern int bios_call ( char * into , uint32_t sector ) ;
static int spin_x = 0 ;
static void spin ( void ) {
static int spincnt = 0 ;
2021-10-26 10:13:50 +03:00
draw_logo ( spincnt + 1 ) ;
spincnt = ( spincnt + 1 ) & 0x7 ;
}
2021-10-19 14:10:59 +03:00
2021-10-26 10:13:50 +03:00
static void clear_spin ( void ) {
y = 16 ;
//print_banner("");
2021-10-19 14:10:59 +03:00
}
2021-10-19 14:29:44 +03:00
extern uint16_t * vbe_cont_info_mode_off ;
extern uint32_t * vbe_info_fbaddr ;
extern uint16_t vbe_info_pitch ;
extern uint16_t vbe_info_width ;
extern uint16_t vbe_info_height ;
extern uint8_t vbe_info_bpp ;
extern void bios_text_mode ( void ) ;
2021-06-14 05:11:37 +03:00
void boot ( void ) {
2021-10-19 14:29:44 +03:00
/* Did we ask for VGA text mode and are currently in a video mode? */
2021-11-04 14:44:22 +03:00
if ( boot_mode = = 5 ) {
2021-10-19 14:29:44 +03:00
bios_text_mode ( ) ;
}
2021-06-14 05:11:37 +03:00
clear_ ( ) ;
2021-10-26 10:13:50 +03:00
draw_logo ( 0 ) ;
2021-06-14 06:06:31 +03:00
print ( " Looking for ISO9660 filesystem... " ) ;
2021-06-14 05:11:37 +03:00
for ( int i = 0x10 ; i < 0x15 ; + + i ) {
2021-10-19 14:10:59 +03:00
bios_call ( ( char * ) ( DATA_LOAD_BASE + ISO_SECTOR_SIZE * i ) , i ) ;
2021-06-14 05:11:37 +03:00
root = ( void * ) ( DATA_LOAD_BASE + ISO_SECTOR_SIZE * i ) ;
switch ( root - > type ) {
case 1 :
2021-06-14 06:06:31 +03:00
print ( " found. \n " ) ;
2021-06-14 05:11:37 +03:00
goto done ;
}
}
return ;
done :
2021-06-14 06:06:31 +03:00
print ( " Looking for kernel... " ) ;
2021-06-14 05:11:37 +03:00
if ( ! navigate ( kernel_path ) ) {
print_ ( " Failed to locate kernel. \n " ) ;
return ;
}
2021-06-14 06:06:31 +03:00
print ( " found. \n " ) ;
2021-06-14 05:11:37 +03:00
kernel_load_start = ( char * ) ( DATA_LOAD_BASE + dir_entry - > extent_start_LSB * ISO_SECTOR_SIZE ) ;
2021-10-26 10:13:50 +03:00
print ( " Loading kernel... " ) ; spin_x = x ;
2021-10-19 14:10:59 +03:00
for ( int i = 0 , j = 0 ; i < dir_entry - > extent_length_LSB ; j + + ) {
if ( ! ( j & 0x3FF ) ) spin ( ) ;
bios_call ( kernel_load_start + i , dir_entry - > extent_start_LSB + j ) ;
i + = ISO_SECTOR_SIZE ;
}
2021-10-26 10:13:50 +03:00
print ( " \n " ) ;
2021-10-19 14:10:59 +03:00
2021-06-14 06:06:31 +03:00
print ( " Looking for ramdisk... " ) ;
2021-06-14 05:11:37 +03:00
if ( ! navigate ( ramdisk_path ) ) {
print_ ( " Failed to locate ramdisk. \n " ) ;
return ;
}
2021-06-14 06:06:31 +03:00
print ( " found. \n " ) ;
2021-06-14 05:11:37 +03:00
ramdisk_off = DATA_LOAD_BASE + dir_entry - > extent_start_LSB * ISO_SECTOR_SIZE ;
2021-10-19 14:10:59 +03:00
2021-10-26 10:13:50 +03:00
print ( " Loading ramdisk... " ) ; spin_x = x ;
2021-10-19 14:10:59 +03:00
for ( int i = 0 , j = 0 ; i < dir_entry - > extent_length_LSB ; j + + ) {
if ( ! ( j & 0x3FF ) ) spin ( ) ;
bios_call ( ( char * ) ( ramdisk_off + i ) , dir_entry - > extent_start_LSB + j ) ;
i + = ISO_SECTOR_SIZE ;
}
2021-10-26 10:13:50 +03:00
print ( " \n " ) ;
2021-10-19 14:10:59 +03:00
2021-06-14 05:11:37 +03:00
ramdisk_len = dir_entry - > extent_length_LSB ;
multiboot_header . cmdline = ( uintptr_t ) cmdline ;
2021-10-26 10:13:50 +03:00
draw_logo ( 0 ) ;
2021-10-19 14:29:44 +03:00
if ( vbe_info_width ) {
multiboot_header . framebuffer_addr = ( uint32_t ) vbe_info_fbaddr ;
multiboot_header . framebuffer_pitch = vbe_info_pitch ;
multiboot_header . framebuffer_width = vbe_info_width ;
multiboot_header . framebuffer_height = vbe_info_height ;
multiboot_header . framebuffer_bpp = vbe_info_bpp ;
}
2021-06-14 06:06:31 +03:00
print ( " Loading kernel from 0x " ) ; print_hex ( ( uint32_t ) kernel_load_start ) ; print ( " ... " ) ;
2021-06-14 05:11:37 +03:00
if ( ! load_kernel ( ) ) {
print_ ( " Failed to load kernel. \n " ) ;
return ;
}
2021-06-14 06:06:31 +03:00
print ( " Relocating ramdisk from 0x " ) ; print_hex ( ( uint32_t ) ramdisk_off ) ; print ( " :0x " ) ; print_hex ( ramdisk_len ) ; print ( " to 0x " ) ; print_hex ( final_offset ) ; print ( " ... " ) ;
2021-09-07 05:45:58 +03:00
relocate_ramdisk ( modules_mboot ) ;
2021-10-26 10:13:50 +03:00
2021-06-14 05:11:37 +03:00
finish_boot ( ) ;
}
2021-09-07 05:45:58 +03:00
# endif