How to compile a "hello world" /init process? - linux

I'm trying to learn how to build a minimal initramfs for Linux. I set CONFIG_INITRAMFS_SOURCE="asd", created asd directory, inside there's an init file compiled using gcc -fpic -static main.c -o init. In the kernel log I'm getting the following error:
Run /init as init process
Failed to execute /init (error -8)
Here's the input source code:
int main() {
printf("Hello, world!\n");
for(;;);
}
What am I doing wrong?

It works with a defconfig kernel and CONFIG_INITRAMFS_SOURCE set. In the directory I had to make the node dev/console.
mkdir dev
sudo mknod --mode=0600 dev/console c 5 1
After running -kernel linux*/arch/x86_64/boot/bzImage in qemu Hello, world! is shown after calling init.

Related

Linker error : undefined reference to _fbss

I'm sucessfully building pulp-riscv-gnu-toolchain from this this
But when I try to compile my simple source code with builded compiler,
error occured.
My command is riscv32-unknown-elf-g++ -o hello hello.cpp
Error message is /home/jskim/test_toolchains_lib/gcc/riscv32-unknown-elf/7.1.1/../../../../riscv32-unknown-elf/bin/ld : cannot open linker script file riscv.ld : No such file or directory
So I try with this command riscv32-unknown-elf-g++ -o main main.cpp -T /home/jskim/test_toolchains/riscv32-unknown-elf-ld/lib/ldscripts/elf32lriscv.x
But following error occured : /home/jskim/test_toolchains/lib/gcc/riscv32-unknown-elf/7.1.1/../../../../riscv32-unknown-elf/lib/crt0.o: In function '.L0': (.text+0x10):undefined reference to '_fbss' collect2: error: ld returned 1 exit status
I'm using CentOS 7.6 and I try build this pulp-gcc with gcc 4.8.5 and 7.3.1 but both shows me same error. Please help me.
I resolve the problem in this way.
Actually Here is the solution.
I'm not accurate but I think the problem is that the name is not matched.
crt0, which seems to be the helper of start riscv processor has this line la a0 _fbss just basically linker can recognize this if _fbss is replaced with _edata. So i edit the assembly file which is located at pulp-riscv-gnu-toolchain/riscv-newlib/libgloss/riscv/ And rebuild the gnu toolchain. And execute your compiler with -T option like riscv32-unknown-elf-g++ -o main main.cpp -T /home/jskim/test_toolchains/riscv32-unknown-elf-ld/lib/ldscripts/elf32lriscv.x
This is the easiest solution as I think.

Missing slab.h from linux includes - Ubuntu 16 VM

I'm working on a linux kernel driver and need access to the kmalloc and kfree functions. From my research these should be available in the slab.h header, but that file doesn't exist in my filesystem.
I tried updating my includes using this solution: https://askubuntu.com/questions/75709/how-do-i-install-kernel-header-files but it shows that I already have all relevant files.
My system is a VMWare Ubuntu 16.04 installation running kernel 4.15.0.
Any ideas?
Here is a very simple demo module that calls kmalloc and kfree:
demo.c:
#define pr_fmt(fmt) "demo: " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
MODULE_LICENSE("GPL");
static int __init demo_init(void) {
void *buf;
buf = kmalloc(1000, GFP_KERNEL);
pr_info("kmalloc returned %p\n", buf);
kfree(buf);
return 0;
}
static void __exit demo_exit(void) {
}
module_init(demo_init);
module_exit(demo_exit);
Makefile:
ifneq ($(KERNELRELEASE),)
# KBuild part of Makefile
obj-m += demo.o
else
# Normal part of Makefile
#
# Kernel build directory specified by KDIR variable
# Default to running kernel's build directory if KDIR not set externally
KDIR ?= "/lib/modules/`uname -r`/build"
all:
$(MAKE) -C "$(KDIR)" M=`pwd` modules
clean:
$(MAKE) -C "$(KDIR)" M=`pwd` clean
endif
You can just run make to build the module for the currently running kernel version:
$ make
Or you can set KDIR to build the module for an arbitrary kernel version (defined by ${KERNELVER} in the following example):
$ make KDIR="/lib/modules/${KERNELVER}/build"
(If KDIR is unspecified, the Makefile sets it to the build path for the currently running kernel: "/lib/modules/`uname -r`/build".)
If it builds successfully, then you definitely have the kernel headers installed!
To test the module, run:
$ sudo /sbin/insmod demo.ko
$ sudo /sbin/rmmod demo
$ sudo dmesg
There should be a message on the kernel log similar to this showing the return value from the kmalloc() call:
[TIMESTAMP] demo: kmalloc returned xxxxxxxxxxxxxxx
The module also calls kfree() to free the allocated block.

