mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 22:57:44 +00:00
Kernel: Print if image has become too large again
Instead of just disabling interrupts and halting when entering the C++ section, just halt with a printed message indicating the error.
This commit is contained in:
parent
a95b726fd8
commit
cc98871383
2 changed files with 88 additions and 58 deletions
|
@ -110,54 +110,47 @@ gdt64ptr:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
start:
|
start:
|
||||||
cli
|
jmp real_start
|
||||||
cld
|
|
||||||
|
|
||||||
#if ARCH(X86_64)
|
/*
|
||||||
/* test for long mode presence, save the most important registers from corruption */
|
this function assumes that paging is disabled (or everything is mapped 1:1)
|
||||||
pushl %eax
|
param 1: pointer to string ended with null terminator (C string)
|
||||||
pushl %edx
|
*/
|
||||||
pushl %ebx
|
print_and_halt:
|
||||||
|
|
||||||
movl $0x80000001, %eax
|
.equ COPIED_STRING_LOCATION, 0x400
|
||||||
cpuid
|
|
||||||
testl $(1 << 29), %edx /* Test if the LM-bit, which is bit 29, is set in the edx register. */
|
|
||||||
jnz continue /* If LM-bit is not enabled, there is no long mode. */
|
|
||||||
|
|
||||||
/* from now on, we don't really care about booting because we don't have long mode supported.
|
|
||||||
the flow from now is like so:
|
|
||||||
1. Copy all necessary parts to low memory section in RAM
|
|
||||||
2. Jump to that section
|
|
||||||
3. In that section we do:
|
|
||||||
a. exit protected mode to pure 16 bit real mode
|
|
||||||
b. load the "Long mode is not supported" String, call the BIOS print to screen service
|
|
||||||
c. halt
|
|
||||||
*/
|
|
||||||
|
|
||||||
.equ NO_LONG_MODE_STRING_LOCATION, 0x400
|
|
||||||
.equ GDT_REAL_MODE_LOCATION, 0x45000
|
.equ GDT_REAL_MODE_LOCATION, 0x45000
|
||||||
.equ EXITING_PROTECTED_MODE_CODE_LOCATION, 0x10000
|
.equ EXITING_PROTECTED_MODE_CODE_LOCATION, 0x10000
|
||||||
.equ REAL_MODE_CODE, 0x500
|
.equ REAL_MODE_CODE, 0x500
|
||||||
.equ PROTECTED_MODE_16_BIT_CODE, 0x600
|
.equ PROTECTED_MODE_16_BIT_CODE, 0x600
|
||||||
|
mov %esp, %ebp
|
||||||
|
mov 4(%ebp), %edi
|
||||||
|
|
||||||
/* Copy no_long_mode_string to low memory section */
|
/* Copy string to low memory section */
|
||||||
lea no_long_mode_string, %eax
|
mov %edi, %esi
|
||||||
lea exiting_real_mode, %ebx
|
xor %ecx, %ecx
|
||||||
sub $0xc0000000, %ebx
|
|
||||||
sub $0xc0000000, %eax
|
|
||||||
|
|
||||||
movl %ebx, %ecx
|
pushl %eax
|
||||||
sub %eax, %ecx
|
pushl %edi
|
||||||
mov %eax, %esi /* source address of the code */
|
check_string_length:
|
||||||
movw %cx, (NO_LONG_MODE_STRING_LOCATION)
|
movb (%edi), %ah
|
||||||
mov $NO_LONG_MODE_STRING_LOCATION+2, %edi /* destination address of the code */
|
cmp $0, %ah
|
||||||
|
je check_string_length_exit
|
||||||
|
inc %ecx
|
||||||
|
inc %edi
|
||||||
|
jmp check_string_length
|
||||||
|
check_string_length_exit:
|
||||||
|
popl %edi
|
||||||
|
popl %eax
|
||||||
|
|
||||||
|
/* source address of the code is ESI */
|
||||||
|
movw %cx, (COPIED_STRING_LOCATION)
|
||||||
|
mov $COPIED_STRING_LOCATION + 2, %edi /* destination address of the code */
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
/* Copy gdt_table_real_mode to low memory section */
|
/* Copy gdt_table_real_mode to low memory section */
|
||||||
lea gdt_table_real_mode, %eax
|
movl $(gdt_table_real_mode - KERNEL_BASE), %eax
|
||||||
lea gdt_table_real_mode_end, %ebx
|
movl $(gdt_table_real_mode_end - KERNEL_BASE), %ebx
|
||||||
sub $0xc0000000, %ebx
|
|
||||||
sub $0xc0000000, %eax
|
|
||||||
|
|
||||||
movl %ebx, %ecx
|
movl %ebx, %ecx
|
||||||
sub %eax, %ecx
|
sub %eax, %ecx
|
||||||
|
@ -166,10 +159,8 @@ start:
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
/* Copy protected_mode_16_bit to real_mode to low memory section */
|
/* Copy protected_mode_16_bit to real_mode to low memory section */
|
||||||
lea protected_mode_16_bit, %eax
|
movl $(protected_mode_16_bit - KERNEL_BASE), %eax
|
||||||
lea real_mode, %ebx
|
movl $(real_mode - KERNEL_BASE), %ebx
|
||||||
sub $0xc0000000, %ebx
|
|
||||||
sub $0xc0000000, %eax
|
|
||||||
|
|
||||||
movl %ebx, %ecx
|
movl %ebx, %ecx
|
||||||
sub %eax, %ecx
|
sub %eax, %ecx
|
||||||
|
@ -177,11 +168,9 @@ start:
|
||||||
mov $PROTECTED_MODE_16_BIT_CODE, %edi /* destination address of the code */
|
mov $PROTECTED_MODE_16_BIT_CODE, %edi /* destination address of the code */
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
/* Copy real_mode to continue to low memory section */
|
/* Copy real_mode to end_of_print_and_halt_function to low memory section */
|
||||||
lea real_mode, %eax
|
movl $(real_mode - KERNEL_BASE), %eax
|
||||||
lea continue, %ebx
|
movl $(end_of_print_and_halt_function - KERNEL_BASE), %ebx
|
||||||
sub $0xc0000000, %ebx
|
|
||||||
sub $0xc0000000, %eax
|
|
||||||
|
|
||||||
movl %ebx, %ecx
|
movl %ebx, %ecx
|
||||||
sub %eax, %ecx
|
sub %eax, %ecx
|
||||||
|
@ -191,10 +180,8 @@ start:
|
||||||
|
|
||||||
|
|
||||||
/* Copy all opcodes from exiting_real_mode label to protected_mode_16_bit label to low memory RAM */
|
/* Copy all opcodes from exiting_real_mode label to protected_mode_16_bit label to low memory RAM */
|
||||||
lea exiting_real_mode, %eax
|
movl $(exiting_real_mode - KERNEL_BASE), %eax
|
||||||
lea protected_mode_16_bit, %ebx
|
movl $(protected_mode_16_bit - KERNEL_BASE), %ebx
|
||||||
sub $0xc0000000, %ebx
|
|
||||||
sub $0xc0000000, %eax
|
|
||||||
|
|
||||||
movl %ebx, %ecx
|
movl %ebx, %ecx
|
||||||
sub %eax, %ecx
|
sub %eax, %ecx
|
||||||
|
@ -227,6 +214,9 @@ gdt_table_real_mode_end:
|
||||||
no_long_mode_string:
|
no_long_mode_string:
|
||||||
.asciz "Your computer does not support long mode (64-bit mode). Halting!"
|
.asciz "Your computer does not support long mode (64-bit mode). Halting!"
|
||||||
|
|
||||||
|
kernel_image_too_big_string:
|
||||||
|
.asciz "Error: Kernel Image too big for memory slot. Halting!"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This part is completely standalone - it doesn't involve any location from this
|
This part is completely standalone - it doesn't involve any location from this
|
||||||
near code. It uses arbitrary locations in the low memory section of the RAM.
|
near code. It uses arbitrary locations in the low memory section of the RAM.
|
||||||
|
@ -292,19 +282,64 @@ real_mode:
|
||||||
movb $0x13, %ah
|
movb $0x13, %ah
|
||||||
movb $0x0, %bh
|
movb $0x0, %bh
|
||||||
movb $0xf, %bl
|
movb $0xf, %bl
|
||||||
movw (NO_LONG_MODE_STRING_LOCATION), %cx
|
movw (COPIED_STRING_LOCATION), %cx
|
||||||
movw $0, %dx
|
movw $0, %dx
|
||||||
movw $NO_LONG_MODE_STRING_LOCATION + 2, %bp
|
movw $COPIED_STRING_LOCATION + 2, %bp
|
||||||
int $0x10
|
int $0x10
|
||||||
|
|
||||||
movl $0xdeadcafe, %ebx
|
movl $0xdeadcafe, %ebx
|
||||||
cli
|
cli
|
||||||
hlt
|
hlt
|
||||||
|
end_of_print_and_halt_function:
|
||||||
|
|
||||||
|
.code32
|
||||||
|
real_start:
|
||||||
|
cli
|
||||||
|
cld
|
||||||
|
mov $end_of_kernel_image, %esi
|
||||||
|
cmp $0xc2000000, %esi
|
||||||
|
jbe kernel_not_too_large
|
||||||
|
|
||||||
|
movl $(kernel_image_too_big_string - KERNEL_BASE), %esi
|
||||||
|
pushl %esi
|
||||||
|
call print_and_halt
|
||||||
|
/* We should not return, but just in case, halt */
|
||||||
|
hlt
|
||||||
|
|
||||||
|
kernel_not_too_large:
|
||||||
|
|
||||||
|
|
||||||
|
#if ARCH(X86_64)
|
||||||
|
/* test for long mode presence, save the most important registers from corruption */
|
||||||
|
pushl %eax
|
||||||
|
pushl %edx
|
||||||
|
pushl %ebx
|
||||||
|
|
||||||
|
movl $0x80000001, %eax
|
||||||
|
cpuid
|
||||||
|
testl $(1 << 29), %edx /* Test if the LM-bit, which is bit 29, is set in the edx register. */
|
||||||
|
jnz long_mode_supported /* If LM-bit is not enabled, there is no long mode. */
|
||||||
|
|
||||||
|
/* from now on, we don't really care about booting because we don't have long mode supported.
|
||||||
|
the flow from now is like so:
|
||||||
|
1. Copy all necessary parts to low memory section in RAM
|
||||||
|
2. Jump to that section
|
||||||
|
3. In that section we do:
|
||||||
|
a. exit protected mode to pure 16 bit real mode
|
||||||
|
b. load the "Long mode is not supported" String, call the BIOS print to screen service
|
||||||
|
c. halt
|
||||||
|
*/
|
||||||
|
movl $(no_long_mode_string - KERNEL_BASE), %esi
|
||||||
|
pushl %esi
|
||||||
|
call print_and_halt
|
||||||
|
/* We should not return, but just in case, halt */
|
||||||
|
hlt
|
||||||
|
|
||||||
|
|
||||||
/* If long mode is supported, continue with booting the system */
|
/* If long mode is supported, continue with booting the system */
|
||||||
|
|
||||||
.code32
|
.code32
|
||||||
continue:
|
long_mode_supported:
|
||||||
/* restore the pushed registers and continue with booting */
|
/* restore the pushed registers and continue with booting */
|
||||||
popl %ebx
|
popl %ebx
|
||||||
popl %edx
|
popl %edx
|
||||||
|
|
|
@ -107,11 +107,6 @@ static Processor s_bsp_processor; // global but let's keep it "private"
|
||||||
|
|
||||||
extern "C" [[noreturn]] UNMAP_AFTER_INIT void init()
|
extern "C" [[noreturn]] UNMAP_AFTER_INIT void init()
|
||||||
{
|
{
|
||||||
if ((FlatPtr)&end_of_kernel_image >= 0xc2000000u) {
|
|
||||||
// The kernel has grown too large again!
|
|
||||||
asm volatile("cli;hlt");
|
|
||||||
}
|
|
||||||
|
|
||||||
g_in_early_boot = true;
|
g_in_early_boot = true;
|
||||||
setup_serial_debug();
|
setup_serial_debug();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue