diff options
Diffstat (limited to 'arch/x86/lib/barebox.lds.S')
-rw-r--r-- | arch/x86/lib/barebox.lds.S | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/arch/x86/lib/barebox.lds.S b/arch/x86/lib/barebox.lds.S new file mode 100644 index 0000000000..2917d2fa12 --- /dev/null +++ b/arch/x86/lib/barebox.lds.S @@ -0,0 +1,194 @@ +/* + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#undef i386 +#include <asm/barebox.lds.h> + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +MEMORY +{ + mbr(rwx): ORIGIN = TEXT_BASE, LENGTH = 2 * SECTOR_SIZE + barebox (rwx) : ORIGIN = TEXT_BASE + SECTOR_SIZE, LENGTH = (256 * 1024 * 1024) +} + +SECTIONS +{ +#ifdef CONFIG_X86_HDBOOT + + .ramlayout : { + boot_stack = INDIRECT_AREA; + indirect_area = INDIRECT_AREA; + } + /* describing the main boot sector */ + .bootsector : AT (0) { + *(.boot_start) + + . = 0x00b; + /* + * Maybe later on occupied by a "BIOS parameter block". So, + * keep it free from code. + * - BytesPerSector dw@0x000B + * - SectorsPerCluster db@0x000D + * - ReservedSectors dw@0x000E + * - FatCopies db@0x0010 + * - RootDirEntries dw@0x0011 + * - NumSectors dw@0x0013 + * - MediaType db@0x0015 + * - SectorsPerFAT dw@0x0016 + * - SectorsPerTrack dw@0x0018 + * - NumberOfHeads dw@0x001A + * - HiddenSectors dd@0x001C + * - SectorsBig dd@0x0020 + */ + LONG(0); + + . = 0x024; + *(.boot_code) + *(.boot_data) + + /* + * embed one "Disk Address Packet Structure" into the boot sector + * This DAPS points to the 'indirect' sector to give the boot code + * an idea what and where to load. Its content must be adapted + * to the system it should run on, so, this structure must be + * located at a well known offset. + */ + . = PATCH_AREA; + indirect_sector_lba = .; + SHORT(0x0010); /* size of this structure */ + SHORT(0x0001); /* one sector */ + SHORT(indirect_area); /* where to store: offset */ + SHORT(0x0000); /* where to store: segment */ + /* the following values are filled by the installer */ + LONG(0x00000000); /* LBA start lower */ + LONG(0x00000000); /* LBA start upper */ + + /* boot disk number used by upper layers */ + . = PATCH_AREA + PATCH_AREA_BOOT_DEV; + boot_disk = .; + BYTE(0x00); /* boot disk number (provided by the BIOS) + + /* information about the persistant environment storage */ + . = PATCH_AREA + PATCH_AREA_PERS_START; + pers_env_storage = .; + LONG(0x00000000); /* LBA start lower */ + LONG(0x00000000); /* LBA start upper */ + + . = PATCH_AREA + PATCH_AREA_PERS_SIZE; + pers_env_size = .; + SHORT(PATCH_AREA_PERS_SIZE_UNUSED); /* size of this area in sectors */ + + . = PATCH_AREA + PATCH_AREA_PERS_DRIVE; + pers_env_drive = .; + BYTE(0x00); /* used drive */ + + /* partition table area (fixed location) */ + . = OFFSET_OF_PARTITION_TABLE; + /* create an empty one */ + LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); + LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); + LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); + LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); + + /* boot sector signature */ + . = OFFSET_OF_SIGNATURE; + BYTE(0x55); + BYTE(0xAA); + /* end of the first sector */ + + /* + * The indirect sector starts here + */ + . = SECTOR_SIZE; + BYTE(MARK_DAPS_INVALID); /* mark the first entry invalid */ + BYTE(0x00); + . = SECTOR_SIZE + 496; + BYTE(MARK_DAPS_INVALID); /* mark the last entry invalid */ + BYTE(0x00); + . = SECTOR_SIZE + 508; + LONG(0x00000000); /* LBA start upper */ + } > mbr + + /* some real mode bootstrapping */ + .bootstrapping : AT ( LOADADDR(.bootsector) + SIZEOF(.bootsector) ) { + *(.boot.head) + *(.boot.text*) + *(.boot.rodata*) + *(.boot.data*) + . = ALIGN(4); + } > barebox +#endif + + /* the main barebox part (32 bit) */ + .text : AT ( LOADADDR(.bootstrapping) + SIZEOF(.bootstrapping) ) { + /* do not align here! It may fails with the LOADADDR! */ + _stext = .; + *(.text_entry*) + *(.text_bare_init*) + *(.text*) + . = ALIGN(4); + *(.rodata*) + . = ALIGN(4); + _etext = .; /* End of text and rodata section */ + } > barebox + + .data : AT ( LOADADDR(.text) + SIZEOF(.text) ) { + *(.data*) + . = ALIGN(4); + } > barebox + + .got : AT ( LOADADDR(.data) + SIZEOF (.data) ) { + *(.got*) + . = ALIGN(4); + } > barebox + + .barebox_cmd : AT ( LOADADDR(.got) + SIZEOF (.got) ) { + __barebox_cmd_start = .; + BAREBOX_CMDS + __barebox_cmd_end = .; + . = ALIGN(4); + } > barebox + + .barebox_initcalls : AT ( LOADADDR(.barebox_cmd) + SIZEOF (.barebox_cmd) ) { + __barebox_initcalls_start = .; + INITCALLS + __barebox_initcalls_end = .; + . = ALIGN(4); + } > barebox + + .__usymtab : AT ( LOADADDR(.barebox_initcalls) + SIZEOF (.barebox_initcalls) ) { + __usymtab_start = .; + BAREBOX_SYMS + __usymtab_end = .; + . = ALIGN(4); + } > barebox + + .bss : { + __bss_start = .; + *(.bss*); + *( COMMON ) + __bss_end = .; + _end = .; + } > barebox +} |