Skip to content

Instantly share code, notes, and snippets.

@orangecms
Last active August 28, 2022 15:37
Show Gist options
  • Save orangecms/0f220b6268dab17829915f72f749af11 to your computer and use it in GitHub Desktop.
Save orangecms/0f220b6268dab17829915f72f749af11 to your computer and use it in GitHub Desktop.
kexec FreeBSD (RISC-V)

Loading a Linux ELF

$ cpu-mqpro.sh /bbin/kexec -d ./vmlinux
...
1970/01/02 00:03:48 Kernel: /tmp/kexec-image2840883519
1970/01/02 00:03:48 Command line:
2022/08/25 23:30:57 Wait: wait: remote command exited without exit status or exit signal
[  222.632355] kexec_image: The entry point of kernel at 0x40200000
[  222.641547] kexec_image: Loaded device tree at 0x5fff6000
[  223.841061] kexec_core: Starting new kernel
[  223.845396] Will call new kernel at 5fffda30 from hart id 0
[  223.850996] FDT image at 5fff6000
[  223.854328] Bye...

Loading a default "red herring" FreeBSD kernel

$ cpu-mqpro.sh /bbin/kexec -d ./kernel
........
1970/01/02 00:02:18 Kernel: /tmp/kexec-image2185782358
1970/01/02 00:02:18 Command line:
1970/01/02 00:02:18 SYS_kexec_file_load(11, 0, , 4) = exec format error
1970/01/02 00:02:18 CPUD(as remote):exit status 1
2022/08/25 23:29:12 Wait: Process exited with status 1
[  132.666024] kexec_elf: Requires an ELF interpreter.

grep for it...

kernel/kexec_elf.c

346   for (i = 0; i < ehdr->e_phnum; i++) {
347     /*
348      * Kexec does not support loading interpreters.
349      * In addition this check keeps us from attempting
350      * to kexec ordinay executables.
351      */
352     if (elf_info->proghdrs[i].p_type == PT_INTERP) {
353       pr_err("Requires an ELF interpreter.\n");
354       goto error;
355     }
356   }
kernel: ELF 64-bit LSB executable, UCB RISC-V, RVC, soft-float ABI, version 1 (SYSV), dynamically linked, interpreter /red/herring, BuildID[sha1]=ecc741985e0e7ea342cc734587e27ef2c9df34af, not stripped

Loading a hacky-static FreeBSD kernel

freebsd

src/sys/conf/kern.post.mk

SYSTEM_LD_BASECMD= \
	${LD} -m ${LD_EMULATION} -Bdynamic -T ${LDSCRIPT} ${_LDFLAGS} \
	--no-warn-mismatch --warn-common --export-dynamic \
	--dynamic-linker /red/herring -X

src/sys/conf/kern.pre.mk

# This is a hack.  BFD "optimizes" away dynamic mode if there are no
# dynamic references.  We could probably do a '-Bforcedynamic' mode like
# in the a.out ld.  For now, this works.
force-dynamic-hack.c:
	:> ${.TARGET}

force-dynamic-hack.pico: force-dynamic-hack.c Makefile
	${CC} ${CCLDFLAGS} -shared ${CFLAGS} -nostdlib \
	    force-dynamic-hack.c -o ${.TARGET}
