Kernel panic on attempted OS load
Posted: Sat Oct 15, 2011 2:32 pm
It is quite likely that nobody here remembers me, I haven't posted in over a year an a half at this point.
Some background first:
I am a Junior in CS specializing in Software Engineering. I have attempted to make an operating system before (1.5 years ago...) and that went to the stage of attempting to get a bootloader working. It didn't get anywhere and I decided that I didn't know enough to make it very far at that point. I am now back to attempt things again.
Basically, here is what I have: A basic C++ object-oriented kernel which (thanks to Bran's kernel dev tutorial) should be up to the point of printing a hello world message to the screen (I'll post code here in a second).
The problem: I can't for the life of me figure out how to make an ISO or grub-based floppy image which I can run (via GRUB) that will do anything. I have attempted to just put my image in the GRUB options and boot it on my dev machine but each attempt has resulted in a kernel panic (I will attempt to get the exact message here in a little bit).
So, I guess I am asking for any help people may have in getting my kernel booted successfully. Now for the code:
start.asm
main.cpp
system.h
memory.h
memory.cpp
port.h
port.cpp
TextMonitorDriver.h
TextMonitorDriver.cpp
link.ld
Makefile
Now, as I said, I have attempted booting a floppy image that I made based on this page's floppy disk images section (http://wiki.osdev.org/Disk_Images) and I have placed both the standard bin and the floppy image in the /boot directory and pointed to them via the menu.lst file. It occurs to me that I don't know much about how GRUB actually works so it is quite possible (probable in fact) that the biggest issue here is that I don't know how to set it up properly.
Here is the relevant portion of the menu.lst file (if you want the rest I can post it):
Any help would be appreciated. As you can probably tell, I am relatively new to OS development. While I have taken the OS course my university offers it was just an overview and relatively worthless in anything other than theory.
Again, thanks for any and all help.
~ BetaWar
Some background first:
I am a Junior in CS specializing in Software Engineering. I have attempted to make an operating system before (1.5 years ago...) and that went to the stage of attempting to get a bootloader working. It didn't get anywhere and I decided that I didn't know enough to make it very far at that point. I am now back to attempt things again.
Basically, here is what I have: A basic C++ object-oriented kernel which (thanks to Bran's kernel dev tutorial) should be up to the point of printing a hello world message to the screen (I'll post code here in a second).
The problem: I can't for the life of me figure out how to make an ISO or grub-based floppy image which I can run (via GRUB) that will do anything. I have attempted to just put my image in the GRUB options and boot it on my dev machine but each attempt has resulted in a kernel panic (I will attempt to get the exact message here in a little bit).
So, I guess I am asking for any help people may have in getting my kernel booted successfully. Now for the code:
start.asm
Code: Select all
[BITS 32]
global start
start:
mov esp, _sys_stack ; This points the stack to our new stack area
jmp stublet
; This part MUST be 4byte aligned, so we solve that issue using 'ALIGN 4'
ALIGN 4
mboot:
; Multiboot macros to make a few lines later more readable
MULTIBOOT_PAGE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_INFO equ 1<<1
MULTIBOOT_AOUT_KLUDGE equ 1<<16
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
EXTERN code, bss, end
; This is the GRUB Multiboot header. A boot signature
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM
; AOUT kludge - must be physical addresses. Make a note of these:
; The linker script fills in the data for these ones!
dd mboot
dd code
dd bss
dd end
dd start
; This is an endless loop here. Make a note of this: Later on, we
; will insert an 'extern _main', followed by 'call _main', right
; before the 'jmp $'.
stublet:
extern main
call main
jmp $
; Shortly we will add code for loading the GDT right here!
; In just a few pages in this tutorial, we will add our Interrupt
; Service Routines (ISRs) right here!
; Here is the definition of our BSS section. Right now, we'll use
; it just to store the stack. Remember that a stack actually grows
; downwards, so we declare the size of the data before declaring
; the identifier '_sys_stack'
SECTION .bss
resb 8192 ; This reserves 8KBytes of memory here
_sys_stack:
Code: Select all
#include "system.h"
int main(){
TextMonitorDriver monitor;
monitor.puts("Hello Modos!");
for(;;); // infinite loop
return 0;
}
Code: Select all
#ifndef SYSTEM_H
#define SYSTEM_H
#include "memory.h"
#include "port.h"
#include "TextMonitorDriver.h"
#endif
Code: Select all
#ifndef MEMORY_H
#define MEMORY_H
unsigned char* memcpy(unsigned char* dest, const unsigned char* src, int count);
unsigned char* memset(unsigned char* dest, unsigned char val, int count);
unsigned short* memsetw(unsigned short* dest, unsigned short val, int count);
unsigned int strlen(const char* str);
#endif
Code: Select all
#include "memory.h"
unsigned char* memcpy(unsigned char* dest, const unsigned char* src, int count){
const char* sp = (const char*)src;
char* dp = (char*)dest;
for(; count != 0; count--){
*dp = *sp;
dp++;
sp++;
}
return dest;
}
unsigned char* memset(unsigned char* dest, unsigned char val, int count){
char* temp = (char*)dest;
for(; count != 0; count--){
*temp = val;
temp++;
}
return dest;
}
unsigned short* memsetw(unsigned short* dest, unsigned short val, int count){
unsigned short* temp = (unsigned short*)dest;
for(; count != 0; count--){
*temp = val;
temp++;
}
return dest;
}
unsigned int strlen(const char* str){
unsigned int count;
for(count = 0; *str != '\0'; str++, count++);
return count;
}
Code: Select all
#ifndef PORT_H
#define PORT_H
unsigned char inportb(unsigned short _port);
void outportb(unsigned short _port, unsigned char _data);
#endif
Code: Select all
#include "port.h"
unsigned char inportb(unsigned short _port){
unsigned char rv;
__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
return rv;
}
void outportb(unsigned short _port, unsigned char _data){
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
Code: Select all
#ifndef TEXTMONITORDRIVER_H
#define TEXTMONITORDRIVER_H
#include "system.h"
class TextMonitorDriver{
private:
unsigned short* textmemptr;
int attrib;
int x;
int y;
public:
TextMonitorDriver(void);
void scroll(void);
void move(void);
void clear();
void putch(unsigned char c);
void puts(char* text);
void settextcolor(unsigned char forecolor, unsigned char backcolor);
};
#endif
Code: Select all
#include "TextMonitorDriver.h"
TextMonitorDriver::TextMonitorDriver(void){
x = y = 0;
textmemptr = (unsigned short*)0xb8000;
clear();
}
void TextMonitorDriver::scroll(void){
unsigned blank = 0x20 | (attrib << 8);
unsigned tmp;
if(y >= 25){
tmp = y - 24;
memcpy((unsigned char*)textmemptr, (unsigned char*)(textmemptr + tmp * 80), (25 - tmp) * 80 * 2);
memsetw(textmemptr + (25 - tmp) * 80, blank, 80);
y = 24;
}
}
void TextMonitorDriver::move(void){
unsigned tmp = y * 80 + x;
outportb(0x3D4, 14);
outportb(0x3D5, tmp >> 8);
outportb(0x3D4, 15);
outportb(0x3D5, tmp);
}
void TextMonitorDriver::clear(){
unsigned blank = 0x20 | (attrib << 8);
int i;
for(i = 0; i < 25; i++){
memsetw(textmemptr + i * 80, blank, 80);
}
x = y = 0;
move();
}
void TextMonitorDriver::putch(unsigned char c){
unsigned short* where;
unsigned att = attrib << 8;
if(c == 0x08 && x != 0){
x = 0;
}
else if(c == 0x09){
x = (x + 8) & !7;
}
else if(c == '\r'){
x = 0;
}
else if(c == '\n'){
x = 0;
y++;
}
else if(c >= ' '){
where = textmemptr + (y * 80 + x);
*where = c | att;
x++;
}
if(x >= 80){
x = 0;
y++;
}
scroll();
move();
}
void TextMonitorDriver::puts(char* text){
for(unsigned int i = 0, len = strlen(text); i < len; i++){
putch(text[i]);
}
}
void TextMonitorDriver::settextcolor(unsigned char forecolor, unsigned char backcolor){
attrib = (backcolor << 4) | (forecolor & 0x0f);
}
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS{
.text phys : AT(phys){
code = .;
*(.text)
*(.rodata)
. = ALIGN(4096);
}
.data : AT(phys + (data - code)){
data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code)){
bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .;
}
Code: Select all
.asm.o:
nasm -f aout -o $@ $^
.cpp.o:
g++ -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -c -o $@ $^
kernel.bin:start.o memory.o port.o TextMonitorDriver.o main.o
ld -T link.ld -o $@ $^
start.o:start.asm
nasm -f aout -o start.o start.asm
clean:
rm kernel.bin *.o
Here is the relevant portion of the menu.lst file (if you want the rest I can post it):
Code: Select all
# (3) modOS
title modOS
root (hd0,0)
kernel /vmlinuz26 root=/dev/disk/by-uuid/2f85c905-e9c7-4318-be77-30d2a186f3f3 ro
initrd /modos.bin
Again, thanks for any and all help.
~ BetaWar