Passing data block from boot loader to the kernel
Posted: Thu Aug 25, 2022 9:23 pm
Just as a heads' up for those who have been helping me so far, I am now having an issue where the second stage loader is supposed to pass some data to the kernel, but the kernel isn't finding the data block at the memory address I expected it to be at.
The plan had been to place the data block on the stack, but I quickly realized that a) this conflicted with how I was intending page map the stack, b) it would leave the kernel with an extremely small usable stack, and c) passing the large amount of data in question would present a problem when defining the function signature for the kernel's main function. I may revisit that idea later, but for now, I am just passing the data as a block at the end of the first 64KiB of the kernel memory. A more complete solution would almost certainly involve a more elaborate setup for the page mapping.
Right now, I am - despite some misgivings on this - hard-coding the address I expect the data block to be at. I do define an enum representing the offsets into this block, but I am not certain if it is a correct reflection of the data block in memory.
The code in the kernel right now is:
The code which moves the data block to FFFF:FFFC (which should be mapped to 0xC000FFFC in virtual memory) is here:
...
The goal of the transfer code is to write first the number of entries in the memory map, followed by the memory map itself, followed by the disk ID, and then finally followed by the entire FAT for the floppy disk.
Right now, it isn't finding any data at that location at all - it's all zeroed memory.
The plan had been to place the data block on the stack, but I quickly realized that a) this conflicted with how I was intending page map the stack, b) it would leave the kernel with an extremely small usable stack, and c) passing the large amount of data in question would present a problem when defining the function signature for the kernel's main function. I may revisit that idea later, but for now, I am just passing the data as a block at the end of the first 64KiB of the kernel memory. A more complete solution would almost certainly involve a more elaborate setup for the page mapping.
Right now, I am - despite some misgivings on this - hard-coding the address I expect the data block to be at. I do define an enum representing the offsets into this block, but I am not certain if it is a correct reflection of the data block in memory.
The code in the kernel right now is:
Code: Select all
/* kernel.c */
#include <stdint.h>
#include "terminal.h"
#include "mem_map.h"
#define KDATA_OFFSET 0xc000fffc
enum KData
{
mmap_cnt = 0,
mmap = mmap_cnt + 1 + (24 * 16),
drive_id,
fat = drive_id + 1 + (9 * (512 / 4))
};
void kernel_main()
{
clear_screen();
kprints("Starting Kernel...\n\n", CYAN, BLACK, 0);
uint32_t* fs_data = (uint32_t *) KDATA_OFFSET;
kprints("Passed Data offset ", WHITE, BLACK, 0);
kprintu((uint32_t)(fs_data + 1), 16, WHITE, BLACK, 0);
kprints("\nDrive ID: ", WHITE, BLACK, 0);
kprintu(*(fs_data - drive_id), 16, WHITE, BLACK, 0);
kprints("\nFAT offset ", WHITE, BLACK, 0);
kprintu((uint32_t)(fs_data - drive_id - 1), 16, WHITE, BLACK, 0);
kprints("\nMemory Map Table offset ", WHITE, BLACK, 0);
kprintu((uint32_t)(fs_data - mmap_cnt - 1), 16, WHITE, BLACK, 0);
print_mmap(*(fs_data - mmap_cnt), (struct memory_map_entry*)(fs_data - mmap));
}
Code: Select all
kernel_base equ 0xffff
kdata_offset equ 0xfffc
struc KData
.mmap_cnt resd 1
.mmap resd High_Mem_Map_size * 16
.drive resd 1
.fat resd fat_size
endstruc
Code: Select all
;; Attempt to get the full physical memory map for the system
;; this must be done before the move to protected mode
get_mem_maps:
; get the low memory map
write low_mem
int LMBIOS
mov si, print_buffer
call print_decimal_word
write kbytes
; get the high memory map
push es
push si
push di
push bp
mov ax, kernel_base
mov es, ax
mov di, (kdata_offset - KData.mmap - mem_map_buffer_size)
mov si, (kdata_offset - KData.mmap_cnt)
call get_hi_memory_map
mov di, (kdata_offset - KData.mmap - mem_map_buffer_size)
mov bp, es:[kdata_offset - KData.mmap_cnt]
call print_hi_mem_map
pop bp
pop di
pop si
pop es
load_kernel_data:
push ax
push es
mov ax, kernel_base
mov es, ax
mov dx, word [bp - stg2_parameters.drive]
mov es:[kdata_offset - KData.drive], edx
lea ax, es:[kdata_offset - KData.fat - fat_size]
memcopy_rm ax, [bp - stg2_parameters.fat_0], fat_size
pop es
pop ax
Right now, it isn't finding any data at that location at all - it's all zeroed memory.