1
Fork 0
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:
Liav A 2021-07-07 20:14:02 +03:00 committed by Gunnar Beutner
parent a95b726fd8
commit cc98871383
2 changed files with 88 additions and 58 deletions

View file

@ -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

View file

@ -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();