How to make gdb for a target and use it there

I am trying to compile gdb-8.2 from source.
Build machine: x86-64
Host AND target: arm-linux-gnueabi
I ran:
CC=arm-linux-gnueabi-gcc ./configure --host=arm-linux-gnueabi --target=arm-linux-gnueabi
make
Then I ran:
make DESTDIR=<Some Path>/gdb_installation install
So I got a usr folder inside gdb_installation folder. I copied the usr/local/bin/gdb to my target and ran
./gdb
Output:
#./gdb
#
But it does not show anything. It exits without any message.
What am I missing here?
Running the file command shows that the gdb executable is indeed built for my target.
PS: Running a sample hello world program using arm-linux-gnueabi-gcc works perfectly fine on the target; and file command shows the same output that it did for gdb.
What am I missing here?
Your build looks correct, but doesn't work. It's not clear why, so you need to debug that.
What is the exit status of this gdb on the target?
./gdb --version; echo $?
Does it actually do anything? strace ./gdb --version
Is there anything interesting in the kernel message log?
Depending on answers to above questions, further guesses of what has gone wrong will be possible.
Perhaps there is some .gdbinit that tells GDB to quit? What does this do:
./gdb -nx --version?

How to build and run a Linux kernel module on QEMU?

My teacher gives me a linux kernel vmlinuz-3.17.2 and a rootfs.ext2 which can be loaded to qemu. And he asks me to build a simplest kernel module which prints a hello world as homework.
Firstly, I download the kernel source and run make oldconfig
Secondly, I make the config to be PREEMPT and without modversions
(according to uname -a of vmlinuz running in qemu) , then make prepare
Thirdly, I compile the kernel mod and copy hello.ko in rootfs.ext2
Finally, In qemu, I run insmod hello.ko which exit without any prompt
and echo $? returns 0.
However, I can't see anything in dmesg or /var/log/messages
Is there anything wrong? How can I do with this?
There is also nothing to be printed when I run rmmod hello.ko successfully.
My log level is 7 4 1 7
I have make my hello.c as follows:
#include <linux/init.h>
#include <linux/module.h>
static int __init hello_init(void)
{
pr_info("Hello World");
return -1;
// I changed this to -1 deliberately, Because It seems that the code is not executed.
}
static void __exit hello_exit(void)
{
printk(KERN_ERR "Goodbye, cruel world\n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
Buildroot
Buildroot is the easiest way to do it:
minimal out-of-tree example: How to add a Linux kernel driver module as a Buildroot package?
minimal in-tree example: https://github.com/cirosantilli/buildroot/tree/kernel-module-2016.05
how to debug the module with GDB: How to debug Linux kernel modules with QEMU?
Tested on Ubuntu 16.04.

linux/module.h No such file or Directory

For my thesis I am creating a Manet using the protocol ARAN. To install the protocol I'm using this manual, but the first step, the creation of trace_route, I received errors such as:
-linux/module.h: No such file or directory
-linux/procs_Fs: No such file or directory
-linux/skbuff: No such file or directory
I searched the web and found out that the problem is in the headers, but I do not find the solution ...
P.S. I am using Ubuntu 10.04 LTS Kernel 2.6.33 recompiled
You're missing the Linux kernel headers which allow you to compile code against the Linux kernel.
To install just the headers in Ubuntu:
$ sudo apt-get install linux-headers-$(uname -r)
To install the entire Linux kernel source in Ubuntu:
$ sudo apt-get install linux-source
Note that you should use the kernel headers that match the kernel you are running.
**/*source file name is basic.c */**
#include <linux/init.h>
#include <linux/module.h>
/*MODULE_LICENSE("Dual BSD/GPL");*/
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
=====================================
now make file for ubuntu
/*at first type on ur terminal that $(uname -r) then u will get the version..
that is using on ur system */
obj-m +=basic.o
KDIR =//usr/src/linux-headers-3.13.0-44-generic
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* *.symvers *.order
================================================
To run the code
$sudo insmode basic.ko
$dmesg
u will get the output
$sudo rmmod basic.ko
$dmesg

Resources