FreeDOS/kernel/kernel.ld

197 lines
5.7 KiB
Plaintext
Executable File

/* Linker script for DOS executables with separate data and text segments.
Partly derived from dos-exe-small.ld in newlib-ia16 and elks-separate.ld. */
OUTPUT_FORMAT(binary)
DOS_PSP = 0x60;
MEMOFS = DOS_PSP * 16 - SIZEOF(.msdos_mz_hdr);
/* these GROUPs play the same role as GROUPS (segments) in OMF */
PGROUP = (MEMOFS + LOADADDR(.ptext)) / 16;
LGROUP = (MEMOFS + LOADADDR(.ltext)) / 16;
DGROUP = (MEMOFS + LOADADDR(.data)) / 16;
_DosDataSeg = DGROUP;
TGROUP = (MEMOFS + LOADADDR(.text)) / 16;
IGROUP = (MEMOFS + LOADADDR(.itext)) / 16;
I_GROUP = (MEMOFS + LOADADDR(.idata)) / 16;
INITSIZE = SIZEOF(.itext) + SIZEOF(.idata) + SIZEOF(.ibss);
SECTIONS
{
/* Fabricate a .exe header here. Although libbfd does have an
"i386msdos" back-end which produces an "MZ" exe header, it cannot do
certain things (yet). */
.msdos_mz_hdr : {
/* Signature. */
SHORT (0x5a4d)
/* Bytes in last 512-byte page. */
SHORT (LOADADDR (.ibss) % 512)
/* Total number of 512-byte pages. */
SHORT (ALIGN(LOADADDR (.ibss), 512) / 512)
/* Relocation entries. */
SHORT ((__msdos_mz_rel_end - __msdos_mz_rel_start) / 4)
/* Header size in paragraphs. */
SHORT (SIZEOF(.msdos_mz_hdr) / 16)
/* Minimum extra paragraphs. */
SHORT (ALIGN(SIZEOF (.ibss) + SIZEOF(.istack), 16) / 16)
/* Maximum extra paragraphs. */
SHORT (0xffff)
/* Initial %ss. */
SHORT (LOADADDR (.istack) / 16 )
/* Initial %sp. */
SHORT (LOADADDR (.istack) % 16 + SIZEOF(.istack))
/* Padding for Checksum (unused) and initial cs:ip (0:0) */
. = 0x18;
/* Relocation table offset. */
SHORT (. + 4)
/* Overlay number */
SHORT (0)
/* Relocations */
HIDDEN (__msdos_mz_rel_start = .);
*(.msdos_mz_reloc .msdos_mz_reloc.*)
HIDDEN (__msdos_mz_rel_end = .);
/* Padding */
. = ALIGN (16);
}
/* Target PSP section. */
.ptext 0 : AT (SIZEOF(.msdos_mz_hdr)) {
*(PSP)
}
/* Target low data+text sections. */
.ltext 0 : AT (LOADADDR(.ptext) + SIZEOF(.ptext)) {
*(_IRQTEXT)
*(_LOWTEXT)
*(_IO_TEXT)
*(_IO_FIXED_DATA)
}
/* Target data sections. */
.data 0 : AT (ALIGN(LOADADDR(.ltext) + SIZEOF(.ltext), 16)) {
*(_FIXED_DATA)
*(_BSS)
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .bss)
*(_DATA)
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .data)
*(_DATAEND)
*(CONST)
*(CONST2)
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .rodata)
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .rodata.*)
*(DYN_DATA)
ASSERT(. <= 0xfff8,
"Error: too large for a small-model .exe file.");
}
/* Target text sections. */
.text 0 : AT (ALIGN(LOADADDR(.data) + SIZEOF(.data), 16)) {
*(HMA_TEXT_START)
*(HMA_TEXT)
_call_intr = CALL_INTR;
_res_DosExec = RES_DOSEXEC;
_res_read = RES_READ;
_strlen = STRLEN;
_fstrlen = FSTRLEN;
_strlen = STRLEN;
_fstrcmp = FSTRCMP;
_strchr = STRCHR;
_fstrchr = FSTRCHR;
_fmemchr = FMEMCHR;
_strcpy = STRCPY;
_fmemcpy = FMEMCPY;
_fstrcpy = FSTRCPY;
_memcpy = MEMCPY;
_fmemset = FMEMSET;
_memset = MEMSET;
_memcmp = MEMCMP;
_fmemcmp = FMEMCMP;
_network_redirector_mx = NETWORK_REDIRECTOR_MX;
_execrh = EXECRH;
_share_check = SHARE_CHECK;
_share_open_check = SHARE_OPEN_CHECK;
_share_close_file = SHARE_CLOSE_FILE;
_share_access_check = SHARE_ACCESS_CHECK;
_share_lock_unlock = SHARE_LOCK_UNLOCK;
_share_is_file_open = SHARE_IS_FILE_OPEN;
_call_nls = CALL_NLS;
_fl_reset = FL_RESET;
_fl_diskchanged = FL_DISKCHANGED;
_fl_format = FL_FORMAT;
_fl_read = FL_READ;
_fl_write = FL_WRITE;
_fl_verify = FL_VERIFY;
_fl_setdisktype = FL_SETDISKTYPE;
_fl_setmediatype = FL_SETMEDIATYPE;
_fl_readkey = FL_READKEY;
_fl_lba_ReadWrite = FL_LBA_READWRITE;
_floppy_change = FLOPPY_CHANGE;
_ReadPCClock = READPCCLOCK;
_WritePCClock = WRITEPCCLOCK;
_WriteATClock = WRITEATCLOCK;
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .text)
*(HMA_TEXT_END)
ASSERT(. <= 0x10000,
"Error: too large for a small-model .exe file.");
}
/* Target init text sections. */
.itext 0 : AT (LOADADDR(.text) + SIZEOF(.text)) {
*(INIT_TEXT_START)
*(INIT_TEXT)
_init_execrh = INIT_EXECRH;
_init_memset = INIT_MEMSET;
_init_fmemset = INIT_FMEMSET;
_init_memcmp = INIT_MEMCMP;
_init_fmemcmp = INIT_FMEMCMP;
_init_memcpy = INIT_MEMCPY;
_init_fmemcpy = INIT_FMEMCPY;
_init_strcpy = INIT_STRCPY;
_init_fstrcpy = INIT_FSTRCPY;
_init_strlen = INIT_STRLEN;
_init_fstrlen = INIT_FSTRLEN;
_init_strchr = INIT_STRCHR;
_UMB_get_largest = UMB_GET_LARGEST;
_init_call_intr = INIT_CALL_INTR;
_read = READ;
_init_DosOpen = INIT_DOSOPEN;
_close = CLOSE;
_dup2 = DUP2;
_lseek = LSEEK;
_allocmem = ALLOCMEM;
_init_PSPSet = INIT_PSPSET;
_init_DosExec = INIT_DOSEXEC;
_init_setdrive = INIT_SETDRIVE;
_init_switchar = INIT_SWITCHAR;
_keycheck = KEYCHECK;
_set_DTA = SET_DTA;
_DetectXMSDriver = DETECTXMSDRIVER;
_init_call_XMScall = INIT_CALL_XMSCALL;
__EnableA20 = _ENABLEA20;
__DisableA20 = _DISABLEA20;
*(.text)
*(INIT_TEXT_END)
ASSERT(. <= 0x10000,
"Error: too large for a small-model .exe file.");
}
/* Target init data sections. */
.idata 0 : AT (LOADADDR(.itext) + SIZEOF(.itext)) {
*(ID_B)
*(.data)
*(.rodata) *(.rodata.*)
*(ID_E)
}
.ibss (NOLOAD) : AT (LOADADDR(.idata) + SIZEOF(.idata)) {
*(IB_B)
*(.bss)
*(IB_E)
}
.istack 0 (NOLOAD) : AT (LOADADDR(.ibss) + SIZEOF(.ibss)) {
*(_STACK)
. = 0x1000;
}
/DISCARD/ : { *(.*) }
}