diff options
| author | Bradley Morgan <brads@mainlining.org> | 2026-10-03 20:02:29 +0000 |
|---|---|---|
| committer | Bradley Morgan <brads@mainlining.org> | 2026-10-03 21:37:00 +0000 |
| commit | 9dbdb15abf8ffb9dbdd972d6bbbcea9a3591e2a3 (patch) | |
| tree | 0fc03f69c4ca60b3306afc7d3a7c86c1fee8437b /lib/string/strlcat.c | |
tashaboot: arm64 bootloader
A small arm64 bootloader. No board code, no device tree porting, the
architecture manual is the whole story: exception vectors in the
fixed 16 slot layout (Table D1-7), ESR_ELx decoded by exception class
(D1-2172), EL entry and eret chains per the programmers model
(D1-2146), cache maintenance by set/way over the CLIDR_EL1 levels,
semihosting for console and file io per DUI 0203, and the A64 boot
protocol from Documentation/arch/arm64/booting.rst.
The loader boots a stock mainline Image end to end on the qemu virt
machine. Boot receipt with 7.3-rc3 (42MB Image):
tashaboot 0.1
loaded 43450368 bytes at 40200000, entry 40200000
jumping
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x411fd070]
[ 0.000000] Linux version 7.3.0-rc3
[ 0.000000] Machine model: linux,dummy-virt
[ 0.000000] earlycon: pl11 MMIO32:0x0000000009000000
...
---[ end Kernel panic - not syncing: VFS: Unable to mount root fs ]---
The panic is the expected end state, no root filesystem is handed
over yet.
The boot chain, state per stage, start to payload:
+-----------+-----+--------------+----------------------------------+
| stage | EL | state | work |
+-----------+-----+--------------+----------------------------------+
| firmware | any | MMU maybe on | x0 = dtb, jump in |
+-----------+-----+--------------+----------------------------------+
| tashaboot | 3-2 | | SCR_EL3.NS = 1, eret to EL2 |
+-----------+-----+--------------+----------------------------------+
| | 2 | virt scrub | HCR/CNTHCTL/CPTR/HSTR, CNTFRQ, |
| | | | VBAR_EL2, MMU off, tlbi alle2 |
+-----------+-----+--------------+----------------------------------+
| | 2 | | load Image over semihosting, |
| | | | validate header, place per |
| | | | booting.rst |
+-----------+-----+--------------+----------------------------------+
| | 2 | caches clean | flush dcache, inval icache, |
| | | | args ride x20/x21, regs last |
+-----------+-----+--------------+----------------------------------+
| payload | 2 | fresh start | x0 = dtb, x1-x3 = 0, DAIF |
| | | | masked, br to image entry |
+-----------+-----+--------------+----------------------------------+
Two handoff bugs the kernel caught, both AAPCS clobbers in the final
jump. Cache maintenance was called after the register setup, x0-x18
are caller saved, so tb_flush_dcache_all() wiped the dtb pointer and
the kernel spun in setup_machine_fdt() with an invalid device tree
blob. The flush helpers also clobbered x1 (u-boot's void call
convention left mov x1, x0 in cache.S) which handed the kernel a wild
x0. The arguments ride in x20/x21 across the cache calls now, callee
saved, and the register setup is the last thing before the branch.
What is missing on purpose: no SMP bringup (secondary cores park),
no PSCI, no initrd or root filesystem handoff, single serial
console. Those come next.
Signed-off-by: Bradley Morgan <brads@mainlining.org>
Diffstat (limited to 'lib/string/strlcat.c')
| -rw-r--r-- | lib/string/strlcat.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/string/strlcat.c b/lib/string/strlcat.c new file mode 100644 index 0000000..c94e90d --- /dev/null +++ b/lib/string/strlcat.c @@ -0,0 +1,55 @@ +/* $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <string.h> + +/* + * Appends src to string dst of size dsize (unlike strncat, dsize is the + * full size of dst, not space left). At most dsize-1 characters + * will be copied. Always NUL terminates (unless dsize <= strlen(dst)). + * Returns strlen(src) + MIN(dsize, strlen(initial dst)). + * If retval >= dsize, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t dsize) +{ + const char *odst = dst; + const char *osrc = src; + size_t n = dsize; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end. */ + while (n-- != 0 && *dst != '\0') + dst++; + dlen = dst - odst; + n = dsize - dlen; + + if (n-- == 0) + return(dlen + strlen(src)); + while (*src != '\0') { + if (n != 0) { + *dst++ = *src; + n--; + } + src++; + } + *dst = '\0'; + + return(dlen + (src - osrc)); /* count does not include NUL */ +} |
