Attempt to jump into 32-bit kernels

This commit is contained in:
Pierre Pronchery 2018-04-07 05:40:21 +02:00
parent ec663f4669
commit fdd310cb0c
2 changed files with 53 additions and 26 deletions

View File

@ -43,6 +43,38 @@ _exit:
jmp 1b
.global _kernel32
.type _kernel32,function
_kernel32:
mov 0x8(%esp), %eax
push 0x4(%esp)
call *%eax
sub $0x4, %esp
ret
.global _kernel64
.type _kernel64,function
_kernel64:
mov $-1, %eax
ret
.global _setgdt
.type _setgdt,function
_setgdt:
lea gdt_descriptor, %ecx
/* set the offset of the GDT */
mov 0x4(%esp), %eax
mov %eax, 0x2(%ecx)
/* set the size of the GDT */
mov 0x8(%esp), %eax
mov %eax, (%ecx)
/* load the GDT */
lgdt (%ecx)
ret
/* start */
.global _start
.type _start, @function
@ -73,21 +105,6 @@ _start:
.size _start, . - _start
.global _setgdt
.type _setgdt,function
_setgdt:
lea gdt_descriptor, %ecx
/* set the offset of the GDT */
mov 0x4(%esp), %eax
mov %eax, 0x2(%ecx)
/* set the size of the GDT */
mov 0x8(%esp), %eax
mov %eax, (%ecx)
/* load the GDT */
lgdt (%ecx)
ret
.section .bss
.align 16
gdt_descriptor:

View File

@ -21,10 +21,17 @@
/* private */
/* types */
typedef int (*LoaderCallback)(ukMultibootInfo * mi, vaddr_t entrypoint);
/* prototypes */
static vaddr_t _loader_kernel(ukMultibootMod * mod);
static LoaderCallback _loader_kernel(ukMultibootMod * mod,
vaddr_t * entrypoint);
static int _loader_module(ukMultibootMod * mod);
extern int _kernel32(ukMultibootInfo * mi, vaddr_t entrypoint);
extern int _kernel64(ukMultibootInfo * mi, vaddr_t entrypoint);
/* platform-dependent */
#if defined(__i386__)
@ -98,7 +105,7 @@ static int _loader_gdt(GDT const * gdt, size_t size)
/* functions */
/* loader_kernel */
static vaddr_t _loader_kernel(ukMultibootMod * mod)
static LoaderCallback _loader_kernel(ukMultibootMod * mod, vaddr_t * entrypoint)
{
Elf32_Ehdr ehdr;
@ -106,22 +113,24 @@ static vaddr_t _loader_kernel(ukMultibootMod * mod)
if(mod->end < mod->start || mod->end - mod->start < sizeof(ehdr))
{
puts("Could not load kernel: Invalid format");
return 0x0;
return NULL;
}
memcpy(&ehdr, (void *)mod->start, sizeof(ehdr));
switch(ehdr.e_ident[EI_CLASS])
{
case ELFCLASS32:
puts("Detected 32-bit kernel");
break;
*entrypoint = ehdr.e_entry + mod->start;
return _kernel32;
case ELFCLASS64:
puts("Detected 64-bit kernel");
break;
*entrypoint = ehdr.e_entry + mod->start;
return _kernel64;
default:
puts("Could not load kernel: Invalid class");
return 0x0;
break;
}
return ehdr.e_entry;
return NULL;
}
@ -146,7 +155,8 @@ int main(ukMultibootInfo * mi)
const char msg_failed2[] = "No modules provided";
const char msg_failed3[] = "No kernel provided";
ukMultibootMod * mod;
vaddr_t entrypoint = 0x0;
LoaderCallback callback = NULL;
vaddr_t entrypoint;
bus = bus_init(LOADER_BUS);
console_init(bus, LOADER_CONSOLE);
@ -177,14 +187,14 @@ int main(ukMultibootInfo * mi)
{
mod = &mi->mods_addr[i];
if(i == 0)
entrypoint = _loader_kernel(mod);
callback = _loader_kernel(mod, &entrypoint);
else
_loader_module(mod);
}
if(entrypoint == 0x0)
if(callback == NULL)
{
puts("Could not load the kernel");
return 5;
}
return 0;
return callback(mi, entrypoint);
}