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 have just started working on a simple kernel, so far everything works except string literals,
when i try to print a string literal either i get a lot of nonsense characters , or it doesnt print anything, while i can print a manually filled char array using the same function:
I honestly don't know about MS Visual Studio, but if this were GCC the problem would be to do with your linker script. String literals go in the .rodata section, which in some linker scripts doesn't get linked into .data properly.
Double check your linker script in case this applies to you.
Use the Bochs Debugger and make sure your string is where its expected to be at. I wonder how you are using objcopy to convert it to a flat binary - perhaps that might be where the problem is at.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
This problem will be simple for you to diagnose. But think about it your plan of attack.
e.g.
1. Create a simple version without any confusing code. e.g. only have one printk, only have one string so you can understand the code more easily.
2. Inspect the actual binary that you are loading code with a disassembler or debugger. Work through the logic line by line. Check all addresses in assembler code.
3. You cannot fix a problem unless you know what the problem is. 'String not appearing' is not a problem, it is a symptom. The problem might be 'The linker links to wrong address' OR 'the compiler puts the sting in the wrong segment'. When you know the problem you can fix it. It's even possible that there is a bug in your tool-chain.
Sometimes people on osdev will recognise a symptom and be able to give you a solution right away, but really, you need to learn how to diagnose these problems yourself. I can guarantee there will be many more problems. Any study you do now will not be wasted.
- gerryg400
If a trainstation is where trains stop, what is a workstation ?
What i found is that it nicely pushes the char * to the stack, with the right address (0x00101600), and that that mapping gets translated to binary fine
Well, after i checked the bin file again i saw that instead of keeping the string at 0x101A00 objcopy moved it to 0x101600 without chainging the pointer, and i couldnt get that to work with ms linker so i made a build step for GNU ld in my visual studio system but the data section pointers are off by 4 bytes,any idea on how i could move a section up 4 bytes?
I personally have never mixed the MSVC toolchain with GNU tools so I cannot offer help. However I do want to mention that you do not need to use a flat binary kernel in order for GRUB to boot it. Thus their are alternative methods to get this working.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
I know, but when i try to run a PE executable linked by the microsoft linker, i get a grub error that it tried to read a block outside of the partition
The problem is in your Multiboot header. You have header_addr set to 0x100000, where the correct address is probably 0x100400. You should set both header_addr and entry_addr to the correct labels instead of writing out the physical addresses you think they'll be at.
It should be possible to skip the objcopy step if you use /ALIGN:16 when linking. An align value below 4096 will create a flat file which can be used directly. However, this also means that uninitialized data will be included in the file. You can remove the extra zeros manually and have your code check the section headers to find any uninitialized data which it should zero out. Or, you could write a program that finds the uninitialized part of the .data segment and places the correct size in the Multiboot header before you objcopy it.