Migrating Mattise to C++
-
- 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++
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).
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).
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
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
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.
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
Please refrain from making brain-dead statements. It's a complete waste of everybody's time.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++
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:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
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+?
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.
-
- 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:
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.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.
-
- 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:
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...).
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...).
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".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++
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.
Indeed goodluck
. No seriously, writing a kernel in C++ can be done rather easily. I know because i am doing it now
. 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.
now you can allocate a page like:
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.
each of the interrupt descriptors can be accessed by using (*idt)[vector] where vector is your interrupt vector.
pretty powerfull IMHO
![Smile :)](./images/smilies/icon_smile.gif)
![Wink :wink:](./images/smilies/icon_wink.gif)
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));
}
Code: Select all
voidp page = new (4096) char [4096];
Code: Select all
Array<InterruptDescriptor, 256> * idt;
idt = new (page) Array<InterruptDescriptor, 256> ;
pretty powerfull IMHO
Author of COBOS
-
- 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:
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.
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.
After this is released, I can go back and modify all the C stuff to use classes.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.
- AndrewAPrice
- Member
- Posts: 2309
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
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.AJ wrote:I am a little concerned about how much c++ hides from the programmer though
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.