41c8eb30396a1 (Warner Losh         2001-11-02 21:34:20 +0000 230) # This is a hack.  BFD "optimizes" away dynamic mode if there are no
41c8eb30396a1 (Warner Losh         2001-11-02 21:34:20 +0000 231) # dynamic references.  We could probably do a '-Bforcedynamic' mode like
41c8eb30396a1 (Warner Losh         2001-11-02 21:34:20 +0000 232) # in the a.out ld.  For now, this works.
aea2a658ef8b7 (David E. O'Brien    2022-02-13 18:24:36 -0800 233) force-dynamic-hack.c:
aea2a658ef8b7 (David E. O'Brien    2022-02-13 18:24:36 -0800 234)       :> ${.TARGET}
aea2a658ef8b7 (David E. O'Brien    2022-02-13 18:24:36 -0800 235)
aea2a658ef8b7 (David E. O'Brien    2022-02-13 18:24:36 -0800 236) force-dynamic-hack.pico: force-dynamic-hack.c Makefile
aea2a658ef8b7 (David E. O'Brien    2022-02-13 18:24:36 -0800 237)       ${CC} ${CCLDFLAGS} -shared ${CFLAGS} -nostdlib \
aea2a658ef8b7 (David E. O'Brien    2022-02-13 18:24:36 -0800 238)           force-dynamic-hack.c -o ${.TARGET}
41c8eb30396a1 (Warner Losh         2001-11-02 21:34:20 +0000 239)

TODO: work out freebsd/src/sys/kern/link_elf.c?

Hacked up for now:

kstatic: ELF 64-bit LSB executable, UCB RISC-V, RVC, soft-float ABI, version 1 (SYSV), statically linked, BuildID[sha1]=c996484a2e6122e1ed3bd741826b7dbbf0117786, not stripped
$ cpu-mqpro.sh /bbin/kexec -d ./kstatic
........
1970/01/02 00:13:37 Kernel: /tmp/kexec-image3762681189
1970/01/02 00:13:37 Command line:
1970/01/02 00:13:37 SYS_kexec_file_load(11, 0, , 4) = cannot assign requested address
1970/01/02 00:13:38 CPUD(as remote):exit status 1
2022/08/26 22:11:11 Wait: Process exited with status 1

grep for that...

vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
739:    {99, "EADDRNOTAVAIL", "cannot assign requested address"},

https://man7.org/linux/man-pages/man2/kexec_load.2.html

       EADDRNOTAVAIL
              The value in a mem or memsz field in one of the segments
              entries is not a multiple of the system page size.

arch/riscv/kernel/elf_kexec.c

*elf_kexec_load -> elf_find_pbase -> arch_kexec_locate_mem_hole

kernel/kexec_file.c

arch_kexec_locate_mem_hole - Find free memory to place the segments.
  ->
kexec_locate_mem_hole - find free memory for the purgatory or the next kernel

calls into kernel/resource.c: kexec_walk_resources -> walk_system_ram_res

kernel/resource.c: walk_system_ram_res -> __walk_iomem_res_desc -> find_next_iomem_res

kexec Freebsd

[  131.327365] kexec_file: kexec_image_load_default: fops->load
[  131.346115] kexec_image: elf_kexec_load: elf_find_pbase
[  131.351855] kexec_image: elf_find_pbase: locate_mem_hole
[  131.357556] kexec_file: kexec_locate_mem_hole: 0 42172416
[  131.363557] resource: __walk_iomem_res_desc: from 0 to 18446744073709551615
[  131.371254] resource: find_next_iomem_res: searching...
[  131.377115] resource: __walk_iomem_res_desc: ret 0, next 1610612736
[  131.384072] resource: find_next_iomem_res: searching...
[  131.389785] kexec_file: kexec_locate_mem_hole: trouble ahead! 0

With Linux:

[  143.041564] resource: __walk_iomem_res_desc: from 0 to 18446744073709551615
[  143.061282] resource: find_next_iomem_res: searching...
[  143.066909] resource: __walk_iomem_res_desc: ret 0, next 1610612736
[  143.073581] resource: find_next_iomem_res: searching...
[  143.079214] kexec_file: kexec_locate_mem_hole: trouble ahead! 0
[ 4455.190117] resource: __walk_iomem_res_desc: from 0 to 18446744073709551615
[ 4455.197694] resource: find_next_iomem_res: searching...
[ 4455.203426] resource: __walk_iomem_res_desc: ret 1, next 1610612736
[ 4455.210322] kexec_image: The entry point of kernel at 0x40200000
[ 4455.216951] resource: __walk_iomem_res_desc: from 0 to 18446744073709551615
[ 4455.224562] resource: find_next_iomem_res: searching...
[ 4455.230262] resource: __walk_iomem_res_desc: ret 1, next 1610612736
[ 4455.240036] resource: __walk_iomem_res_desc: from 0 to 18446744073709551615
[ 4455.247611] resource: find_next_iomem_res: searching...
[ 4455.253508] resource: __walk_iomem_res_desc: ret 1, next 1610612736
[ 4455.260435] kexec_image: Loaded device tree at 0x5fff6000
[ 4456.467686] kexec_core: Starting new kernel
[ 4456.472028] Will call new kernel at 5fffda30 from hart id 0
[ 4456.477627] FDT image at 5fff6000
[ 4456.480966] Bye...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment