Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Hello again, sorry about the sudden wave of questions I just got back into this project. Well I have been writing my Kernel in C++ and am writing a Video driver and seem to be stuck when trying to boot my kernel.
I can load grub fine, I am unsure as to how to compile it to a .bin file using DevC++ . I tried just renaming the extension to find something weird happened.
Log from GRUB:
Booting 'OptimaOS'
root (fd0)
Filesystem type is fat, using whole disk
kernel /boot/kernel.bin
Error 13: Invalid or unsupported executable format
Press any key to continue...
As you can see something is going wrong. I am using the GRUB image by solar with my kernel in it. Any help is appreciated.
Have you got the multiboot header? I also suggest you use ELF since GRUB can understand that directly without you having to manually specify the length of .text, .data and .bss
Would I need to include the multiboot header in kernel.cpp ? I saw talk of it on the osfaq but didn't think much of it. Also mind enlightening me on what exactly ELF is?
Edit: Forgot to mention I am using Windows XP Professional if it makes any difference.
;Entry.asm
[BITS 32]
; Multiboot Header Flags
%define MBF_PAGEALIGN (1<<0) ; Load modules on 4KB Page boundarys
%define MBF_MEMMAP (1<<1) ; Give a memory map to us
%define MBF_VIDEOMODE (1<<2) ; VideoMode settings included
%define MBF_MANUALMAP (1<<16) ; Non-ELF executable type kludge used
; This loader's requested flags
%define MB_FLAGS MBF_PAGEALIGN | MBF_MEMMAP
%define MB_MAGIC 0x1BADB002
%define MB_INFOMAGIC 0x2BADB002
%define MB_CHECK -(MB_FLAGS + MB_MAGIC) ; Multiboot Checksum
; The actual declaration of what's above
MultibootHeader:
MBH_MAGIC: dd MB_MAGIC
MBH_FLAGS: dd MB_FLAGS
MBH_CHECK: dd MB_CHECK
; Multiboot Header Non-ELF kludge
[EXTERN __code] ; Imports from the linker script to fill this out
[EXTERN __dataend]
[EXTERN __bssend]
MBH_HEADERADR: dd MultibootHeader ; Physical address of this header in memory
MBH_LOADADR: dd __code ; Where to load in memory
MBH_LOADENDADR: dd __dataend ; End of the data seg
MBH_BSSENDADR: dd __bssend ; End of the BSS
MBH_ENTRYADR: dd _EntryPoint ; The Entrypoint...
; Multiboot Header Startup Videomode
MBH_VIDEOMODE: dd 1 ; 0=Graphics(VESA), 1=EGA Text
MBH_VIDWIDTH: dd 80 ; Text=Columns, Graphics=Pixels, Default=0
MBH_VIDHEIGHT: dd 25 ; Text=Rows, Graphics=Pixels, Default=0
MBH_VIDDEPTH: dd 0 ; Graphics=Color Depth, Text=0, Default=0
[GLOBAL _EntryPoint]
_EntryPoint:
CMP EAX, MB_INFOMAGIC
JNE MultibootNonCompliant
PUSH EBX
[EXTERN main]
CALL main
hlt
MultibootNonCompliant:
[EXTERN PANIC]
PUSH PanicText
CALL PANIC
hlt
[SECTION .data]
PanicText: db 'The Kernel was not loaded by a multiboot compliant loader, please use a compliant loader such as GRUB',0
If you use ELF then the kludge section doesn't need to be included, if you use anything else then add " | MBF_MANUALMAP" to MB_FLAGS.
I suggest you read the docs for GRUB here (Although I have pretty much just thrown you everything you need except for what's in the data struct that GRUB gives you)
If I include the header do I have to include that assembly? Also how would I compile into a .bin or can someone post information on ELF (I'm using Dev-CPP)
Usually you start the Kernel with an Assembly file since entering the C/C++ section of the Kernel directly will leave you with GRUB's stack, you should always move the stack to a known location at startup before using it to prevent accidentally overriding it.
To produce ELFs you use 'OUTPUT_FORMAT("elf32-i386")' in your linkscript, as to how to do that in Dev-Cpp I don't know. That assembly code should work as is, to link it just compile it with NASM/YASM and add the object file to LD's command line (Again, I don't know how to do this in Dev-Cpp). I personally use plain text editors, custom makefiles and a custom cross compiler to avoid issues with trying to bend IDEs and compilers to suit my purpose. You should be able to find out how to tinker with LD's commandline in the Dev-Cpp help files though.
My problem is I have multiple files and it exports as multiple .o files. I try to link them all together including the assembly but it fails.
This is when compiling with NASM using: nasmw -o Entry.o Entry.asm
Entry.asm:26: error: binary output format does not support external references
Entry.asm:27: error: binary output format does not support external references
Entry.asm:28: error: binary output format does not support external references
Entry.asm:44: error: binary output format does not support external references
Entry.asm:50: error: binary output format does not support external references
It still assembles but I think that might have to do with the problem.
This is when I try to link using: ld -T linker.ld Drivers.o Kernel.o Interrupts.o Video.o Entry.o
ld: warning: cannot find entry symbol _EntryPoint; defaulting to 00100000
Kernel.o(.text+0x10):Kernel.cpp: undefined reference to `_alloca'
Kernel.o(.text+0x18):Kernel.cpp: undefined reference to `__main'
_alloca is a Windows function that is used to expand the stack, you definetly don't want that in the Kernel, the __main is a reference to a Windows style main entry point, these may go away when you build as ELF, or they require a commandline argument (something like --no-alloca) to get rid of
I was expecting something like that, what that means is that the linker can't understand the ELF created by NASM, it also usually indicates that the linker can't produce ELFs either.