Kernel compilation error (invalid magic number) - linux-kernel

I am trying to compile the kernel from downloaded source. I made the kernel image using sources from kernel.org.
I have successfully loaded it into grub, but when I try to run the loaded module it gives error message: "invalid magic number". I am not getting what I need to fix to get the things done.
Steps that I've followed:
make xconfig,
make bzImage
make modules
make modules_install
I also changed the name of image from bzImage (in /boot folder), then created initrd image from:
# dracut /boot/initramfs-3.1.6-1.fc16.x86_64.img 3.1.6-1.fc16.x86_64 (command copied from net)

Every time you compile a kernel, you must re-compile also the kernel module that you need to use within that kernel. For example, you cannot load a module compiled for kernel 2.6.39 on kernel 3.7. You must recompile it for kernel 3.7.
More details --> better answer

Actually I doubt this has anything to do with kernel modules. As it seems the kernel itself is being refered to as a module. It is possible the kernel got built incorrectly or is being loaded incorrectly possibly from the grub commandline.
http://forums.gentoo.org/viewtopic-t-932358-start-0.html try that.
It is possible that some file in the kernel build didn't get cleaned up properly an so has incorrect data in it since any changes you made in a previous attempt at building it.
Also do note that the x86 images will end up at arch/x86_64/boot/bzImage or arch/x86/boot/bzImage inside the kernel source make sure you actually have copied the kernel itself and not some other incorrect file.
If that fails try grub 1.x as its simpler to use than grub 2.x just note that alot of things are different and you should read tutorials for the correct version of grub. Often grub 1.x will be in a grub-legacy or similar package depending on the distro.
Edit: If you are building your kernel for your hardware only... do not use an initramfs its overkill. There are places you would want to do this is if your system is incapable of loading a kernel large enough for essential drivers (sparc for instance is very limited in kernel image size). another being booting over network possibly but by and large it isn't needed. If you must use an initramfs get your kernel build working without it first.
Also personally I build my kernel with essential drivers included (disk and filesystem basically) and build it with.
make mrproper (save/backup your .config first) ;
make menuconfig ;
make -j8 ;
make modules_install ;
cp arch/x86_64/boot/bzImage /boot/linux-3.7.1 ;
(modify grub to boot the new kernel) and im done and ready to reboot.
Any chance you could attach a screenshot of the failure?

I am not getting your question 100% clearly. Anyway, you downloaded some kernel tree from kernel.org and successfully booted with new Image.
Then you are trying to load a LKM i.e kernel module using insmod or modprobe.
so you are getting "Invalid magic number".
Solution
Need to re-compile the kernel module in new kernel, then try to insert.

Related

Using kexec --load-panic to reboot if file system is corrupted

I have a device which loads a small 'safe mode' Yocto image from coreboot, then selects a larger image to load, and performs a kexec to load that image. Typically this works, but in rare cases the target image's file system has been corrupted and kernel panics on boot.
Since the device will eventually be deployed into locations that are difficult to access, I was hoping to find a way to recover from any kernel panic without having to physically reboot the device.
To fix this, I added an init script using "init=/sbin/init.sh" in the kexec command line when the new kernel is loaded, and I added a recovery kernel load using "kexec --load-panic" in the init script on the 2nd file system. This method successfully recovers kernel panics that happen late in the boot process, but I encountered a file system which was trashed in a particular way so that the kernel panic would occur before the init script gets launched. Since the init script isn't executed, the panic kernel never gets loaded, and the device must be power cycled.
To fix this, I tried adding the recovery kernel into the initial small kernel loaded by coreboot, but it appears to only handle kernel panics that occur before the "kexec --exec" command loads the new kernel.
I'm trying to figure out what is the best way to solve this. For example, I could add validation before I kexec to the new image. I currently check that the file system can be mounted, that its kernel file and the init script are present. If anyone knows which other files are necessary to get to the init script, I could add them to my validation.
Alternatively, is there a way to load the new kernel and kexec to it with the recovery kernel "--load-panic" parameter already loaded?
I tried putting both the kexec --load and --load-panic in the same line, but that doesn't work.
Any recommendation is greatly appreciated.

