[Solved] Linking c file without including it causes reboo...

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.
User avatar
BluCode
Posts: 22
Joined: Fri May 26, 2017 4:12 pm

[Solved] Linking c file without including it causes reboo...

Post by BluCode »

I am trying to develop an OS, mainly to learn about whats going on 'under the hood', and I am having trouble enabling paging. When I simply link the paging.c file with the rest of my c files, without ever mentioning it in another file, I get an endless reboot cycle. If I don't link the file but keep everything else the same, it works. So far I have tried to move my stack out of the way (from 0x9000 to 0xF000), and it has had no effect. I am open to suggestions and I am willing to post my code if needed.

My linking command (in my Makefile):

Code: Select all

ld -Ttext 0x1000 -m elf_i386 -o kernel/kernel.bin $^ --oformat binary
Hope you see something I don't.
Last edited by BluCode on Fri Jun 02, 2017 3:23 pm, edited 1 time in total.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Linking c file without including it causes reboot cycle.

Post by alexfru »

What about the order in which your C files end up in the binary? May that be screwing up the entry point?
goku420
Member
Member
Posts: 51
Joined: Wed Jul 10, 2013 9:11 am

Re: Linking c file without including it causes reboot cycle.

Post by goku420 »

Two things:

- Why run ld manually? Linking with gcc or g++ will call the linker under the hood

- Why specify text manually? You might as well use a linker script.

Also 0x1000 is unusual. The most common place to load the kernel is at the 1MB mark as that's safe enough to avoid anything that's loaded below it.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Linking c file without including it causes reboot cycle.

Post by iansjack »

Run it under a debugger.
mallard
Member
Member
Posts: 280
Joined: Tue May 13, 2014 3:02 am
Location: Private, UK

Re: Linking c file without including it causes reboot cycle.

Post by mallard »

A guess; since you're loading your kernel at a "low" address, you have (approximately; there are complications) 636KB (since you're loading at the 4KB mark) of memory before you hit the legacy ROM/MMIO area (the 384KB just below the 1MB boundary).

When you link this extra file into your kernel, it increases the size of the file so it no longer fits into that small RAM space, so your loader attempts to overwrite ROM, write to non-existent memory, etc. and the system resets in response.
Image
User avatar
BluCode
Posts: 22
Joined: Fri May 26, 2017 4:12 pm

Re: Linking c file without including it causes reboot cycle.

Post by BluCode »

Wow, thanks for all the replies!
alexfru wrote:What about the order in which your C files end up in the binary? May that be screwing up the entry point?
No, I use an entry assembly script that calls my 'start' c function, so thats not it.
goku420 wrote: - Why run ld manually? Linking with gcc or g++ will call the linker under the hood

- Why specify text manually? You might as well use a linker script.

Also 0x1000 is unusual. The most common place to load the kernel is at the 1MB mark as that's safe enough to avoid anything that's loaded below it.
1) I've heard about that, but never found how to use it. Please elaborate on how I could do that.

2) I have tried using a linker script but it messed up my .rodata sections (I couldn't print pre-defined strings). Any help with that would also be appreciated.

3) I am using my own bootloader, which, being 16 bit and only having a 16 bit disk read function, can only load the kernel to 0xFFFF.
iansjack wrote:Run it under a debugger.
Please elaborate, it sounds useful in the future.
mallard wrote:A guess; since you're loading your kernel at a "low" address, you have (approximately; there are complications) 636KB (since you're loading at the 4KB mark) of memory before you hit the legacy ROM/MMIO area (the 384KB just below the 1MB boundary).

When you link this extra file into your kernel, it increases the size of the file so it no longer fits into that small RAM space, so your loader attempts to overwrite ROM, write to non-existent memory, etc. and the system resets in response.
Good insight, but I can't figure out how I would go about loading the kernel somewhere high, like 1M, seeing as I am using a 16 bit bootloader and 16 bit disk read function.

Thanks for all your help so far!
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Linking c file without including it causes reboot cycle.

Post by iansjack »

Presumably you are testing your kernel with an emulator/virtual machine rather than on real hardware. (If not, you should.) Qemu is a good choice, and it can be used in conjunction with gdb to debug the kernel: http://wiki.qemu.org/Documentation/Debugging
User avatar
BluCode
Posts: 22
Joined: Fri May 26, 2017 4:12 pm

Re: Linking c file without including it causes reboot cycle.

Post by BluCode »

Yes, I am using qemu. I tried to use gdb but I couldn't figure out how to get a symbol file from my kernel.bin. It would be really advantageous to get that working though.
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Linking c file without including it causes reboot cycle.

Post by Octocontrabass »

BluCode wrote:Good insight, but I can't figure out how I would go about loading the kernel somewhere high, like 1M, seeing as I am using a 16 bit bootloader and 16 bit disk read function.
If your kernel is small enough to fit in low memory, you can load it all in real mode and then copy it above 1M after you switch to protected mode.

