Page 1 of 2

N00b trying to write a kernel in C++

Posted: Thu Aug 11, 2005 3:57 pm
by amee2000
Hi!

Currently I'm playing around with writing my own OS. What's available on mega-tokyo.com and invalidsoftware.net/os is amazing and made getting started easier than I expected. Though I encounter some problems ...

The one I'm currently lost with is the following:

Among other things I red BareBones (http://www.osdev.org/osfaq2/index.php/BareBones) and this (http://www.invalidsoftware.net/os/).

BareBones worked. Then I tried to combine what I had from BareBones with a C++ kernel like the one on invalidsoftware.net/os which resulted in the following:

The loader from BareBones is mostly untouched except ...
multiboot.s contains the multiboot header from loader.s (this works)
The files core.cpp , core_video.cpp and core.h/video.h are attached in devel.tar.gz (REMOVE THE .ZIP EXTENSION!! It is "devel.tar.gz")
the linker script is c&p'ed from barebones

then I used the following bash scripts to compile that all together:

Code: Select all

#!/bin/bash
...
export SRC="src"

export CC="gcc"
export LNK="ld"
export ASM="as"
...

Code: Select all

#!/bin/bash

CCOPT="-Wall -Werror -nostdlib -nostartfiles -nodefaultlibs"

set -x

$CC -c $SRC/os/core_video.cpp -o $SRC/os/core_video.o $CCOPT
$CC -c $SRC/os/core.cpp -o $SRC/os/core.o $CCOPT
$ASM $SRC/os/loader.s -o $SRC/os/loader.o
$ASM $SRC/os/multiboot.s -o $SRC/os/multiboot.o
$LNK -T $SRC/aux/link_core.ld -o $SRC/os/core.bin \
    $SRC/os/multiboot.o \
    $SRC/os/core_video.o \
    $SRC/os/core.o $SRC/os/loader.o

set +x
So. the problem is that the linker returns the following error:

Code: Select all

+ ld -T src/aux/link_core.ld -o src/os/core.bin src/os/multiboot.o src/os/core_video.o src/os/core.o src/os/loader.o
src/os/core.o(.text+0x61): In function `main':
core.cpp: undefined reference to `_Unwind_Resume'
src/os/core.o(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
+
I never use "_Unwind_Resume" anywhere in my code. Where does it come from and how can I get rid of it or whatever I need to do?


Both my development and my test machine are VMWare.
Development:
Fedora Core 4
GCC 4.0.0 20050519 (Red Hat 4.0.0-8)

Re:N00b trying to write a kernel in C++

Posted: Thu Aug 11, 2005 5:24 pm
by Phugoid
That is a helper function used in C++ exception handling. You will need to turn exception handling off, or implement it yourself. There will also likely be other routines you will need to implement before you can do OS development with C++, depending on how much of C++ you decide to use. I think C++ is a little too high-level for early OS development.

Re:N00b trying to write a kernel in C++

Posted: Thu Aug 11, 2005 5:35 pm
by amee2000
After I red about GRUB and then that kernek-in-c++ howto it seemed to be a goot idea. at least better than doing most of it in ASM, which is what I originally assumed I'm required to do.
C++ provides native(right word?) support for classes. I assume this would make basic object handling easier. I anyway intended to forget exceptions for now and worry about that later, when I have something running that (I -?-) can crash ;)

Or what would you suggest?

EDIT: adding "-fno-exceptions" to CCOPT in the bash script solved that for now

Re:N00b trying to write a kernel in C++

Posted: Thu Aug 11, 2005 5:47 pm
by Phugoid
Good.

I assume you know this, but anyway: the hardware-level exceptions normally mentioned in this forum are generally unrelated to C++ exceptions. Nothing should stop you from implementing C++ exceptions in your kernel later though, of course. Ideally, you would never have anything that can crash ;)

The reason I suggested staying away from C++ is that I get nervous seeing a template class and inline assembly only a few lines from each other. But I don't think there is a very good reason why C++ should be avoided. Just be aware that there may be more to implement before you can get some built-in language features to work, unlike with C, which feels like portable assembly.