fail to attach eBPF blob

I've just compiled BPF examples from kernel tools/testing/selftests/bpf and tried to load as explained in http://cilium.readthedocs.io/en/v0.10/bpf/:
% tc filter add dev enp0s1 ingress bpf \
object-file ./net-next.git/tools/testing/selftests/bpf/sockmap_parse_prog.o \
section sk_skb1 verbose
Program section 'sk_skb1' not found in ELF file!
Error fetching program/map!
This happens on Ubuntu 16.04.3 LTS with kernel 4.4.0-98, llvm and clang of version 3.8 installed from packages, iproute2 is the latest from github.
I suspect I'm running into some toolchain/kernel version/features mismatch.
What am I doing wrong?
I do not know why tc complains. On my setup, with a similar command, the program loads. Still, here are some hints:
I think the problem might come, as you suggest, from some incompatibility between kernel headers version and iproute2, and that some relocation fails to occur, although on a quick investigation I did not find exactly why it refuses to load the section. On my side I'm using clang-3.8, latest iproute2, but also the latest kernel (some commit close to 4.14).
If you manage to load the section somehow, I believe you would still encounter problems when trying to attach the program in the kernel. The feature called “direct packet access” is only present on kernels 4.7 and higher. This is what makes you able to use skb->data and skb->data_end in your programs.
Then as a side note, this program sockmap_parse_prog.c is not meant to be used with tc. It is supposed to be attached directly to a socket (search for SOCKMAP_PARSE_PROG in file test_maps.c in the same directory to see how it is loaded there). Technically this does not prevent one to attach the program as a tc filter, but it will probably not work as expected. In particular, the value returned from the program will probably not have a meaning that tc classifier hook will understand.
So I would advise to try with a recent kernel, and to see if you have more success. Alternatively, try compiling and running the examples that you can find in your own kernel sources. Good luck!

Boot linux kernel to terminal

