Page 1 of 2
Greetings and Noob Questions
Posted: Fri Apr 20, 2007 6:12 pm
by Rhob
Greetings, everyone. This is my first post to the forum.
I am starting a project to create a simple object-oriented OS, on the level of MS-DOS. Currently I am working to set up the proper development environment. Perhaps against the grain, I have decided thus far to use Windows and Visual C++.
My question concerns the compiler settings for my IDE, Visual C++ Express. I have included the /NODEFAULTLIB option for the linker, yet I still get the following error:
Code: Select all
error LNK2001: unresolved external symbol _mainCRTStartup
Somehow, the CRT is still involved in the build process. At this point, I have no idea why that could be. Here are my compiler and linker options in command-line format:
Compiler:
Code: Select all
/O1 /Os /GL /X /GF /FD /MT /Zp1 /GS- /Zc:wchar_t- /GR- /FAcs /Fa"\\" /Fo"\\" /Fd"\vc80.pdb" /W4 /nologo /c /Gz /TP /Zl /errorReport:prompt /Oy-
Linker:
Code: Select all
/OUT:"\odos.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"\.intermediate.manifest" /NODEFAULTLIB /MAP:"odos.map" /TSAWARE:NO /OPT:REF /OPT:ICF /LTCG /MACHINE:X86 /ERRORREPORT:PROMPT /DRIVER /ALIGN:512
I noticed that "kernel32.lib" was still getting included in the linker command-line arguments,
despite the fact that I had set the "NODEFAULTLIB" option. However, I was able to remove it from the linker arguments, and the aforementioned link error still occurs.
Finally, I am using Visual C++ Express 2005 Version 8.0.50727.42 (RTM.050727-4200), if anyone needs to know.
If you need more information in order to help (if you are willing in the first place!), then please let me know.
- Rob
Posted: Fri Apr 20, 2007 6:38 pm
by anon19287473
I think VC++ using JIT. It's worth checking
![Sad :(](./images/smilies/icon_sad.gif)
Posted: Fri Apr 20, 2007 6:40 pm
by Brynet-Inc
The OSDev wiki should be some assistance..
http://www.osdev.org/wiki/Visual_Studio
Take care..
Posted: Fri Apr 20, 2007 6:46 pm
by Rhob
Hi Brynet-Inc,
I should have mentioned that the compiler and linker settings above are based on the Wiki page. In other words, I already looked there.
Edit: The only thing I have not set is the entry point. Perhaps this is causing the problem?
Re-Edit: According to
this link, Visual C++ Express does not support JIT.
- Rob
Posted: Fri Apr 20, 2007 6:52 pm
by Brynet-Inc
RHaden wrote:Hi Brynet-Inc,
I should have mentioned that the compiler and linker settings above are based on the Wiki page. In other words, I already looked there.
Edit: The only thing I have not set is the entry point. Perhaps this is causing the problem?
- Rob
You could always use Cygwin/MinGW (GCC) if problems persist..
Posted: Fri Apr 20, 2007 7:04 pm
by Rhob
Sure, but I'd like to find out what is causing the problem at hand. Does anyone know?
- Rob
Posted: Fri Apr 20, 2007 7:15 pm
by pcmattman
Try setting the entry point to your entry point - and that's the code that sets up the runtime (stack etc...), not your main() function.
Posted: Fri Apr 20, 2007 7:23 pm
by Rhob
If I'm not (yet) using any features which would need runtime support, do I still need to set up the runtime environment?
I apologize if the above is a stupid question.
- Rob
Posted: Fri Apr 20, 2007 7:26 pm
by mystran
C needs at least stack setup's worth runtime environment, so..
But no, ofcourse you don't need to setup anything you don't use, but then again you must make sure you compiler indeed doesn't try to use any of that without asking you...
I don't know anything about Visual Studio (well at least not for kernel development) so can't help with that.
Posted: Fri Apr 20, 2007 7:27 pm
by pcmattman
You do need a runtime. If you're developing an operating system kernel you don't have anything setup when your OS runs.
What I mean by 'runtime' is a small stub that sets up the stack and (in C++) initializes static and global classes then calls your main() function. If you use C++ it also deinitializes classes when main() returns...
You usually set the entry point for your kernel to that stub's main function (it'll have to be in assembly).
If you look at the Barebones example in the Wiki you can see how to setup the stack... If you use a PE bootloader you won't need to worry about the multiboot stuff, just the init stuff.
Edit: barebones also shows how to do other necessary init in C++ environments (barebones C++).
Posted: Sat Apr 21, 2007 12:25 pm
by jnc100
Code: Select all
error LNK2001: unresolved external symbol _mainCRTStartup
I'm no expert on VC++, but I think the linker is wired by default to look for an entry point called _mainCRTStartup (not 'main' like most other linkers). This function is contained in the CRT (which you aren't including), and the CRT version basically sets up a few MS-favourite things and then calls a function called main in your program.
Either define _mainCRTStartup yourself or find some option which changes the entry point the linker looks for.
BTW it is possible to have VC++ 2005 Express use an external build system. This is what I use so I can use the VC++ IDE but then call gnu make, gcc, nasm, ld, objcopy etc whenever I hit the compile button.
Regards,
John.
Posted: Sat Apr 21, 2007 6:21 pm
by earlz
I actually got this error on GCC before and got rid of it by (i think) using _main instead of main
Posted: Sun Apr 22, 2007 3:01 am
by jnc100
I actually got this error on GCC before and got rid of it by (i think) using _main instead of main
Was that gcc under Cygwin/MinGW?
You do need a runtime. If you're developing an operating system kernel you don't have anything setup when your OS runs.
This is also true - even if using MultiBoot then you still need a stub which sets up ESP (the stack pointer that is
![Wink :wink:](./images/smilies/icon_wink.gif)
) although MultiBoot-compliant loaders set up a gdt and segment selectors for you (including SS). The stub also needs to do something with the MultiBoot header if you want to know how much memory you have...
Oh yeah, and you need some code near the start of your kernel to include a MultiBoot header if you want to do it this way.
Finally (of course this is all assuming you want to use MultiBoot!), its a lot easier to use ELF binaries than PE (which is what MSVC outputs) as bootloaders can easily parse their section table and load everything to the right place, and jump to the entry point which you specify with:
link /ENTRY:symbol
or in the IDE: Project properties->Configuration Properties->Linker->Advanced->Entry Point
Regards,
John.
Posted: Sun Apr 22, 2007 3:09 am
by pcmattman
If you use NASM and output in COFF format a simple loader that has an entry point '_start' and sets up the stack, then set the entry point of the final executable to '_start', you should be able to load your kernel with any PE bootloader.
Good luck!
Posted: Wed May 02, 2007 7:42 pm
by Rhob
Thanks for your replies, everyone. I'm sorry for writing back to this so late, but I've been doing a lot of reading about operating systems.
A little clarification is in order, I think. First off, my OS project is intended to be extremely simple -- as I said before, on the level of MS-DOS or so. This means that it will use 16-bit real mode. (I hope that doesn't scare all of you away.) Basically, I think I need to learn how to crawl before I can learn how to walk.
Second, I intend the OS to be object-oriented from the start. Creating an object-oriented OS is indeed the main goal of my project. I feel that OOP is an extremely powerful paradigm, and I see no reason why it should not be used for OSes. Using OOP here means using C++, of course. And yes, I know that many OSes have been written in C++ already -- I just want to see if I can make one myself.
Anyways, I have a few more questions for the time being, based on your responses:
- What is the recommended stack size to create for the OS?
- How exactly does one create the stack? Does it have to be done in assembly (if so, why)?
- What method(s) do you recommend for accessing the x86 CPU registers in C/C++?
Thanks in advance for your answers!
- Rob