I need help figuring out how to link my program/os
Posted: Sat May 27, 2023 6:13 pm
I have this really simple and basic real mode command line system programmed entirely in assembly. I want to do a few moderately complex operations that I really, really don't want to make in assembly and would like to use C or C++. Ideally, I need to make a standalone C++ function and come up with a way to access that function from the assembly section where all the stuff happens.
Now I wasn't using any linking of any kind before I decided I need to try to get C/C++ working. My original build script (not found in the linked github repository) was as follows:
After running my build script, I can run it in qemu by typing "qemu-system-i386 bootloader.bin -cpu=486-v1". I also run it on real hardware by copying the contents of bootloader.bin into a compact flash card using dd and putting that into a cf to ide adapter.
It must be noted that the target system is 486 architecture so I need to try to keep non-486 opcodes out if at all possible. Other people have had success in the past using open watcom for this type of thing. It supports compiling into 16 bit real mode as well as cpus as old as 8088. I always get stuck when figuring out linking for these types of projects though so I need help. I finally figured out a way to at least make a linker script in a way that doesn't spit out errors but of course it doesn't work and I don't really know what else to try.
First, I run open watcom "wpp" on my test helloworld.cpp file. Wpp is for compiling c++ without linking according to this source. If it matters, I compile using which gives me a file called helloworld.o.
Next, I run
This compiles the bootloader and bios into o files for the linker. There's elf, elf32 and elf64. elf32 and elf seem to work the same. Using bin instead just gives me an error saying "bootloader.o: file not recognized: file format not recognized" when I run any variation of the link command that I've tried. I'm currently using "ld -melf_i386 -T link.ld" for the linking step, not sure if that the best thing to use. Anyway, that doesn't actually boot up when I try to do it with qemu and that's about the extent of what I have been able to accomplish, it was hard enough to get all those commands to run without errors in the first place.
Anyway I don't know what to try next but here's a github repository for the project.
https://github.com/Xeraster/RealModeOS
"buildScript.sh" is the build script, "link.ld" is the linker file, if what I have isn't correct I will need help figuring that out too. The bootloader is loaded into memory location 07c00h which loads the rest of the program into memory at location 07e00h and then jumps to 07e00h to start the program.
Another thing that kind of has me baffled is that in the file "COMMANDS.ASM", there are 3 entries called "debug1cmd", "debug2cmd" and "debug3cmd". The declaration looks like "debug3cmd db "debug3",0,$". I have to change that db to a dw or the link command gives me the following error:never mind now it always happens. I didn't really change anything, don't know whats going on there.
Why it does it for those 3 entries and none of the others that are written in the exact same way? I have no idea and I don't know if it's important or not.
Let me know if I need to post any additional information. I don't like asking simple beginner-like questions if they can be avoided but getting linking to work is always such an ordeal.
Now I wasn't using any linking of any kind before I decided I need to try to get C/C++ working. My original build script (not found in the linked github repository) was as follows:
Code: Select all
#!bin/bash
nasm BIOS.ASM -o bios.o
nasm bootloader.asm -o bootloader.o
cat bios.bin >> bootloader.bin
It must be noted that the target system is 486 architecture so I need to try to keep non-486 opcodes out if at all possible. Other people have had success in the past using open watcom for this type of thing. It supports compiling into 16 bit real mode as well as cpus as old as 8088. I always get stuck when figuring out linking for these types of projects though so I need help. I finally figured out a way to at least make a linker script in a way that doesn't spit out errors but of course it doesn't work and I don't really know what else to try.
First, I run open watcom "wpp" on my test helloworld.cpp file. Wpp is for compiling c++ without linking according to this source. If it matters, I compile using
Code: Select all
/usr/bin/watcom/binl/wpp helloworld.cpp
Next, I run
Code: Select all
nasm -f elf -o bootloader.o bootloader.asm
nasm -f elf -o bios.o BIOS.ASM
Anyway I don't know what to try next but here's a github repository for the project.
https://github.com/Xeraster/RealModeOS
"buildScript.sh" is the build script, "link.ld" is the linker file, if what I have isn't correct I will need help figuring that out too. The bootloader is loaded into memory location 07c00h which loads the rest of the program into memory at location 07e00h and then jumps to 07e00h to start the program.
Another thing that kind of has me baffled is that in the file "COMMANDS.ASM", there are 3 entries called "debug1cmd", "debug2cmd" and "debug3cmd". The declaration looks like "debug3cmd db "debug3",0,$". I have to change that db to a dw or the link command gives me the following error:never mind now it always happens. I didn't really change anything, don't know whats going on there.
Code: Select all
bios.o: in function `debug3cmd':
BIOS.ASM:(.text+0x17e4): relocation truncated to fit: R_386_8 against `.text'
Let me know if I need to post any additional information. I don't like asking simple beginner-like questions if they can be avoided but getting linking to work is always such an ordeal.