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.
I'm trying to build a kernel in C, however my Dev C++ IDE always compiles my code to .EXE.
The .com (.bin) format is exactly what the code is in memory, so I want to load the kernel.bin instead of kernel.exe.
Is it possible to compile C code to DOS-like .com file
Last edited by pauldinhqd on Sun Apr 15, 2012 9:41 am, edited 1 time in total.
I recommend using gcc and if possible using a cross compiler as this will give you least problems and most possibilities going forwards and matches what is used in most tutorials and examples.
pauldinhqd wrote:The .com (.bin) format is exactly what the code is in memory, so I want to load the kernel.bin instead of kernel.exe.
Is it possible to compile C code to DOS-like .com file
While you can rather easily make a flat binary with Dev-C++'s toolchain, making a DOS binary is tricky because DOS is a 16-bit architecture and GCC, even the DOS version, can only make 32-bit code. The same precautions are necessary if you try writing bootstrap code with GCC.
The examples on the wiki can help you get past the 16-bit stage - either by using GRUB which does the work for you, or you'll have to write your own substitute.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
pauldinhqd wrote:The .com (.bin) format is exactly what the code is in memory, so I want to load the kernel.bin instead of kernel.exe.
Is it possible to compile C code to DOS-like .com file
While you can rather easily make a flat binary with Dev-C++'s toolchain, making a DOS binary is tricky because DOS is a 16-bit architecture and GCC, even the DOS version, can only make 32-bit code. The same precautions are necessary if you try writing bootstrap code with GCC.
The examples on the wiki can help you get past the 16-bit stage - either by using GRUB which does the work for you, or you'll have to write your own substitute.
yeah, what i mean for 'dos-like .com' is flat binary.
i'm trying to use gcc with this command line: "gcc kernel.c -m64",
but gcc reports back that: "sorry, unimplemented: 64-bit mode not compiled in"
any other compilers (on windows) to compile c code to 64-bit flat binary?
ps.
although i want to create a kernel from c code, but what would happen with those standard c libraries? if included into kernel, would be a big bunch of code, some say these libs may take a few MB.
If you wish to target an architecture that is not supported by your default compiler, the easiest and most recommended solution is to build a GCC Cross-Compiler. This will help you avoid a lot of trouble later and provide you with a tested standard toolchain that many people here use. If you plan to write a 64 bit kernel, something like x86_64-elf will probably be a good choice for a target architecture. This will allow you to create flat binary output, but leave you with the option to create ELF binaries as well.
Regarding your second question: Many standard library functions require some kind of interaction with the OS they are compiled for. For example, printf uses some system call to generate text output. You cannot use these library functions in your own OS before you have written things like system calls and ported the library to use these system calls. If you write an OS kernel, the only thing you can use is your own code - nothing else.
XenOS wrote:If you wish to target an architecture that is not supported by your default compiler, the easiest and most recommended solution is to build a GCC Cross-Compiler. This will help you avoid a lot of trouble later and provide you with a tested standard toolchain that many people here use. If you plan to write a 64 bit kernel, something like x86_64-elf will probably be a good choice for a target architecture. This will allow you to create flat binary output, but leave you with the option to create ELF binaries as well.
Regarding your second question: Many standard library functions require some kind of interaction with the OS they are compiled for. For example, printf uses some system call to generate text output. You cannot use these library functions in your own OS before you have written things like system calls and ported the library to use these system calls. If you write an OS kernel, the only thing you can use is your own code - nothing else.
this means i can use C for my kernel but without any "#include", true
about the executable file format:
flat binary isn't popular to be the primary executable format on modern OSes (all public & personal projects),
so should I choose ELF as the primary executable format for my would-be-called OS
(as many C compilers support this format directly)
pauldinhqd wrote:this means i can use C for my kernel but without any "#include", true
You can include anything you have written yourself or what is part of a "freestanding environment" (such as <stdint.h>, which only contains typedefs and defines for integer sizes), but you cannot include header files from specific libraries or those that require a "hosted environment" (such as <stdio.h>, which contains function that require OS support).
about the executable file format:
flat binary isn't popular to be the primary executable format on modern OSes (all public & personal projects),
so should I choose ELF as the primary executable format for my would-be-called OS
(as many C compilers support this format directly)
Yes, something like ELF is certainly a good choice. Many people in osdev (including myself) use ELF since it's quite easy to work with.
XenOS wrote:
Yes, something like ELF is certainly a good choice. Many people in osdev (including myself) use ELF since it's quite easy to work with.
that's great, i would like to use ELF too.
would you tell me some of the experiences when working with this type of file,
especially from the viewpoint of an os developer.
Actually there is not much I can say about my experience with ELF files - except that I never had any real problems working with them The tools I chose to develop my OS (GCC + Binutils) operate well with ELF files for various 32 and 64 bit architectures, including x86, ARM, MIPS, PPC and M68K, so they fit my needs. My kernel is an ELF file which is loaded into memory by GRUB. Executables and drivers are also ELF files, some of which are loaded by GRUB. Things like parsing the ELF header and implementing stuff like dynamic linking and program loading are rather simple, once you know the layout of the ELF header and the sections of an ELF file. For example, I defined all ELF file structures as C++ classes for my kernel:
XenOS wrote:Actually there is not much I can say about my experience with ELF files - except that I never had any real problems working with them The tools I chose to develop my OS (GCC + Binutils) operate well with ELF files for various 32 and 64 bit architectures, including x86, ARM, MIPS, PPC and M68K, so they fit my needs. My kernel is an ELF file which is loaded into memory by GRUB. Executables and drivers are also ELF files, some of which are loaded by GRUB. Things like parsing the ELF header and implementing stuff like dynamic linking and program loading are rather simple, once you know the layout of the ELF header and the sections of an ELF file. For example, I defined all ELF file structures as C++ classes for my kernel: