I chose to post here as opposed to the FreeBASIC forums, as OS development is newish/unexplored idea over there.
Now for the issue:
I decided to use assembly (NASM) and FreeBASIC to develop my OS. So far, I've only used assembly in the bootloader, but now I need both languages as I start my kernel. For my build process, I use a simple script (makefiles will eventually come) that assembles/compiles outdated sources. Then, I link them into a flat binary, put all files into an ISO image, and test things if necessary.
However, when I test my kernel code, I noticed that all sub/function calls between FB code acts strangely: calls are always off by a few bytes in memory (if I call a function at 0x100050, it jumps to 0x10005D, all functions are 16-byte-aligned with FB). This doesn't happen when NASM code calls FB code. I've already tweaked my linker script many times, and have tried both a cross-linking LD and JLoc, but the issue still remains.
The only time it stops is when I remove all "global" variables (those that start with Dim Shared, even though I just want variables visible in the whole translation unit), which removes the .ctors section(s). I know globals may require the runtime, but my linker doesn't complain about unresolved references, and rolling without globals is too annoying. Usually, I call the constructors myself by looping through the list of function pointers on startup.
My startup code (sorry for indentation issues):
Code: Select all
kentry: CLI
LEA ESP, [STACK_BASE + 0x2000]
JMP 0x08:loadnew_gdt
load_gdt: MOV AX, 0x10
MOV DS, AX
MOV ES, AX
MOV FS, AX
MOV GS, AX
MOV SS, AX
clear_bss: MOV EDI, SBSS
MOV ECX, EBSS
SUB ECX, EDI
SHR ECX, 0x02
XOR EAX, EAX
REP STOSD
do_ctors: MOV ESI, SCTORS
MOV ECX, ECTORS
SUB ECX, ESI
SHR ECX, 0x02
.loop: MOV EAX, [ESI]
CALL EAX
ADD ESI, 0x04
DEC ECX
JNZ .loop
;
; call KernelMain with pHwit parameter in EBX; should not return
;
gomain: PUSH EBX
CALL _kernelMain@4
CLI
HLT
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY (kentry)
SECTIONS{
. = 0x00100000;
.text :{
*(.stext)
*(.text)
}
.rodata ALIGN (0x1000) : {
*(.rodata)
SCTORS = .;
*(.ctors)
ECTORS = .;
}
.data ALIGN (0x1000) : {
*(.data)
}
.bss ALIGN (0x1000) : {
SBSS = .;
*(.bss)
EBSS = .;
}
.stack ALIGN (0x1000) : {
STACK_BASE = .;
*(.stack)
_KERNEL_END = .;
}
}