diff --git a/src/arch/i386/Config.lb b/src/arch/i386/Config.lb index 3e72425f27..b85d04ca19 100644 --- a/src/arch/i386/Config.lb +++ b/src/arch/i386/Config.lb @@ -1,7 +1,7 @@ uses CONFIG_SMP -init config/crt0.base -ldscript config/ldscript.lb +init init/crt0.S.lb +ldscript init/ldscript.lb makerule all depends "linuxbios.rom" diff --git a/src/arch/i386/init/crt0.S.lb b/src/arch/i386/init/crt0.S.lb new file mode 100644 index 0000000000..700b01148a --- /dev/null +++ b/src/arch/i386/init/crt0.S.lb @@ -0,0 +1,165 @@ +/* -*- asm -*- + * $ $ + * + */ + +/* + * Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + * + * This file 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. + * + * Originally this code was part of ucl the data compression library + * for upx the ``Ultimate Packer of eXecutables''. + * + * - Converted to gas assembly, and refitted to work with etherboot. + * Eric Biederman 20 Aug 2002 + * - Merged the nrv2b decompressor into crt0.base of LinuxBIOS + * Eric Biederman 26 Sept 2002 + */ + + +#include +#include + +#if CONFIG_SMP==1 +#include +#endif +/* + * This is the entry code the code in .reset section + * jumps to this address. + * + */ +.section ".rom.data", "a", @progbits +.section ".rom.text", "ax", @progbits + + intel_chip_post_macro(0x01) /* delay for chipsets */ + +#include "crt0_includes.h" + + + /* clear boot_complete flag */ + xorl %ebp, %ebp +__main: + CONSOLE_DEBUG_TX_STRING($str_copying_to_ram) + + /* + * Copy data into RAM and clear the BSS. Since these segments + * isn\'t really that big we just copy/clear using bytes, not + * double words. + */ + intel_chip_post_macro(0x11) /* post 11 */ + + cld /* clear direction flag */ + + /* copy linuxBIOS from it's initial load location to + * the location it is compiled to run at. + * Normally this is copying from FLASH ROM to RAM. + */ +#if !CONFIG_COMPRESS + movl $_liseg, %esi + movl $_iseg, %edi + movl $_eiseg, %ecx + subl %edi, %ecx + rep movsb +#else + leal 4+_liseg, %esi + leal _iseg, %edi + movl %ebp, %esp /* preserve %ebp */ + movl $-1, %ebp /* last_m_off = -1 */ + jmp dcl1_n2b + +/* ------------- DECOMPRESSION ------------- + + Input: + %esi - source + %edi - dest + %ebp - -1 + cld + + Output: + %eax - 0 + %ecx - 0 +*/ + +.macro getbit bits +.if \bits == 1 + addl %ebx, %ebx + jnz 1f +.endif + movl (%esi), %ebx + subl $-4, %esi /* sets carry flag */ + adcl %ebx, %ebx +1: +.endm + +decompr_literals_n2b: + movsb + +decompr_loop_n2b: + addl %ebx, %ebx + jnz dcl2_n2b +dcl1_n2b: + getbit 32 +dcl2_n2b: + jc decompr_literals_n2b + xorl %eax, %eax + incl %eax /* m_off = 1 */ +loop1_n2b: + getbit 1 + adcl %eax, %eax /* m_off = m_off*2 + getbit() */ + getbit 1 + jnc loop1_n2b /* while(!getbit()) */ + xorl %ecx, %ecx + subl $3, %eax + jb decompr_ebpeax_n2b /* if (m_off == 2) goto decompr_ebpeax_n2b ? */ + shll $8, %eax + movb (%esi), %al /* m_off = (m_off - 3)*256 + src[ilen++] */ + incl %esi + xorl $-1, %eax + jz decompr_end_n2b /* if (m_off == 0xffffffff) goto decomp_end_n2b */ + movl %eax, %ebp /* last_m_off = m_off ?*/ +decompr_ebpeax_n2b: + getbit 1 + adcl %ecx, %ecx /* m_len = getbit() */ + getbit 1 + adcl %ecx, %ecx /* m_len = m_len*2 + getbit()) */ + jnz decompr_got_mlen_n2b /* if (m_len == 0) goto decompr_got_mlen_n2b */ + incl %ecx /* m_len++ */ +loop2_n2b: + getbit 1 + adcl %ecx, %ecx /* m_len = m_len*2 + getbit() */ + getbit 1 + jnc loop2_n2b /* while(!getbit()) */ + incl %ecx + incl %ecx /* m_len += 2 */ +decompr_got_mlen_n2b: + cmpl $-0xd00, %ebp + adcl $1, %ecx /* m_len = m_len + 1 + (last_m_off > 0xd00) */ + movl %esi, %edx + leal (%edi,%ebp), %esi /* m_pos = dst + olen + -m_off */ + rep + movsb /* dst[olen++] = *m_pos++ while(m_len > 0) */ + movl %edx, %esi + jmp decompr_loop_n2b +decompr_end_n2b: + intel_chip_post_macro(0x12) /* post 12 */ + + movl %esp, %ebp +#endif + + CONSOLE_DEBUG_TX_STRING($str_pre_main) + leal _iseg, %edi + jmp %edi + +.Lhlt: + intel_chip_post_macro(0xee) /* post fe */ + hlt + jmp .Lhlt + +.section ".rom.data" +str_copying_to_ram: .string "Copying LinuxBIOS to ram.\r\n" +str_pre_main: .string "Jumping to LinuxBIOS.\r\n" +.previous diff --git a/src/arch/i386/init/ldscript.lb b/src/arch/i386/init/ldscript.lb new file mode 100644 index 0000000000..1af399cf81 --- /dev/null +++ b/src/arch/i386/init/ldscript.lb @@ -0,0 +1,62 @@ +/* + * Memory map: + * + * _RAMBASE + * : data segment + * : bss segment + * : heap + * : stack + * _ROMBASE + * : linuxbios text + * : readonly text + */ +/* + * Bootstrap code for the STPC Consumer + * Copyright (c) 1999 by Net Insight AB. All Rights Reserved. + * + */ + +/* + * Written by Johan Rydberg, based on work by Daniel Kahlin. + * Rewritten by Eric Biederman + */ +/* + * We use ELF as output format. So that we can + * debug the code in some form. + */ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) + +ENTRY(_start) + +TARGET(binary) +INPUT(linuxbios_payload) +SECTIONS +{ + . = _ROMBASE; + /* This section might be better named .setup */ + .rom . : { + _rom = .; + *(.rom.text); + *(.rom.data); + . = ALIGN(16); + _erom = .; + } + _lrom = LOADADDR(.rom); + _elrom = LOADADDR(.rom) + SIZEOF(.rom); + + .payload . : { + _payload = . ; + linuxbios_payload(*) + _epayload = . ; + } + _iseg = _RAMBASE; + _eiseg = _iseg + SIZEOF(.payload); + _liseg = _payload; + _eliseg = _epayload; + + /DISCARD/ : { + *(.comment) + *(.note) + } +} diff --git a/src/arch/ppc/Config.lb b/src/arch/ppc/Config.lb index 87b54ed080..31ccc297ce 100644 --- a/src/arch/ppc/Config.lb +++ b/src/arch/ppc/Config.lb @@ -1,4 +1,4 @@ -ldscript config/ldscript.lb +ldscript init/ldscript.lb makerule linuxbios.rom depends "linuxbios" diff --git a/src/arch/ppc/init/ldscript.lb b/src/arch/ppc/init/ldscript.lb new file mode 100644 index 0000000000..a8ad86f1c0 --- /dev/null +++ b/src/arch/ppc/init/ldscript.lb @@ -0,0 +1,94 @@ +/* + * Memory map: + * + * _ROMBASE : start of ROM + * _RESET : reset vector (may be at top of ROM) + * _EXCEPTIONS_VECTORS : exception table + * + * _ROMSTART : linuxbios text + * : payload text + * + * _RAMBASE : address to copy payload + */ + +/* + * Written by Johan Rydberg, based on work by Daniel Kahlin. + * Rewritten by Eric Biederman + * Re-rewritten by Greg Watson for PPC + */ + +/* + * We use ELF as output format. So that we can + * debug the code in some form. + */ + +OUTPUT_FORMAT("elf32-powerpc") +ENTRY(_start) + +TARGET(binary) +INPUT(linuxbios_payload) +SECTIONS +{ + /* + * Absolute location of base of ROM + */ + . = _ROMBASE; + + /* + * Absolute location of reset vector. This may actually be at the + * the top of ROM. + */ + . = _RESET; + .reset . : { + *(.rom.reset); + . = ALIGN(16); + } + + /* + * Absolute location of exception vector table. + */ + . = _EXCEPTION_VECTORS; + .exception_vectors . : { + *(.rom.exception_vectors); + . = ALIGN(16); + } + + /* + * Absolute location of LinuxBIOS initialization code in ROM. + */ + . = _ROMSTART; + .rom . : { + _rom = .; + *(.rom.text); + *(.text); + *(.rom.data); + *(.rodata); + *(EXCLUDE_FILE(linuxbios_payload) .data); + . = ALIGN(16); + _erom = .; + } + _lrom = LOADADDR(.rom); + _elrom = LOADADDR(.rom) + SIZEOF(.rom); + + /* + * Payload is LinuxBIOS proper. + */ + .payload . : { + _payload = . ; + linuxbios_payload(*) + _epayload = . ; + } + + /* + * Absolute location of where payload will be relocated in RAM. + */ + _iseg = _RAMBASE; + _eiseg = _iseg + SIZEOF(.payload); + _liseg = _payload; + _eliseg = _epayload; + + /DISCARD/ : { + *(.comment) + *(.note) + } +}