Skip to content

Suggest to use custom linker script to link x86-16 code?#5

Description

@tkchia

Hello @rebane2001,

Current (casual) maintainer of ia16-elf-gcc here. Thanks for the project, and I hope to try it out soon on a capable browser. 馃檪

For compiling the x86-16 code, I notice you are not using the toolchain's newlib-ia16 C library. For this case, I would actually suggest to link the program using a custom linker script, which will allow you more control over the code and data layout in the final binary.

E.g. as a start, you could have a file c/main.ld which says something like this:

OUTPUT_FORMAT ("binary")
ENTRY (_start)
SECTIONS
{
  PROVIDE (_stext = 0x100);
  .text _stext :
    {
      BYTE (0xe9)  /* Near jump to _start. */
      SHORT (_start - (. + 2))
      *(.text.startup .text.startup.*)
      *(.text .text.* .gnu.linkonce.t.*)
      *(.gnu.warning)
    }
  PROVIDE (_etext = .);
  .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  .data : { *(.data .data.* .gnu.linkonce.d.*) }
  PROVIDE (_edata = .);
  .bss :
    {
      *(.bss .bss.* .gnu.linkonce.b.*)
      *(COMMON)
    }
  PROVIDE (_end = .);
  /DISCARD/ : { *(*) }
}

and tweak build_c.py to use it:

--- a/build_c.py
+++ b/build_c.py
@@ -20,5 +20,5 @@ def build():
         pass
 
-    command = f"ia16-elf-gcc c/{BASE_NAME}.c -o tmp/{BASE_NAME}.a {FLAGS}"
+    command = f"ia16-elf-gcc c/{BASE_NAME}.c -T c/{BASE_NAME}.ld -o tmp/{BASE_NAME}.a {FLAGS}"
     res =  subprocess.run([*bash_prefix, command], capture_output=True, text=True)
     print(res.stdout)
@@ -29,5 +29,5 @@ def build():
 
 def asm_build():
-    command = f"ia16-elf-gcc c/{BASE_NAME}.c -o tmp/{BASE_NAME}.o {FLAGS} -c"
+    command = f"ia16-elf-gcc c/{BASE_NAME}.c -T c/{BASE_NAME}.ld -Wl,--oformat=elf32-i386 -o tmp/{BASE_NAME}.o {FLAGS}"
     #
     res =  subprocess.run([*bash_prefix, command], capture_output=True, text=True)
@@ -38,5 +38,5 @@ def asm_build():
         raise Exception(str(res.returncode))
 
-    command = f"ia16-elf-objdump -Mi8086 -Mintel --adjust-vma=256 -fd tmp/{BASE_NAME}.o"
+    command = f"ia16-elf-objdump -Mi8086 -Mintel -fd tmp/{BASE_NAME}.o"
     res =  subprocess.run([*bash_prefix, command], capture_output=True, text=True)
     return res.stdout

The normal linker script when ia16-elf-gcc is invoked with default options鈥攚ithout -nostdlib鈥攊s meant for compiling "tiny" (< 64 KiB) headerless .com programs with newlib-ia16 which will run under MS-DOS. (Or an MS-DOS clone or emulator, such as DOSBox.) Such a program will be loaded at PSP:0x100 (PSP = program segment prefix), and will begin running at %cs:%ip = PSP:0x100. I can explain further if you are inclined. 馃檪

Thank you!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions