I am no expert either, but as I can see, you get decompression failed. Probably because you supply kernel in a different format (ELF?), than is expected by kexec. So you either need to choose correct format with kexec options ( kexec --help output would help), or to supply the kernel in format supported by kexec (uImage maybe?)
the kernel file is from the openwrt build process:
build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8
binwalk:
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 ELF, 32-bit LSB MIPS64 executable, MIPS, version 1 (SYSV)
3825796 0x3A6084 Linux kernel version "4.14.149 (canavisia@canavisia-Aspire-E5-574G) (gcc version 8.3.0 (OpenWrt GCC 8.3.0 r11242-889b841048)) #0 Fri Oct 18 12:20:40 2"
3903488 0x3B9000 CRC32 polynomial table, little endian
4387000 0x42F0B8 ASCII cpio archive (SVR4 with no CRC), file name: "op (skipped) already calibrated this CPU", file name length: "0xbrating ", file size: "0xInitramf"
4390929 0x430011 Unix path: /arch/mips/include/asm/fpu.h
4404377 0x433499 Unix path: /include/linux/sched/signal.h
4482120 0x446448 xz compressed data
4517072 0x44ECD0 Unix path: /lib/firmware/updates/4.14.149
4535168 0x453380 Unix path: /sys/firmware/devicetree/base
4544161 0x4556A1 Neighborly text, "neighbor table overflow!tics"
4563060 0x45A074 Neighborly text, "NeighborSolicitsports"
4563080 0x45A088 Neighborly text, "NeighborAdvertisements"
4565906 0x45AB92 Neighborly text, "neighbor %.2x%.2x.%pM lost rename link %s to %s"
4890624 0x4AA000 ELF, 32-bit LSB MIPS64 shared object, MIPS, version 1 (SYSV)
5050820 0x4D11C4 ASCII cpio archive (SVR4 with no CRC), file name: "dev", file name length: "0x00000004", file size: "0x00000000"
5050936 0x4D1238 ASCII cpio archive (SVR4 with no CRC), file name: "dev/console", file name length: "0x0000000C", file size: "0x00000000"
5051060 0x4D12B4 ASCII cpio archive (SVR4 with no CRC), file name: "root", file name length: "0x00000005", file size: "0x00000000"
5051176 0x4D1328 ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
i'm trying to launch the same exact kernel from kexec that is already on the device right now for test.
The idea is to be able to kexec newer version of the kernel from external storage, always builded from openwrt
Apparently, it's uncompressed, at least xz entry seems to be bogus, though of course you can try tail -c +4482121 vmlinux.elf | xzcat > unpacked and analyze the content of resulting file with hexdump, strings and binwalk.
Notice that the command is using decimal offset+1.
I have looked up kexec --help but it would help if you post what your particular version outputs.
i tried doing tail -c +4482121 vmlinux.elf | xzcat > unpacked
but it print an error about the data stream being corrupted, i'm not sure if i understood correctly what you asked me to do, i'm not very familiar with binwalk and binary format (especially elf kernel).
The output of kexec on the target:
root@(none):/# kexec -h
kexec-tools 2.0.16
Usage: kexec [OPTION]... [kernel]
Directly reboot into a new kernel
-h, --help Print this help.
-v, --version Print the version of kexec.
-f, --force Force an immediate kexec,
don't call shutdown.
-x, --no-ifdown Don't bring down network interfaces.
-y, --no-sync Don't sync filesystems before kexec.
-l, --load Load the new kernel into the
current kernel.
-p, --load-panic Load the new kernel for use on panic.
-u, --unload Unload the current kexec target kernel.
If capture kernel is being unloaded
specify -p with -u.
-e, --exec Execute a currently loaded kernel.
-t, --type=TYPE Specify the new kernel is of this type.
--mem-min=<addr> Specify the lowest memory address to
load code into.
--mem-max=<addr> Specify the highest memory address to
load code into.
--reuseinitrd Reuse initrd from first boot.
--print-ckr-size Print crash kernel region size.
--load-preserve-context Load the new kernel and preserve
context of current kernel during kexec.
--load-jump-back-helper Load a helper image to jump back
to original kernel.
--entry=<addr> Specify jump back address.
(0 means it's not jump back or
preserve context)
to original kernel.
-s, --kexec-file-syscall Use file based syscall for kexec operation
-d, --debug Enable debugging to help spot a failure.
-S, --status Return 0 if the type (by default crash) is loaded.
Supported kernel file types and options:
elf-mips
Architecture options:
--command-line=STRING Set the kernel command line to STRING.
--append=STRING Set the kernel command line to STRING.
--dtb=FILE Use FILE as the device tree blob.
--initrd=FILE Use FILE as initial ramdisk.
root@(none):/#
also uname -a:
Linux (none) 4.14.149 #0 Fri Oct 18 12:20:40 2019 mips GNU/Linux
It is perfectly normal and expected in this case, because xz stream is embedded in another file. xzcat should still unpack what it could despite the warning. You should have file unpacked created in the directory. Check its content, that's all.
I do not know what else you can do though. Except maybe you can give it dtb file? It should also be compiled if you compiled the complete image from source.
tail -c +4482121 vmlinux.elf | xzcat > unpacked produce a zero byte file
i used extract-vmlinux vmlinux.elf > unpack.elf from the linux repository but it produced a file of the same size. Maybe the kernel is not compressed?? edit: or it dosen't work with .elf files
I tried booting both the compressed kernel and the "uncompressed" one with the dtb as parameter in both case the output was:
The output is truncated since i didn't have access to a serial port and i needed to do via ssh, but from what i see it's the same kernel panic (since the actual booting of the new kernel is with kexec -e.
So it seem that the loading of the kernel is the main problem, id imagine i need to change the memory address but i'm not sure what value to use.
if someone need the complete output of the kernel panic with the btb parameter i can post-it tomorrow.
i'm not sure what to try next, documentation on kexec is scarce
I am seeing this fault in 21.02-rc3 with the 5.4 kernel and also building from head with the 5.10 kernel. This appears to be completely broken. Did you have any luck? Note: This is crashing the kernel before kexec -e is being run.
@xabolcs That is PRECISELY the issue. I modified the kernel config to say "CONFIG_HARDENED_USERCOPY=n" and kexec now works again.
You are a lifesaver, thank you for the pointer. Now I just need to make kexec be able to load a uimage, which shouldn't be too difficult. kexec-tools already support this for other targets, just not mips for some reason.
Will do, along with a patch for kexecing a uimage for mips (once thats working). So that we should be able to kexec directly in to a sysupgrade image held on another flash partition.
While this fixes kexec, unfortunately the MT7621 linux kernel does not like it.
It starts up and detects only 2 processors, and not 4.
Then it complains the PCIE bus is already set up.
It then assigns all the peripherals to different irq's than it does on a clean boot.
And before it can print up the failsafe boot options, it just hangs.
Looks like the MT7621 (and maybe the mips drivers) drivers do not de-initialize themselves properly and rely on the bootloader to give them a clean state on start.
Just an update so if anyone else comes here wondering how to do it.
MT7621 as it stands is broken for kexec. Fixable, but broken.
I don't think my "fixes" would make it into openwrt.
OpenWRT and now upstream as of 5.13, applies a patch to detect single core variant MT7621S version chips. This forces the kexec'd kernel to drop to a single core. I don't know any way to fix it for dual core MT7621 and not break it for single core MT7621.
It looks like both Etherenet drivers and PCI drivers leave the hardware in an odd state when the kernel shuts down, clocks disabled and in reset. Which is NOT what it is out of u-boot. And when you try and init the drivers with this state they hang. I fixed that with some grotesque hackery to force all peripherals into a hardware reset and back out before the kernel itself loads and runs. (I hack the stand alone LZMA loader code to achieve this). Its ugly, but it does work. With both of these hacks an MT7621 will kexec properly.
IF you have a choice and you want to use kexec, use different hardware.