kboot: Rework _start
Split _start into _start and _start_c (inspired by musl and the powerpc impl is copied from there). This allows us to actually get the command line arguments on all the platforms. We have a very simplified startup that supports only static linking. Sponsored by: Netflix
This commit is contained in:
parent
c1bbe71104
commit
f5ed1b0f84
@ -1,5 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LOADER_DISK_SUPPORT?= yes
|
||||
LOADER_CD9660_SUPPORT?= yes
|
||||
LOADER_MSDOS_SUPPORT?= no
|
||||
LOADER_EXT2FS_SUPPORT?= yes
|
||||
@ -17,7 +18,7 @@ NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH}
|
||||
INSTALLFLAGS= -b
|
||||
|
||||
# Architecture-specific loader code
|
||||
SRCS= vers.c main.c host_syscalls.c hostcons.c hostdisk.c kbootfdt.c gfx_fb_stub.c
|
||||
SRCS= crt1.c vers.c main.c host_syscalls.c hostcons.c hostdisk.c kbootfdt.c gfx_fb_stub.c
|
||||
|
||||
CFLAGS.gfx_fb_stub.c += -I${SRCTOP}/contrib/pnglite -I${SRCTOP}/sys/teken
|
||||
|
||||
|
34
stand/kboot/arch/amd64/start_arch.h
Normal file
34
stand/kboot/arch/amd64/start_arch.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Netflix, Inc.
|
||||
*
|
||||
* SPDX-Licnse-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Provides a _start routine that calls a _start_c routine that takes a pointer
|
||||
* to the stack as documented in crt1.c. We skip the pointer to _DYNAMIC since
|
||||
* we don't support dynamic libraries, at all. And while _start_c is our own
|
||||
* thing, we comport to the calling conventions that glibc and musl have and
|
||||
* make sure the second argument (%esi) is 0 for _DYNAMIC placeholder. We
|
||||
* likely could call main directly with only a few more lines of code, but this
|
||||
* is simple enough and concentrates all the expressable in C stuff there. We
|
||||
* also generate eh_frames should we need to debug things (it doesn't change the
|
||||
* genreated code, but leaves enough breadcrumbs to keep gdb happy).
|
||||
*/
|
||||
|
||||
__asm__(
|
||||
".text\n" /* ENTRY(_start) */
|
||||
".p2align 4,0x90\n"
|
||||
".global _start\n"
|
||||
".type _start, @function\n"
|
||||
"_start:\n"
|
||||
".cfi_startproc\n"
|
||||
" xor %rbp, %rbp\n" /* Clear out the stack frame pointer */
|
||||
" mov %rsp, %rdi\n" /* Pass pointer to current stack with argc, argv and envp on it */
|
||||
" xor %rsi, %rsi\n" /* No dynamic pointer for us, to keep it simple */
|
||||
" andq $-16, %rsp\n" /* Align stack to 16-byte boundary */
|
||||
" call _start_c\n" /* Our MI code takes it from here and won't return */
|
||||
/* NORETURN */
|
||||
".size _start, . - _start\n" /* END(_start) */
|
||||
".cfi_endproc"
|
||||
);
|
30
stand/kboot/arch/powerpc64/start_arch.h
Normal file
30
stand/kboot/arch/powerpc64/start_arch.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Netflix, Inc
|
||||
*
|
||||
* SPDX-Licnse-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Due to the PowerPC ABI, We can call main directly from here, so do so.
|
||||
*
|
||||
* Note: there may be some static initializers that aren't called, but we don't
|
||||
* worry about that elsewhere. This is a stripped down environment.
|
||||
*
|
||||
* I think we could also do something like
|
||||
*
|
||||
* mflr r0
|
||||
* stw r0,4(r1)
|
||||
* stwu r1,-16(r1)
|
||||
* b _start_c
|
||||
*
|
||||
* But my powerpc assembler fu is quite lacking...
|
||||
*/
|
||||
|
||||
#define __unused __attribute__((__unused__))
|
||||
|
||||
void
|
||||
_start(int argc, const char **argv, char **env, void *obj __unused,
|
||||
void (*cleanup)(void) __unused)
|
||||
{
|
||||
main(argc, argv, env);
|
||||
}
|
74
stand/kboot/crt1.c
Normal file
74
stand/kboot/crt1.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Netflix, Inc.
|
||||
*
|
||||
* SPDX-Licnse-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* MI part of the C startup code. We take a long * pointer (we assume long is
|
||||
* the same size as a pointer, as the Linux world is wont to do). We get a
|
||||
* pointer to the stack with the main args on it. We don't bother decoding the
|
||||
* aux vector, but may need to do so in the future.
|
||||
*
|
||||
* The long *p points to:
|
||||
*
|
||||
* +--------------------+
|
||||
* | argc | Small address
|
||||
* +--------------------+
|
||||
* | argv[0] | argv
|
||||
* +--------------------+
|
||||
* | argv[1] |
|
||||
* +--------------------+
|
||||
* ...
|
||||
* +--------------------+
|
||||
* | NULL | &argv[argc]
|
||||
* +--------------------+
|
||||
* | envp[0] | envp
|
||||
* +--------------------+
|
||||
* | envp[1] |
|
||||
* +--------------------+
|
||||
* ...
|
||||
* +--------------------+
|
||||
* | NULL |
|
||||
* +--------------------+
|
||||
* | aux type | AT_xxxx
|
||||
* +--------------------+
|
||||
* | aux value |
|
||||
* +--------------------+
|
||||
* | aux type | AT_xxxx
|
||||
* +--------------------+
|
||||
* | aux value |
|
||||
* +--------------------+
|
||||
* | aux type | AT_xxxx
|
||||
* +--------------------+
|
||||
* | aux value |
|
||||
* +--------------------+
|
||||
*...
|
||||
* +--------------------+
|
||||
* | NULL |
|
||||
* +--------------------+
|
||||
*
|
||||
* The AUX vector contains additional information for the process to know from
|
||||
* the kernel (not parsed currently). AT_xxxx constants are small (< 50).
|
||||
*/
|
||||
|
||||
extern void _start_c(long *);
|
||||
extern int main(int, const char **, char **);
|
||||
|
||||
#include "start_arch.h"
|
||||
|
||||
void
|
||||
_start_c(long *p)
|
||||
{
|
||||
int argc;
|
||||
const char **argv;
|
||||
char **envp;
|
||||
|
||||
argc = p[0];
|
||||
argv = (const char **)(p + 1);
|
||||
envp = (char **)argv + argc + 1;
|
||||
|
||||
/* Note: we don't ensure that fd 0, 1, and 2 are sane at this level */
|
||||
/* Also note: we expect main to exit, not return off the end */
|
||||
main(argc, argv, envp);
|
||||
}
|
@ -479,12 +479,6 @@ kboot_kseg_get(int *nseg, void **ptr)
|
||||
*ptr = &loaded_segments[0];
|
||||
}
|
||||
|
||||
void
|
||||
_start(int argc, const char **argv, char **env)
|
||||
{
|
||||
main(argc, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user