summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/i386/Config.lb4
-rw-r--r--src/arch/i386/init/crt0.S.lb165
-rw-r--r--src/arch/i386/init/ldscript.lb62
-rw-r--r--src/arch/ppc/Config.lb2
-rw-r--r--src/arch/ppc/init/ldscript.lb94
5 files changed, 324 insertions, 3 deletions
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 <arch/asm.h>
+#include <arch/intel.h>
+
+#if CONFIG_SMP==1
+#include <cpu/p6/apic.h>
+#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)
+ }
+}