Page MenuHomeFreeBSD

D29465.diff
No OneTemporary

D29465.diff

diff --git a/stand/powerpc/kboot/Makefile b/stand/powerpc/kboot/Makefile
--- a/stand/powerpc/kboot/Makefile
+++ b/stand/powerpc/kboot/Makefile
@@ -17,9 +17,10 @@
INSTALLFLAGS= -b
# Architecture-specific loader code
-SRCS= conf.c vers.c main.c ppc64_elf_freebsd.c
-SRCS+= host_syscall.S hostcons.c hostdisk.c kerneltramp.S kbootfdt.c
-SRCS+= ucmpdi2.c gfx_fb.c
+SRCS= host_init.S host_syscall.S
+SRCS+= conf.c vers.c main.c ppc64_elf_freebsd.c
+SRCS+= hostcons.c hostdisk.c kerneltramp.S
+SRCS+= kbootfdt.c ucmpdi2.c gfx_fb.c
CFLAGS.gfx_fb.c += -I${SRCTOP}/contrib/pnglite
CFLAGS.gfx_fb.c += -I${SRCTOP}/sys/teken
diff --git a/stand/powerpc/kboot/host_init.S b/stand/powerpc/kboot/host_init.S
new file mode 100644
--- /dev/null
+++ b/stand/powerpc/kboot/host_init.S
@@ -0,0 +1,51 @@
+/*
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asm.h>
+
+/*
+ * Linux-style entry point:
+ * r1: Initial sp
+ * r2: Intialized by ENTRY macro
+ * r3: Need to load argc
+ * r4: Need to load argv
+ * r5: Need to load envp
+ * r6: Need to load auxv
+ * r7: atexit pointer or 0
+ */
+ENTRY(_start)
+ /* Use r6 to traverse the stack. */
+ mr %r6, %r1
+
+ /* Set up initial stack frame. */
+ addi %r1, %r1, -16
+ /* Ensure we're aligned. */
+ clrrwi %r1, %r1, 4
+
+ li %r0, 0
+ /* Ensure the backchain is disconnected. */
+ stw %r0, 0(%r1)
+
+ lwz %r3, 0(%r6) /* argc */
+ addi %r6, %r6, 4 /* next dword */
+ mr %r4, %r6 /* argv */
+ mulli %r5, %r3, 4 /* compute argv size */
+ add %r6, %r6, %r5 /* skip over argv */
+ addi %r6, %r6, 4 /* next dword */
+ mr %r5, %r6 /* envp */
+ /*
+ * Don't bother with auxv for now. If we end up needing it, it's a
+ * word past the first null pointer in envp.
+ */
+ li %r6, 0
+
+ /* This appears to be set to &_start on PPC32. We don't care. */
+ li %r7, 0
+
+ bl main
+ /* Exit via syscall. */
+ b host_exit
+
+END(_start)
diff --git a/stand/powerpc/kboot/host_syscall.S b/stand/powerpc/kboot/host_syscall.S
--- a/stand/powerpc/kboot/host_syscall.S
+++ b/stand/powerpc/kboot/host_syscall.S
@@ -5,6 +5,12 @@
#include <machine/asm.h>
+ENTRY(host_exit)
+ li %r0, 1 # SYS_exit
+ sc
+ trap
+END(host_exit)
+
ENTRY(host_read)
li %r0, 3 # SYS_read
sc
@@ -42,7 +48,7 @@
bso 1f
blr
1:
- li %r3, 0
+ li %r3, -1
blr
END(host_open)
diff --git a/stand/powerpc/kboot/ldscript.powerpc b/stand/powerpc/kboot/ldscript.powerpc
--- a/stand/powerpc/kboot/ldscript.powerpc
+++ b/stand/powerpc/kboot/ldscript.powerpc
@@ -18,7 +18,7 @@
*(.gnu.linkonce.t*)
} =0
_etext = .;
- .interp : { *(.interp) }
+ /DISCARD/ : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
@@ -42,24 +42,25 @@
.rela.plt : { *(.rela.plt) }
.rela.sbss : { *(.rela.sbss) }
.rela.sbss2 : { *(.rela.sbss2) }
- .text :
- {
- *(.text)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0
- _etext = .;
- PROVIDE (etext = .);
.init : { *(.init) } =0
.fini : { *(.fini) } =0
+
+ /*
+ * If the linker wants rodata, ensure it is page aligned.
+ *
+ * This works around a PS3 petitboot bug where alignment would be ignored
+ * and the last text page would have its execution permission removed.
+ */
+ . = ((. + 0x1000) & ~(0x1000 - 1));
.rodata : { *(.rodata) *(.gnu.linkonce.r*) }
.rodata1 : { *(.rodata1) }
.sbss2 : { *(.sbss2) }
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
/* Adjust the address for the data segment to the next page up. */
. = ((. + 0x1000) & ~(0x1000 - 1));
.data :
{
+ *(.data.rel.ro) /* Skip extra section creation */
*(.data)
*(.gnu.linkonce.d*)
CONSTRUCTORS
diff --git a/stand/powerpc/kboot/main.c b/stand/powerpc/kboot/main.c
--- a/stand/powerpc/kboot/main.c
+++ b/stand/powerpc/kboot/main.c
@@ -250,11 +250,12 @@
}
int
-main(int argc, const char **argv)
+main(int argc, const char **argv, char **envp)
{
void *heapbase;
const size_t heapsize = 15*1024*1024;
const char *bootdev;
+ char **env;
/*
* Set the heap to one page after the end of the loader.
@@ -262,6 +263,12 @@
heapbase = host_getmem(heapsize);
setheap(heapbase, heapbase + heapsize);
+ /*
+ * Copy out environment.
+ */
+ for (env = envp; *env != NULL; env++)
+ putenv(*env);
+
/*
* Set up console.
*/
@@ -480,23 +487,6 @@
*ptr = &loaded_segments[0];
}
-void
-_start(int argc, const char **argv, char **env)
-{
-// This makes error "variable 'sp' is uninitialized" be just a warning on clang.
-// Initializing 'sp' is not desired here as it would overwrite "r1" original value
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic warning "-Wuninitialized"
-#endif
- register volatile void **sp asm("r1");
- main((int)sp[0], (const char **)&sp[1]);
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
-}
-
/*
* Since proper fdt command handling function is defined in fdt_loader_cmd.c,
* and declaring it as extern is in contradiction with COMMAND_SET() macro

File Metadata

Mime Type
text/plain
Expires
Thu, Dec 25, 4:01 PM (7 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27251021
Default Alt Text
D29465.diff (5 KB)

Event Timeline