0

I'm trying to write a bootloader for a kernel. At the moment i'm loading the GDT with assembly but I want to write some C code to generate the GDT(and the IDT) The problem is that the boot sector is always loaded at address 0x7c00 so I need a way to offset my labels with that address. If I assemble to a bin file I can just use [org 0x7c00] but I want to assemble the bootloader to an object file(Which org is not supported in this format by NASM) so that I can use external symbols. Without org, I have this in my assembly code:

gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start            
.
.
.
lgdt [gdt_descriptor]

when assembled looks like:

lgdt 0x71

when it should be

lgdt 0x7c71

The table itself is also wrong as the gdt start location does not take into account the offset.

Save for manually adding the offset myself(Which there would be a bunch of places I would have to), is there any directive I can use to set the start address?

edit: Changed from 0xc700 to 0x7c00

Ziamor
  • 493
  • 1
  • 7
  • 11
  • The load address BIOS bootloaders is actually at 0x7c00. There's really not much point in using object files, bootloaders and need to be 512 bytes exactly with a 0xAA55 word at the end. The easiest thing is to define the entire bootsector in one file so you can easily meet those requirements. Otherwise you're going to have to pad it out and add the signature. – Ross Ridge May 19 '15 at 21:13
  • Ahh yes, I fixed it in the original post to 0x7c00. The reason I want to have an object file is so I can use external symbols but as Jester pointed out the code would be in 32 bit mode while I would need 16 bit for the boot loader – Ziamor May 19 '15 at 21:19
  • Even if you have a 16-bit C compiler I'd still use assembly instead, both for the reasons I gave in my previous comment and because you'll have a harder time getting your code to fit in 512 bytes. – Ross Ridge May 19 '15 at 21:22

1 Answers1

0

If you assemble to an object file, you will presumably link it. You can tell the linker where to place things. You might need to put your stuff into a separate section though.

Also note that the bootsector code is 16 bit real mode, while C code is usually 32/64 bit protected mode code. As such, it's normally not easy to link those together, and I don't really see how you will "generate" the GDT from C...

Jester
  • 56,577
  • 4
  • 81
  • 125
  • hmm your right about that, didn't cross my mind. Might have to bite the bullet and just keep in in assembly. – Ziamor May 19 '15 at 21:13
  • 1
    @Ziamor: The GDT is typically tiny and can be hard-coded; and it's probably easier just having a second GDT in the kernel itself. Also; it's a massive mistake to switch to protected mode in the first 512 bytes of your boot loader - you must use the BIOS while it's still usable for things like getting a memory map, setting a video mode, getting information on the boot device/disks, etc; and (assuming useful error handling) this adds up to far more than you'll ever fit in 512 bytes, and needs to be done before starting kernel/discarding boot code/discarding BIOS. – Brendan May 19 '15 at 21:37