xref: /freebsd/stand/kboot/libkboot/crt1.c (revision a03411e84728e9b267056fd31c7d1d9d1dc1b01e)
1*a03411e8SWarner Losh /*
2*a03411e8SWarner Losh  * Copyright (c) 2022, Netflix, Inc.
3*a03411e8SWarner Losh  *
4*a03411e8SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
5*a03411e8SWarner Losh  */
6*a03411e8SWarner Losh 
7*a03411e8SWarner Losh /*
8*a03411e8SWarner Losh  * MI part of the C startup code. We take a long * pointer (we assume long is
9*a03411e8SWarner Losh  * the same size as a pointer, as the Linux world is wont to do). We get a
10*a03411e8SWarner Losh  * pointer to the stack with the main args on it. We don't bother decoding the
11*a03411e8SWarner Losh  * aux vector, but may need to do so in the future.
12*a03411e8SWarner Losh  *
13*a03411e8SWarner Losh  * The long *p points to:
14*a03411e8SWarner Losh  *
15*a03411e8SWarner Losh  * +--------------------+
16*a03411e8SWarner Losh  * | argc               | Small address
17*a03411e8SWarner Losh  * +--------------------+
18*a03411e8SWarner Losh  * | argv[0]            | argv
19*a03411e8SWarner Losh  * +--------------------+
20*a03411e8SWarner Losh  * | argv[1]            |
21*a03411e8SWarner Losh  * +--------------------+
22*a03411e8SWarner Losh  *  ...
23*a03411e8SWarner Losh  * +--------------------+
24*a03411e8SWarner Losh  * | NULL               | &argv[argc]
25*a03411e8SWarner Losh  * +--------------------+
26*a03411e8SWarner Losh  * | envp[0]            | envp
27*a03411e8SWarner Losh  * +--------------------+
28*a03411e8SWarner Losh  * | envp[1]            |
29*a03411e8SWarner Losh  * +--------------------+
30*a03411e8SWarner Losh  *  ...
31*a03411e8SWarner Losh  * +--------------------+
32*a03411e8SWarner Losh  * | NULL               |
33*a03411e8SWarner Losh  * +--------------------+
34*a03411e8SWarner Losh  * | aux type           | AT_xxxx
35*a03411e8SWarner Losh  * +--------------------+
36*a03411e8SWarner Losh  * | aux value          |
37*a03411e8SWarner Losh  * +--------------------+
38*a03411e8SWarner Losh  * | aux type           | AT_xxxx
39*a03411e8SWarner Losh  * +--------------------+
40*a03411e8SWarner Losh  * | aux value          |
41*a03411e8SWarner Losh  * +--------------------+
42*a03411e8SWarner Losh  * | aux type           | AT_xxxx
43*a03411e8SWarner Losh  * +--------------------+
44*a03411e8SWarner Losh  * | aux value          |
45*a03411e8SWarner Losh  * +--------------------+
46*a03411e8SWarner Losh  *...
47*a03411e8SWarner Losh  * +--------------------+
48*a03411e8SWarner Losh  * | NULL               |
49*a03411e8SWarner Losh  * +--------------------+
50*a03411e8SWarner Losh  *
51*a03411e8SWarner Losh  * The AUX vector contains additional information for the process to know from
52*a03411e8SWarner Losh  * the kernel (not parsed currently). AT_xxxx constants are small (< 50).
53*a03411e8SWarner Losh  */
54*a03411e8SWarner Losh 
55*a03411e8SWarner Losh extern void _start_c(long *);
56*a03411e8SWarner Losh extern int main(int, const char **, char **);
57*a03411e8SWarner Losh 
58*a03411e8SWarner Losh #include "start_arch.h"
59*a03411e8SWarner Losh 
60*a03411e8SWarner Losh void
_start_c(long * p)61*a03411e8SWarner Losh _start_c(long *p)
62*a03411e8SWarner Losh {
63*a03411e8SWarner Losh 	int argc;
64*a03411e8SWarner Losh 	const char **argv;
65*a03411e8SWarner Losh 	char **envp;
66*a03411e8SWarner Losh 
67*a03411e8SWarner Losh 	argc = p[0];
68*a03411e8SWarner Losh 	argv = (const char **)(p + 1);
69*a03411e8SWarner Losh 	envp = (char **)argv + argc + 1;
70*a03411e8SWarner Losh 
71*a03411e8SWarner Losh 	/* Note: we don't ensure that fd 0, 1, and 2 are sane at this level */
72*a03411e8SWarner Losh 	/* Also note: we expect main to exit, not return off the end */
73*a03411e8SWarner Losh 	main(argc, argv, envp);
74*a03411e8SWarner Losh }
75