linker.ld (same as the bare bones)
Code: Select all
ENTRY (loader)
SECTIONS{
. = 0x00100000;
.text :{
*(.text)
}
.rodata ALIGN (0x1000) : {
*(.rodata)
}
.data ALIGN (0x1000) : {
start_ctors = .;
*(.ctor*)
end_ctors = .;
start_dtors = .;
*(.dtor*)
end_dtors = .;
*(.data)
}
.bss : {
sbss = .;
*(COMMON)
*(.bss)
ebss = .;
}
}
Code: Select all
global loader ; making entry point visible to linker
extern _main ; kmain is defined elsewhere
; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
section .text
align 4
MultiBootHeader:
dd MAGIC
dd FLAGS
dd CHECKSUM
; reserve initial kernel stack space
STACKSIZE equ 0x4000 ; that's 16k.
extern start_ctors, end_ctors, start_dtors, end_dtors
_loader:
mov esp, stack+STACKSIZE ; set up the stack
push eax ; Multiboot magic number
push ebx ; Multiboot info structure
static_ctors_loop:
mov ebx, start_ctors
jmp .test
.body:
call [ebx]
add ebx,4
.test:
cmp ebx, end_ctors
jb .body
call _main ; call kernel proper
static_dtors_loop:
mov ebx, start_dtors
jmp .test
.body:
call [ebx]
add ebx,4
.test:
cmp ebx, end_dtors
jb .body
hlt ; halt machine should kernel return
section .bss
align 32
stack:
resb STACKSIZE ; reserve 16k stack on a quadword boundary
Code: Select all
/*
* kernel.cpp
*
* Created on: Oct 2, 2008
* Author: kllrnohj
*/
#include "include/multiboot.h"
extern "C" void _main (multiboot_info_t* mbd, unsigned int magic);
void cls();
/*
uncomment to also break the code
void BREAK_EVERYTHING() {}
*/
void _main (multiboot_info_t* mbd, unsigned int magic)
{
// cls(); <- BREAKS!
*((int*)0xb8000)=0x07690748;
for(;;);
}
void cls()
{
}
cppruntime.cpp
Code: Select all
/*
* cppruntime.cpp
*
* Created on: Oct 2, 2008
* Author: kllrnohj
*/
namespace __cxxabiv1
{
/* guard variables */
/* The ABI requires a 64-bit type. */
__extension__ typedef int __guard __attribute__((mode (__DI__)));
extern "C" int __cxa_guard_acquire (__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);
extern "C" int __cxa_guard_acquire (__guard *g)
{
return !*(char *)(g);
}
extern "C" void __cxa_guard_release (__guard *g)
{
*(char *)g = 1;
}
extern "C" void __cxa_guard_abort (__guard *)
{
}
}
extern "C" void __cxa_pure_virtual()
{
// print error message
}
extern "C"
{
int __cxa_atexit(void (*f)(void *), void *p, void *d);
void __cxa_finalize(void *d);
};
void *__dso_handle; /*only the address of this symbol is taken by gcc*/
struct object
{
void (*f)(void*);
void *p;
void *d;
} object[32] = {0};
unsigned int iObject = 0;
int __cxa_atexit(void (*f)(void *), void *p, void *d)
{
if (iObject >= 32) return -1;
object[iObject].f = f;
object[iObject].p = p;
object[iObject].d = d;
++iObject;
return 0;
}
/* This currently destroys all objects */
void __cxa_finalize(void *d)
{
unsigned int i = iObject;
for (; i > 0; --i)
{
--iObject;
object[iObject].f(object[iObject].p);
}
}
NASM is invoked as
nasm -f elf -o"$@" "$<"
G++ is invoked as
g++ -O0 -Wall -c -Wextra -nostdlib -nostartfiles -nodefaultlibs -fno-rtti -fno-builtin -fno-exceptions -fomit-frame-pointer -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
LD is invoked as
ld -T ../src/linker.ld -o"kernel.bin" $(OBJS) $(USER_OBJS) $(LIBS)
Platform is Ubuntu 8.04.
G++ version is 4.2.3
LD version is 2.18.0.20080103
NASM version is 0.99.06-20071101
I have used this same platform to successfully make a kernel in C, so the toolchain has previously worked fine. I am using Sun xVM VirtualBox and GRUB .97 with the VBE patch (I'm not setting a VBE mode yet, but I have tested that and it does work)
Now, when I say that it breaks, basically the "Hi" that should be printed never is. Either one of the commented out sections will cause the break.
And the build output is as follows
Building file: ../src/kernel.cpp
Invoking: GCC C++ Compiler
g++ -O0 -Wall -c -Wextra -nostdlib -nostartfiles -nodefaultlibs -fno-rtti -fno-builtin -fno-exceptions -fomit-frame-pointer -MMD -MP -MF"src/kernel.d" -MT"src/kernel.d" -o"src/kernel.o" "../src/kernel.cpp"
../src/kernel.cpp:13: warning: unused parameter ‘mbd’
../src/kernel.cpp:13: warning: unused parameter ‘magic’
Finished building: ../src/kernel.cpp
Building file: ../src/loader.asm
Invoking: GCC Assembler
nasm -f elf -o"src/loader.o" "../src/loader.asm"
Finished building: ../src/loader.asm
Building file: ../src/cppruntime/cppruntime.cpp
Invoking: GCC C++ Compiler
g++ -O0 -Wall -c -Wextra -nostdlib -nostartfiles -nodefaultlibs -fno-rtti -fno-builtin -fno-exceptions -fomit-frame-pointer -MMD -MP -MF"src/cppruntime/cppruntime.d" -MT"src/cppruntime/cppruntime.d" -o"src/cppruntime/cppruntime.o" "../src/cppruntime/cppruntime.cpp"
../src/cppruntime/cppruntime.cpp:52: warning: missing braces around initializer for ‘object’
../src/cppruntime/cppruntime.cpp:52: warning: missing initializer for member ‘object::p’
../src/cppruntime/cppruntime.cpp:52: warning: missing initializer for member ‘object::d’
../src/cppruntime/cppruntime.cpp:66: warning: unused parameter ‘d’
Finished building: ../src/cppruntime/cppruntime.cpp
Building target: kernel.bin
Invoking: GCC C++ Linker
ld -T ../src/linker.ld -o"kernel.bin" ./src/kernel.o ./src/loader.o ./src/cppruntime/cppruntime.o
ld: warning: cannot find entry symbol loader; defaulting to 0000000000100000
Finished building target: kernel.bin
make --no-print-directory post-build
cp kernel.bin ../iso/boot/ && mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o grub.iso ../iso
I: -input-charset not specified, using utf-8 (detected in locale settings)
Size of boot image is 4 sectors -> No emulation
Total translation table size: 2048
Total rockridge attributes bytes: 922
Total directory bytes: 4576
Path table size(bytes): 34
Max brk space used 0
233 extents written (0 MB)