I have a project in mind and for that I require the kernel to boot up and bring me to a console window so that I can start working. [later I'll automate the process].
How do I accomplish it?
Well, I have downloaded the latest stable kernel source from kernel.org and I have tried editing the init/main.c file. But I have no idea what in the world was going on in that file [noob ^n].
Hence, I post this question for an answer.
I require the kernel to boot up and bring me to a console window so that I can start working.
The kernel doesn't do much by itself. In fact, it's unlikely you want to alter "main" in the kernel.
If you want to "run" the kernel, you'll also need a root filesystem and some user-space programs. If you want a minimal userland, you can use "busybox". Even better, buildroot will help you create a minimal userland + kernel.
You can even combine your root filesystem plus the kernel into a single binary. At runtime, it will uncompress userland into a ramdisk and run entirely from RAM. See initramfs. This is super-helpful for embedded systems. A minimal kernel+root filesystem can be around 1MB.
Go through below link
http://balau82.wordpress.com/2010/03/27/busybox-for-arm-on-qemu/
Just black screen after running Qemu

Changing linux kernel system call number

I wanted to build my own custom kernel with a different syscall table. (same syscalls but in different position/numbers)
I was working on kernel 3.2.29.
Changing the kernel was quite easy:
1) changing the syscall position in ‫‪arch/x86/kernel/syscall_table_32.S‬‬
2) changing the syscall macro number in arch/x86/include/asm/unistd_32.h
3) compiling and installing the new kernel
I switched the syscalls around: sys_open took the place and number of sys_read, and vice versa.
I figured that if I compile glibc with the modified kernel headers, I could have a running system, but unfortunately, it wasn't enough and my system won't boot.
Am I missing something? What else do I need to do in order to have a running system?
The steps I have taken are:
1) building and installing the kernel as described in my question
2) extracting the new kernel headers using make headers_install INSTALL_HDR_PATH=[path]
3) building glibc with the parameter --with-headers=[path/include]
4) I used a live cd to access the file system externally in order to install the new glibc, using the make install install_root=[the original file system] (so the system won't break during the install)
I hope that the new glibc was built properly, but I am not sure.
After that, when booting the system, the boot stops in the (initrafms) shell screen:
I guess I need to rebuild the initrd, but how do I compile it according to the new syscall table?
You will have to rebuild everything. Even if all your binaries are dynamically linked, it is possible that the old syscalls were inlined into the binary because many of the C functions are just return syscall(__NR_somecall,...).
You could do this manually, but it could be difficult to keep the toolchains straight unless you use a cross compilable toolchain like buildroot, aboriginal or similar. Pick whichever best suits you (I prefer Rob Landley's aboriginal - http://landley.net/aboriginal/ )
Then to make your initrd just expand the old one using {z,bz,xz}cat oldinit.rd |cpio -id; rm oldinit.rd. Replace the old kernel modules, libs and binaries with the new and cpio and compress it back (cpio needs the -H newc option) ... or now you can rebuild your kernel and point the initramfs to that directory, but wouldn't recommend that if your initrd may need changed frequently such as if for instance you were testing out a whole new syscall structure and having to debug a lot.
Scrambling the system call numbers is really going to hurt. You'll at least need to rebuild all of the statically linked binaries on your system and your initrd (if you use one).
You haven't said at what point the boot fails, but even if the kernel comes up it is likely that the critical programs contained in the initrd compressed ramdisk would fail because they have the original syscall numbers hard-coded. You will need to rebuild and repackage those as well.
You might consider first replacing init with a static hello-world type of program to verify that your kernel can support a userspace at all; then look into the details of making all the complexity of a modern linux userspace match.
you had to learn to reading the messsage of pansic dump and show us what kenrel panic. Without this information, people can hardly help you or provide you useful suggestion.

Qemu arm Linux kernel boot debug, no source code

I am using Qemu to learn some linux kernel development/hacking and wanted to debug the boot process of Linux (2.6.34.3). I have compiled for the ARM versatile platform and is using Codesourcerys arm-none-eabi crosscompiler. I am using Eclipse as the environment to build and debug using gdbserver.
So I have manged to successfully build and run the kernel in qemu but the problem is that I dont see any source code in the debugger at the boot process(at address 0), I can only see the disassembly code. However, when it switches to virtual memory at init/main.c (address over 0xC0000000), the source code appears and I can see the source code and step through and over code. Why is that? I want that from the beginning.
Anyone have any tips on how to debug the boot process of Linux? All the guides in google shows how to debug the kernel, but they all show from start_kernel() (located in init/main.c) and not from the beginning of the boot process (in arch/arm/boot/compressed/head.S). Anyone with experience help please, thank you!
Looked into the System.map in the root folder and there is only symbols for stuff from c0004000 (where the virtual address start). I load vmlinux into gdbserver to get debug information, Maybe thats why theres no source?
The Linux kernel uses a 2-step booting processing (and this does not include any boot loader like u-Boot ...). You can better understand this especially by looking into 2 .lds files (detailed below) for linking:
arch/arm/boot/compressed/vmlinux.lds.in, which generates arch/arm/boot/compressed/vmlinux.lds.
Along with other .o files in arch/arm/boot/compressed, a vmlinux is generated inside this folder.
You can use arm-none-eabi-nm -a -n arch/arm/boot/compressed/vmlinux to see the symbols for this stage. All addresses are physical addresses.
These symbols are NOT included in System.map
The second vmlinux is generated by kernel .o files and arch/arm/kernel/vmlinux.lds (note: the path is different)
I hope this explains why you can not see the booting source code in Eclipse.
linux kernel is too complex to understand(for a beginner).
Why dont use use a smaller OS like xv6:
OS is small, sourcecode is about 8000 lines
used by many universities
based on V6(unix),
boot process is the same except that its less complicated than that of linux.
Appendix B of the xv6 book deals with boot process(its short and sweet).You can run gdb on qemu and see the boot process, the main files to check out for are bootasm.S(in assembler) and bootmain.c.
This is much simpler and easier to do and understand when compared to linux.(atleast for beginners).There are assingmennts on , setting up qemu , using gdb ,tracking the boot process , doing changes to the source code etc in the link given.Give it a shot :)
Cheers,
sharan
head.S is written in assembly, not C. That's what the .S suffix indicates.

Resources