Fix LOG_X usage crashing the system

Each `LOG_X` call declared a rather huge variable on the stack,
and using it to dump a whole structure often led to a page fault.
Now the temporary variables are `static`, which is a bit wasteful
on the kernel binary size, but easier to maintain.

Additionally bootloader updated to load kernels bigger than 64K.
This commit is contained in:
2026-08-25 17:20:34 +03:00
parent c92ccd41ce
commit a3240d9316
2 changed files with 41 additions and 51 deletions
+4 -2
View File
@@ -10,7 +10,6 @@ mov sp, 0x7000
FIRST_PARTITION_SECTOR equ 2048 ; TODO Read MBR. FIRST_PARTITION_SECTOR equ 2048 ; TODO Read MBR.
STAGE_BUFFER_SEGMENT equ 0x0900 STAGE_BUFFER_SEGMENT equ 0x0900
STAGE_BUFFER_OFFSET equ 0x0000 STAGE_BUFFER_OFFSET equ 0x0000
KERNEL_BUFFER_SEGMENT equ 0x2000
jmp prepare_kernel jmp prepare_kernel
@@ -41,6 +40,7 @@ data_start: dw 0
kernel_filename: db 'KERNEL BIN' kernel_filename: db 'KERNEL BIN'
kernel_cluster: dw 0 kernel_cluster: dw 0
kernel_buffer_segment: dw 0x2000
kernel_buffer_offset: dw 0 kernel_buffer_offset: dw 0
read_sectors: read_sectors:
@@ -192,7 +192,7 @@ load_kernel_cluster:
add ax, [data_start] add ax, [data_start]
xor cx, cx xor cx, cx
mov cl, [bpb.sectors_per_cluster] mov cl, [bpb.sectors_per_cluster]
mov bx, KERNEL_BUFFER_SEGMENT mov bx, [kernel_buffer_segment]
mov es, bx mov es, bx
mov di, [kernel_buffer_offset] mov di, [kernel_buffer_offset]
call read_sectors call read_sectors
@@ -201,6 +201,8 @@ load_kernel_cluster:
shl ax, 9 ; * 512 shl ax, 9 ; * 512
add ax, [kernel_buffer_offset] add ax, [kernel_buffer_offset]
mov [kernel_buffer_offset], ax mov [kernel_buffer_offset], ax
jnc find_next_kernel_cluster
add word [kernel_buffer_segment], 0x1000
find_next_kernel_cluster: find_next_kernel_cluster:
xor bx, bx xor bx, bx
+32 -44
View File
@@ -1,7 +1,6 @@
#pragma once #pragma once
#include "src/kernel/stream.h" #include "src/kernel/stream.h"
#include "src/lib/memory.h"
#include "src/lib/string.h" #include "src/lib/string.h"
extern stream_t *kernel_log; extern stream_t *kernel_log;
@@ -15,58 +14,47 @@ extern stream_t *kernel_log;
#define LOG_LEVEL_DATA 3 #define LOG_LEVEL_DATA 3
#define LOG_LEVEL_TRACE 4 #define LOG_LEVEL_TRACE 4
static uint64_t print_size;
static char print_buffer[512];
#define PRINT(stream, fmt, ...) \ #define PRINT(stream, fmt, ...) \
do { \ print_size = string_format(fmt, sizeof(print_buffer) - 1, print_buffer, ##__VA_ARGS__); \
uint64_t _size = string_length(fmt) * 10; \ stream->write(stream, print_buffer, print_size);
char *_string = memory_allocate(_size); \
_size = string_format(fmt, _size, _string, ##__VA_ARGS__); \
stream->write(stream, _string, _size); \
memory_free(_string); \
} while (0);
#define PRINT_LN(stream, fmt, ...) \ #define PRINT_LN(stream, fmt, ...) \
do { \ print_size = string_format(fmt, sizeof(print_buffer) - 1, print_buffer, ##__VA_ARGS__); \
uint64_t _size = string_length(fmt) * 10; \
char *_string = memory_allocate(_size); \
_size = string_format(fmt, _size, _string, ##__VA_ARGS__); \
stream->write(stream, __func__, string_length(__func__)); \ stream->write(stream, __func__, string_length(__func__)); \
stream->write(stream, ": ", 2); \ stream->write(stream, ": ", 2); \
stream->write(stream, _string, _size); \ stream->write(stream, print_buffer, print_size); \
stream->write(stream, "\n", 1); \ stream->write(stream, "\n", 1);
memory_free(_string); \
} while (0);
#define PRINT_VAL(stream, v, f) PRINT_LN(#v = f, v) #define PRINT_VAL(stream, v, f) PRINT_LN(#v = f, v)
#define LOG_INFO(fmt, ...) \ #define LOG(level, fmt, ...) \
if (LOG_LEVEL >= LOG_LEVEL_INFO) \ if (LOG_LEVEL >= level) { \
PRINT(kernel_log, fmt, ##__VA_ARGS__) PRINT(kernel_log, fmt, ##__VA_ARGS__) \
#define LOG_STEP(fmt, ...) \ }
if (LOG_LEVEL >= LOG_LEVEL_STEP) \
PRINT(kernel_log, fmt, ##__VA_ARGS__)
#define LOG_DATA(fmt, ...) \
if (LOG_LEVEL >= LOG_LEVEL_DATA) \
PRINT(kernel_log, fmt, ##__VA_ARGS__)
#define LOG_TRACE(fmt, ...) \
if (LOG_LEVEL >= LOG_LEVEL_TRACE) \
PRINT(kernel_log, fmt, ##__VA_ARGS__)
#define LOG_LN_INFO(fmt, ...) \ #define LOG_LN(level, fmt, ...) \
if (LOG_LEVEL >= LOG_LEVEL_INFO) \ if (LOG_LEVEL >= level) { \
PRINT_LN(kernel_log, fmt, ##__VA_ARGS__) PRINT_LN(kernel_log, fmt, ##__VA_ARGS__) \
#define LOG_LN_STEP(fmt, ...) \ }
if (LOG_LEVEL >= LOG_LEVEL_STEP) \
PRINT_LN(kernel_log, fmt, ##__VA_ARGS__)
#define LOG_LN_DATA(fmt, ...) \
if (LOG_LEVEL >= LOG_LEVEL_DATA) \
PRINT_LN(kernel_log, fmt, ##__VA_ARGS__)
#define LOG_LN_TRACE(fmt, ...) \
if (LOG_LEVEL >= LOG_LEVEL_TRACE) \
PRINT_LN(kernel_log, fmt, ##__VA_ARGS__)
#define LOG_VAL_INFO(v, f) LOG_LN_INFO(#v "=" f, v) #define LOG_VAL(level, v, f) LOG_LN(level, #v "=" f, v)
#define LOG_VAL_STEP(v, f) LOG_LN_STEP(#v "=" f, v)
#define LOG_VAL_DATA(v, f) LOG_LN_DATA(#v "=" f, v) #define LOG_INFO(fmt, ...) LOG(LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
#define LOG_VAL_TRACE(v, f) LOG_LN_TRACE(#v "=" f, v) #define LOG_STEP(fmt, ...) LOG(LOG_LEVEL_STEP, fmt, ##__VA_ARGS__)
#define LOG_DATA(fmt, ...) LOG(LOG_LEVEL_DATA, fmt, ##__VA_ARGS__)
#define LOG_TRACE(fmt, ...) LOG(LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__)
#define LOG_LN_INFO(fmt, ...) LOG_LN(LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
#define LOG_LN_STEP(fmt, ...) LOG_LN(LOG_LEVEL_STEP, fmt, ##__VA_ARGS__)
#define LOG_LN_DATA(fmt, ...) LOG_LN(LOG_LEVEL_DATA, fmt, ##__VA_ARGS__)
#define LOG_LN_TRACE(fmt, ...) LOG_LN(LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__)
#define LOG_VAL_INFO(v, f) LOG_VAL(LOG_LEVEL_INFO, v, f)
#define LOG_VAL_STEP(v, f) LOG_VAL(LOG_LEVEL_STEP, v, f)
#define LOG_VAL_DATA(v, f) LOG_VAL(LOG_LEVEL_DATA, v, f)
#define LOG_VAL_TRACE(v, f) LOG_VAL(LOG_LEVEL_TRACE, v, f)
void log_init(stream_t *log); void log_init(stream_t *log);