Migrating Mattise to C++

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.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Migrating Mattise to C++

Post by pcmattman »

I'm embarking on a massive project - to convert Mattise from the C kernel it is now into a C++ kernel.

Why? I hear you ask...

Because I like the power of C++, templates have always appealed to me. For instance, I can create a linked list template that does all the allocation and leaves me to just provide a struct type with 'next' and 'prev' fields.

Because classes can make my code much neater, and make my life much easier. I've already simplified the console output system by migrating it to a class.

And because my kernel is finally stable and I couldn't be bothered adding a shell yet...

Of course, the old C version will still be available, and for the next couple of months will continue to be maintained (but no new features).
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Good luck - I've often wondered about doing this myself as I like the idea of oop for OS dev - my normal dev environment is c#.

I am a little concerned about how much c++ hides from the programmer though - with C, I feel fairly confident about where all my data and code are at any particular point. I would be quite interested to see how your conversion progresses - it may inspire me to do the same.

Cheers,
Adam
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

I suggest you go with the conversion by first making your C kernel compile as C++ without actually changing anything else, and then slowly replacing stuff with classes, so you can have a working kernel all the time. I've converted projects from C to C++ with this method, and in the end it's much less work than just rewriting in C++ directly.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

You know a lot of Operating Systems (Most..) refuse C++ in the kernel..

Maybe there is a hidden reason for that... C > C++ 8)
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Post by Colonel Kernel »

Brynet-Inc wrote:You know a lot of Operating Systems (Most..) refuse C++ in the kernel..

Maybe there is a hidden reason for that... C > C++ 8)
Please refrain from making brain-dead statements. It's a complete waste of everybody's time.

If you think C is better than C++ for kernel development (and I'm not saying it isn't), then at least explain why.
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

C is simpler. It's usually cleaner, and I think it allows a closer bond to the system without many abstractions.

C++ allows such abstractions. (templates, classes, etc.)

It's all a matter of preference, really. I tend to like C, because it's clean. Frankly, if C++ was just prettier, and lighter, then I would probably use C++. C++ does have a technical advantage. (Templates are definitely an improvement from void*)

However, I think there's a middle ground. I'm not too fond of over OOP and over use of templates, but in certain situations they're fine. The trick is to find this middle ground between C and C++.............C+?
C8H10N4O2 | #446691 | Trust the nodes.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

mystran wrote:I suggest you go with the conversion by first making your C kernel compile as C++ without actually changing anything else, and then slowly replacing stuff with classes, so you can have a working kernel all the time. I've converted projects from C to C++ with this method, and in the end it's much less work than just rewriting in C++ directly.
That's my plan, and it's what I'm doing now. 90% of my code is directly transferrable to C++. Most of the problems come from assembly routines and the C++ name mangling - nothing 'extern "C"' can't fix.
User avatar
omin0us
Member
Member
Posts: 49
Joined: Tue Oct 17, 2006 6:53 pm
Location: Los Angeles, CA
Contact:

Post by omin0us »

I'm excited to see how this pans out. I have studied your code a bit, and cant wait to see the end result of this. Godspeed. :]
http://ominos.sourceforge.net - my kernel
#ominos @ irc.freenode.net
http://dtors.ath.cx - my blog
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

In reply to the comments about the simplicity of C in comparison to the abstraction of C++, I wanted to make some points.

Firstly, I plan on implementing a template class that can handle linked lists without taking much effort. ATM to use a linked list in my kernel I have to copy and paste a file that is designated as working linked list code, change the structure definitions and then cross my fingers. This takes a lot of time and means I have multiple versions of the same code. Template classes can help me out here.

Secondly, abstracting complex routines into classes means that I can have multiple objects for different tasks. For instance, file i/o can be turned into a class, while at the moment it is extremely complex and difficult to use. The same goes for my device management (and i/o handling routines). By creating a base class 'Device' (or 'CDevice') and then creating derived classes for each device that overload the simple i/o functions or allow the base class to use its own implementation (which would generally do nothing, or print an error).

Finally, operating systems at the core level don't have much room for abstraction. Hence the reason why I'm keeping a lot of my old C kernel and not converting that to classes. However, once the kernel reaches the point where the code being written is no longer working with non-abstractable components (such as the descriptor tables, or multitasking) but more working on visuals or device drivers, C becomes cubersome to implement and can become complex extremely quickly.