It's also possible to load part of the kernel in real mode, switch to protected mode to copy that part above 1M, then switch back to real mode and repeat until the entire kernel is loaded.

My favorite option is to install a GPF handler that switches to unreal mode for transparent 32-bit addressing, although you probably don't need something that complicated.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Linking c file without including it causes reboot cycle.

Post by iansjack »

BluCode wrote:Yes, I am using qemu. I tried to use gdb but I couldn't figure out how to get a symbol file from my kernel.bin. It would be really advantageous to get that working though.
Produce an elf file as well as a binary file, and use that as the file you "load" to provide symbols. Or, without symbols, you can still use gdb to debug at the assembler level.
MichaelPetch
Member
Member
Posts: 799
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: Linking c file without including it causes reboot cycle.

Post by MichaelPetch »

BluCode wrote:Yes, I am using qemu. I tried to use gdb but I couldn't figure out how to get a symbol file from my kernel.bin. It would be really advantageous to get that working though.
An observation. If you want a symbol file don't use GCC/LD to output as binary. Output as ELF (with the symbols) and then use Objcopy to convert the ELF to binary.

Code: Select all

ld -Ttext 0x1000 -m elf_i386 -o kernel/kernel.elf <list of objects>
objcopy -O binary kernel.elf kernel.bin
this would generate an intermediate ELF file called `kernel.elf` that is then converted into `kernel.bin`.
MichaelPetch
Member
Member
Posts: 799
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: Linking c file without including it causes reboot cycle.

Post by MichaelPetch »

If you had a project available (github etc) we could have a look.
User avatar
eryjus
Member
Member
Posts: 286
Joined: Fri Oct 21, 2011 9:47 pm
Libera.chat IRC: eryjus
Location: Tustin, CA USA

Re: Linking c file without including it causes reboot cycle.

Post by eryjus »

MichaelPetch wrote: ld -Ttext 0x1000 -m elf_i386 -o kernel/kernel.elf <list of objects>
objcopy -O binary kernel.elf kernel.bin
Don't forget you need a cross compiler: http://wiki.osdev.org/GCC_Cross-Compiler
Adam

The name is fitting: Century Hobby OS -- At this rate, it's gonna take me that long!
Read about my mistakes and missteps with this iteration: Journal

"Sometimes things just don't make sense until you figure them out." -- Phil Stahlheber
LtG
Member
Member
Posts: 384
Joined: Thu Aug 13, 2015 4:57 pm

Re: Linking c file without including it causes reboot cycle.

Post by LtG »

Didn't see it mentioned yet, but you should think if you want to do osdev or write a bootloader, the two are almost completely different, in design and goals.

If you don't care about bootloaders then use GRUB or some other existing one, and it's their responsibility to load your binary, if you want to do a bootloader then do that, but it doesn't really have much to do with osdev, except it's job is to load some OS.
User avatar
BluCode
Posts: 22
Joined: Fri May 26, 2017 4:12 pm

Re: Linking c file without including it causes reboot cycle.

Post by BluCode »

Octocontrabass wrote: If your kernel is small enough to fit in low memory, you can load it all in real mode and then copy it above 1M after you switch to protected mode.

It's also possible to load part of the kernel in real mode, switch to protected mode to copy that part above 1M, then switch back to real mode and repeat until the entire kernel is loaded.

My favorite option is to install a GPF handler that switches to unreal mode for transparent 32-bit addressing, although you probably don't need something that complicated.
All good ideas, I'll look into them in the future.
iansjack wrote:Produce an elf file as well as a binary file, and use that as the file you "load" to provide symbols. Or, without symbols, you can still use gdb to debug at the assembler level.
MichaelPetch wrote: An observation. If you want a symbol file don't use GCC/LD to output as binary. Output as ELF (with the symbols) and then use Objcopy to convert the ELF to binary.

Code: Select all

ld -Ttext 0x1000 -m elf_i386 -o kernel/kernel.elf <list of objects>
objcopy -O binary kernel.elf kernel.bin
this would generate an intermediate ELF file called `kernel.elf` that is then converted into `kernel.bin`.
Using these two replies and the wiki article on debugging with QEMU I got it working, thanks!
MichaelPetch wrote:If you had a project available (github etc) we could have a look.
I'll probably move there soon, and I'll let you know if and when I do.
LtG wrote:Didn't see it mentioned yet, but you should think if you want to do osdev or write a bootloader, the two are almost completely different, in design and goals.

If you don't care about bootloaders then use GRUB or some other existing one, and it's their responsibility to load your binary, if you want to do a bootloader then do that, but it doesn't really have much to do with osdev, except it's job is to load some OS.
Good point, but since this is mainly to learn about all of whats going on under the hood I'm doing both, please and thank you. :P

Also good and bad news, I solved the original issue, I wasn't reading enough sectors from the disk. The bad news is that paging isn't working, but thanks to you guys I should be able to use gdb and find the problem.
Post Reply