You should know where the GCC internals section is in the GCC manual.

Re:N00b trying to write a kernel in C++

Posted: Thu Aug 11, 2005 6:47 pm
by Colonel Kernel
Phugoid wrote:The reason I suggested staying away from C++ is that I get nervous seeing a template class and inline assembly only a few lines from each other.
But think about how templates could aid in portability... You could implement portable algorithms in template classes that take architecture-specific "policy" classes as template parameters. No more #ifdefs, messing around with include paths, using plain old functions that you'd rather inline, etc. :)

Re:N00b trying to write a kernel in C++

Posted: Fri Aug 12, 2005 1:09 am
by Solar
I'm not sure about using templates for hardware abstractions, but even with everything disabled that requires runtime support (exceptions for example), C++ still offers stricter type checking, namespaces, references, classes, and overloading of functions.

My recently restarted project now uses C because I want to keep it simple and stay away from all the runtime support stuff (as this is often compiler-specific). But I still believe strongly that using C++ is worthwhile even if you use nothing but namespaces, references, and overloading.

Re:N00b trying to write a kernel in C++

Posted: Fri Aug 12, 2005 3:05 am
by JoeKayzA
Phugoid wrote: The reason I suggested staying away from C++ is that I get nervous seeing a template class and inline assembly only a few lines from each other. But I don't think there is a very good reason why C++ should be avoided. Just be aware that there may be more to implement before you can get some built-in language features to work, unlike with C, which feels like portable assembly.
The reason why I switched to C++ recently is that my programming style simply is object oriented, no matter which language I'm using. And I believe that object orientation is very well suited for system code anyway (hardware abstraction). But, at the lowest levels of course, you should stay away from high level constructs like exceptions. And you should also be careful with virtuals.


cheers Joe

Re:N00b trying to write a kernel in C++

Posted: Fri Aug 12, 2005 3:31 am
by Solar
I still remember what made me adamantly believe in the suitability of C++ in kernel space: kout.

You remember the pains you go through implementing kprintf(), that one monolithic function that gets extended by additional format specifiers all the time, and a wrong format string / parameter list gets you into all kinds of trouble?

I dug up a few lines from my old C++ kernel. Assume that put(char) writes a character.

Code: Select all

void KVideo::write( char const * ptr )
{
    while ( *ptr )
    {
        put(*ptr++);
    }
}

KVideo& KVideo::operator<<( char const * ptr )
{
    write(ptr);
    return *this;
}

KVideo& KVideo::operator<<( char const c )
{
    put(c);
    return *this;
}

KVideo& KVideo::operator<<( void * )
{
    std::uintptr_t address = reinterpret_cast< std::uintptr_t >( ptr );
    std::uint_fast8_t tmpNumericBase = mNumericBase;
    mNumericBase = 16;
    operator<<( address );
    mNumericBase = tmpNumericBase;
    return *this;
}

KVideo& KVideo::operator<<( void (*formatter)() )
{
    formatter();
    return *this;
}

KVideo& KVideo::operator<<( std::intmax_t integer )
{
    std::uintmax_t newint;
    if ( integer < 0 )
    {
        put('-');
        newint = integer * -1;
    }
    else
    {
        newint = integer;
    }
    return operator<<(newinteger);
}

void endl()
{
    KVideo::put('\n');
}

void hex()
{
    KVideo::setBase(16);
}

void dec()
{
    KVideo::setBase(10);
}

void KVideo::setBase( std::uint_fast8_t const )
{
    mNumericBase = base;
}
Add to that a function that converts (and write()s) an uintmax_t to a char string in whatever mNumericBase is set to (easy)...

...and...

Code: Select all

KVideo kout;

int _main( multiboot_data* mbd, uint32_t magic )
{
    if ( magic != 0x2BADB002 )
    {
        kout << "ERROR! Magic number expected '0x2BADB002', found '" << hex << magic << "'!" << endl;
        return;
    }
    kout << "Multiboot data at " << mbd << endl;
    kout << "The answer to all questions is " << dec << 42 << endl;
}
Beat that. Well-done C++ is a thing of beauty. ;)