I can't wait till I finish the conversion, and I'll probably be posting here if (and probably when) I run into bumps in my path. The old C kernel will probably be released as a freebie for learning how to code a simple operating system and then add layers of functionality (mine now has UDP sockets, networking [duh], hard drive and floppy access, FAT read functions etc...).
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Brynet-Inc wrote:You know a lot of Operating Systems (Most..) refuse C++ in the kernel..

Maybe there is a hidden reason for that... C > C++ 8)
Yep. The Linux kernel maintainers don't know enough C++ to feel comfortable with it, and embarked in a major flamewar with those advocating kernel-space C++, including various pieces of BS that actually made it into the LKM FAQ. Basically since then, people keep making stupid claims about disadvantages of C++ in kernel space that have very little to do with reality, usually based on the observation that "if Linux doesn't do it, it's evil".

As mystran said, fix your C-only source to compile cleanly with a C++ compiler. Once that is done, ta-daa, you got a "C++ kernel". Everything you might want to do beyond that is up to you. (There's a patch for the Linux kernel that does just that, by the way, and never mind that the LKM FAQ tells you it's a mountain of work.)

And as for "hidden cost with C++", there is no such thing, just lack of knowledge about the language. You don't complain about struct padding in C, either; you know it happens, and you cater for it.

(Sorry, but I got a sore point as far as C++ bashing is concerned.)
Every good solution is obvious once you've found it.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

Indeed goodluck :) . No seriously, writing a kernel in C++ can be done rather easily. I know because i am doing it now :wink:. also because of the template reasoning. Once you get the placement new thingy in place and declared a nice operator new for allocating physical kernel memory it is only easy to continue.

Consider the following new operator. FYI bmemEnd points to the last used address and grows down and yes it can waist a lot of memory but that can be changed in the future.

Code: Select all

//- operator 'new' with alignment 
void * operator new [] (size_t size, int align, void * place = 0) {
    if(place) {
        //- placement new construction.
        return(reinterpret_cast<void *>(place));
    }
    bmemEnd -= size;
    bmemEnd -= (bmemEnd % align);
    //- simple physical address allocator.
    return( reinterpret_cast<void *>(bmemEnd));
}
now you can allocate a page like:

Code: Select all

voidp page = new (4096) char [4096];
now consider that you have an template class Array and a template class for InterruptDescriptor. Now its pretty easy to map your interrupt descriptor on the page you've just allocated.

Code: Select all

Array<InterruptDescriptor, 256> *   idt;
idt = new (page) Array<InterruptDescriptor, 256> ;
each of the interrupt descriptors can be accessed by using (*idt)[vector] where vector is your interrupt vector.

pretty powerfull IMHO
Author of COBOS
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Yes, as well as that I can re-implement the things that I wanted to change but couldn't because doing so meant changing a lot of complex code. For instance, now I clear the screen by going through and filling via an unsigned long long, ie. 8 bytes at a time. It's fast.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Just thought it might be good to post here and say, looking back over 4 months of rewriting an entire operating system, it was worth it.

In this time, Mattise has been switched from a monolithic design to a microkernel design.

I've just today finished the FAT32 driver and am now working on the shell. Once complete, version 1.1 (or maybe 2.0) will be released.
mystran wrote:I suggest you go with the conversion by first making your C kernel compile as C++ without actually changing anything else, and then slowly replacing stuff with classes, so you can have a working kernel all the time. I've converted projects from C to C++ with this method, and in the end it's much less work than just rewriting in C++ directly.
After this is released, I can go back and modify all the C stuff to use classes.
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

AJ wrote:I am a little concerned about how much c++ hides from the programmer though
What does it hide? A class is allocated memory just as huge struct. Templates don't 'hide' anything either, you're still in control of what can be accepted, and you can easily work out by hand how much memory things are allocated and where they will be stored in memory.

I think a lot of OS dev'ers keep away from C++ because they think it's slower and more bloated. Even some tests have shown how a C "Hello World" is smaller than a C++ variation. This is because the C++ standard library is a lot more complex, but a barebone C/C++ program wouldn't be much different. Efficiently designed C++ code isn't any slower than C code (although un-efficent code (like over hiding huge matrix multiplications behind a simple + operator and not telling the programmer) is - but this sort of bloat could happen in any language).
My OS is Perception.
Post Reply