N00b trying to write ISR in C++

Posted: Fri Aug 12, 2005 6:30 pm
by amee2000
New night, new problem.

I assume it is better to reuse this threat rather than spamming the forum with "N00b trying to ... in C++" threads:)


While trying to write the keyboard driver I encountered the following problem with my ISR:

While researching about how to write an ISR with GCC, using "__attribute__ (( signal, naked ))" was suggested several times and seemed to me to be a quite elegant solution. Unfortunately it didn't work:

keybd.h:

Code: Select all

class core_Keybd {
   public:
      /* ... */
   private:
      /* ... */
      void isr_keybd(void) __attribute__ (( signal, naked )); /* this is line 35 */
};
keybd.cpp:

Code: Select all

#include "../modules.h/keybd.h"
/* ... */
void isr_keybd(void) {
   /* nothing here for now */
}
Trying to compile that resulted in the following error message:

Code: Select all

+ gcc -c src/os/modules/keybd.cpp -o src/os/modules/keybd.o -Wall -Werror -nostdlib -nostartfiles -nodefaultlibs -fno-exceptions
cc1plus: warnings being treated as errors
src/os/modules/../modules.h/keybd.h:35: warning: `signal' attribute directive ignored
src/os/modules/../modules.h/keybd.h:35: warning: `naked' attribute directive ignored
Grepping the GNU GC manual, I found out that neither the "naked" attribute nor "signal", "interrupt" or "interrupt_handler" are supported by GCC on the x86 architecture :(

http://gcc.gnu.org/onlinedocs/gcc-4.0.1 ... butes.html

Is there a way to do an ISR with GCC without additional ASM?

Re:N00b trying to write a kernel in C++

Posted: Fri Aug 12, 2005 9:06 pm
by AR
I don't know any way to avoid the assembly stubs, but that code is bad. You cannot declare an ISR as a member of a class as the CPU is not going to give you the "this" pointer (although you could use "friend" and have the function externally but still with access to class members). Your actual declaration isn't correct in that context either (your missing the class/namespace prefix on the function name in the CPP), it should be "void core_Keybd::isr_keybd()"

Re:N00b trying to write a kernel in C++

Posted: Sat Aug 13, 2005 2:20 am
by amee2000
Doesn't the address operator give me the 'global' address of that function, which I can use to get it called by the interrupt?

Implementing Device drivers as Classes, I can load the Class as often as I want (Serial port driver would allow more than one where Keybd would check and complain) and I use an address table at a fixed location to index all the drivers (with descriptor, to clarify the device type and driver version) So every driver instance will need its own ISR. The other solution would be one system-wide ISR where drivers can register with. What I don't like are driver-specific but system-provided generic ISRs.

It is my first OS and I don't think this approach is common practice but I think I can get it up and running :)

Re:N00b trying to write a kernel in C++

Posted: Sat Aug 13, 2005 2:26 am
by AR
ok, I'll try to explain the ABI: When a function is a member of a class it recieves a hidden parameter, the parameter is called the "this" pointer, it is a pointer to the class instance the function belongs to (the code only exists once but the internal variables are duplicated for each instance, the "this" pointer points to the internal variables for the current instance being operated on).

So your "void isr_keybd(void)" is really "void isr_keybd(core_Keybd *this)", and like I said, the CPU will not fill the "this" parameter so you cannot have it as a class member.

Re:N00b trying to write a kernel in C++

Posted: Sat Aug 13, 2005 3:17 am
by amee2000
Ah. That makes things clearer.

My attempt to make the ISR member of a class would trash the stack because it would try to pop a dword which has never been pushed, right?

What when I fetch the this pointer from the index table and put it on the stack before calling my C ISR? This would give me per-driver generic ISRs

Re:N00b trying to write a kernel in C++

Posted: Sat Aug 13, 2005 3:25 am
by Legend
Something along the lines of http://doc.trolltech.com/3.3/signalsandslots.html might be interesting for you!

Re:N00b trying to write a kernel in C++

Posted: Sat Aug 13, 2005 6:26 am
by amee2000
Interresting ... Let me think over that for a while!