openhwgroup / cva6-sdk

CVA6 SDK containing RISC-V tools and Buildroot
60 stars 65 forks source link

Fatal error "asm/types.h: No such file or directory" when compiling with riscv64-unknown-elf-gcc #44

Closed 0ena closed 3 years ago

0ena commented 3 years ago

Hi,

I am trying to build a simple Linux Kernel Module that will use the printk() in order to print from inside the kernel. At the moment I am trying to compile this example. The make file I am using is the following:

WARN    := -W -Wall -Wstrict-prototypes -Wmissing-prototypes
INCLUDE := -isystem /lib/modules/`uname -r`/build/include
CFLAGS  := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE}
CC      := riscv64-unknown-elf-gcc
OBJS    := ${patsubst %.c, %.o, ${wildcard *.c}}

all: ${OBJS}

.PHONY: clean

clean:
        rm -rf *.o

As you can see the gcc I am using is the riscv64-unknown-elf-gcc, after building the Ariane SDK tools. When I am executing make all, I get the following error:

riscv64-unknown-elf-gcc  -O2 -DMODULE -D__KERNEL__ -W -Wall -Wstrict-prototypes -Wmissing-prototypes -isystem /lib/modules/`uname -r`/build/include   -c -o hello-2.o hello-2.c
hello-2.c:10: warning: "MODULE" redefined
 #define MODULE

<command-line>: note: this is the location of the previous definition
hello-2.c:12: warning: "__KERNEL__" redefined
 #define __KERNEL__

<command-line>: note: this is the location of the previous definition
In file included from /usr/src/kernels/3.10.0-1127.19.1.el7.x86_64/include/linux/types.h:5,
                 from /usr/src/kernels/3.10.0-1127.19.1.el7.x86_64/include/linux/list.h:4,
                 from /usr/src/kernels/3.10.0-1127.19.1.el7.x86_64/include/linux/module.h:9,
                 from hello-2.c:14:
/usr/src/kernels/3.10.0-1127.19.1.el7.x86_64/include/uapi/linux/types.h:4:10: fatal error: asm/types.h: No such file or directory
 #include <asm/types.h>
          ^~~~~~~~~~~~~
compilation terminated.
make: *** [hello-2.o] Error 1

I am using Centos 7 and the Linux kernel is Linux 3.10.0-1127.19.1.el7.x86_64.

How can I solve this error? I believe it might have to do with the Linux header files, but I don't know how to proceed.

Any response would be really helpful. Thank you in advance for your responses.

Kind regards, Nassos

Moschn commented 3 years ago

I am no expert in kernel modules, but I think you need to link to the kernel where you want to install your module, i.e., the kernel tree in this repo. Now you are probably using your host kernel header files:

INCLUDE := -isystem /lib/modules/`uname -r`/build/include
0ena commented 3 years ago

Good catch @Moschn! I'll change the makefile and link to the kernel tree of Ariane-sdk. I'll post back if I find any difficulties.

0ena commented 3 years ago

Hi @Moschn,

I think I managed to compile my kernel module. What I did was the following:

static int init_module(void) { printk("Hello, world 2\n"); return 0; }

static void cleanup_module(void) { printk("Goodbye, world 2\n"); }


- I changed my Makefile to the following

WARN := -W -Wall -Wstrict-prototypes -Wmissing-prototypes INCLUDE := -isystem /PATH_TO_ARIANE_TOOLCHAIN/ariane-riscv-toolchain/sysroot/usr/include/ CFLAGS := -O2 -DMODULE -DKERNEL ${WARN} ${INCLUDE} CC := riscv64-unknown-elf-gcc OBJS := ${patsubst %.c, %.o, ${wildcard *.c}}

all: ${OBJS}

.PHONY: clean

clean: rm -rf *.o

The `/ariane-riscv-toolchain/sysroot/usr/include/` has inside all the header files

aio.h bits envz.h fstab.h iconv.h linux net netrose pty.h search.h stdio_ext.h termio.h utime.h aliases.h byteswap.h err.h fts.h ieee754.h locale.h netash nfs pwd.h semaphore.h stdio.h termios.h utmp.h alloca.h complex.h errno.h ftw.h ifaddrs.h malloc.h netatalk nl_types.h rdma setjmp.h stdlib.h tgmath.h utmpx.h a.out.h cpio.h error.h _G_config.h inttypes.h math.h netax25 nss.h re_comp.h sgtty.h string.h thread_db.h values.h argp.h crypt.h execinfo.h gconv.h langinfo.h mcheck.h netdb.h obstack.h regex.h shadow.h strings.h time.h video argz.h ctype.h fcntl.h getopt.h lastlog.h memory.h neteconet paths.h regexp.h signal.h stropts.h ttyent.h wait.h ar.h dirent.h features.h glob.h libgen.h misc netinet poll.h resolv.h sound sys uchar.h wchar.h arpa dlfcn.h fenv.h gnu libintl.h mntent.h netipx printf.h rpc spawn.h syscall.h ucontext.h wctype.h asm drm fmtmsg.h gnu-versions.h libio.h monetary.h netiucv proc_service.h rpcsvc stab.h sysexits.h ulimit.h wordexp.h asm-generic elf.h fnmatch.h grp.h limits.h mqueue.h netpacket protocols sched.h stdc-predef.h syslog.h unistd.h xen assert.h endian.h fpu_control.h gshadow.h link.h mtd netrom pthread.h scsi stdint.h tar.h ustat.h


-  The compilation with the makefile gave me the following warnings

riscv64-unknown-elf-gcc -O2 -DMODULE -DKERNEL -W -Wall -Wstrict-prototypes -Wmissing-prototypes -isystem /eda/tools/riscv/ariane-riscv-toolchain/sysroot/usr/include/ -c -o hello-2.o hello-2.c hello-2.c: In function 'init_module': hello-2.c:23:4: warning: implicit declaration of function 'printk' [-Wimplicit-function-declaration] printk("Hello, world 2\n"); ^~ At top level: hello-2.c:29:13: warning: 'cleanup_module' defined but not used [-Wunused-function] static void cleanup_module(void) ^~~~~~ hello-2.c:20:12: warning: 'init_module' defined but not used [-Wunused-function] static int init_module(void) ^~~


but created the .o file. The "implicit declaration" of "printk()" is a little bit disturbing but in at least one other thread that I found, a user with a similar problem with the "printk()" had his module working without a problem. So I decided to go ahead and test it.

- I compiled again the Linux image with my kernel module inside.

- Now when I login inside the Linux kernel, I can see my kernel module under `/`, but now the problem is that the image is missing the `insmod` and `rmmod` applications, so I am not able to un/load the LKM. Is there a way that I can include them inside my Linux image, in order to test my kernel module?

- One more thing is that I haven't still enabled the **loadable kernel module support**, would that solve my problem and include the `insmod` and `rmmod` applications or are these 2 separate issues?

Thank you in advance for your response and time.

Kind regards,
Nassos
0ena commented 3 years ago

I managed to load the insmod and rmmod the way I explained in #43. Now inside my Linux kernel image, I execute insmod hello-2.o and I get the following:

[13037.464810] (missing .modinfo section): No module found in object
[13037.464810] (missing .modinfo section): No module found in object
insmod: can't insert 'hello-2.o': invalid module format

My Makefile as stated above is the following:

WARN    := -W -Wall -Wstrict-prototypes -Wmissing-prototypes
INCLUDE := -isystem /PATH_TO_ARIANE_TOOLCHAIN/ariane-riscv-toolchain/sysroot/usr/include/
CFLAGS  := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE}
CC      := riscv64-unknown-elf-gcc
OBJS    := ${patsubst %.c, %.o, ${wildcard *.c}}

all: ${OBJS}

.PHONY: clean

clean:
        rm -rf *.o

/PATH_TO_ARIANE_TOOLCHAIN/ariane-riscv-toolchain/sysroot/usr/include/ is where I have installed the ariane-sdk tools and the folder contains all the header files .h. When I compile I don't get a .ko but a .o file.

Any ideas on what I might be doing wrong? Is this the proper way to link my LKM to the Linux kernel for Ariane?

Thank you for the support.

Kind regards, Nassos

Moschn commented 3 years ago

I think you have to compile a kernel module differently. I know this kernel module works and is crosscompiled for a Linux kernel image. Maybe take a look at their makefile

0ena commented 3 years ago

Hi @Moschn,

in the link you provided me, they are compiling against the Linux kernel source tree (that's why they have the LINUXSRC := $(PWD)/../linux command in their Makefile). Or at least that is what I am understanding.

To be honest I don't see any kernel source tree inside the Ariane SDK. Where is your kernel tree in this repo? Is it the downloaded ariane-sdk folder or one of the build/buildroot folders inside it?

My current Makefile is the following (I tried to adjust it to the linked example):

DRIVER = hello-2.ko
PWD := $(shell pwd)
LINUXSRC := $(PWD)/../../../../home/user1/tools/ariane-sdk/ariane-sdk/

default:
        $(MAKE) -C $(LINUXSRC) ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- M=$(PWD)

clean:
        rm -rvf *.o *.ko

home/user1/tools/ariane-sdk/ariane-sdk/ is the path where I downloaded your repository.

Thank you for your time.

Kind regards, Nassos

Moschn commented 3 years ago

The linux tree is downloaded by buildroot during build. LINUXSRC probably has to point at the root of the linux tree

Moschn commented 3 years ago

The linux tree is in buildroot/output/build/linux-5.1

0ena commented 3 years ago

I was able to solve my issue and produce a working .ko through this informative guide on how to cross-compile an LKM: https://www.kernel.org/doc/Documentation/kbuild/modules.txt

Thank you for your help @Moschn!

I am closing this thread.

usulkies commented 3 years ago

apk add linux-headers solved it to me on alpine

mirabilos commented 2 years ago

Huh, how did you?

$ make -C ~/stuff/openwrt/build_dir/toolchain-*/linux M=$PWD

I still get:

./include/uapi/linux/types.h:5:10: fatal error: asm/types.h: No such file or directory
    5 | #include <asm/types.h>
      |          ^~~~~~~~~~~~~

And no, installing the host system’s kernel headers won’t help here…

0ena commented 2 years ago

@mirabilos

my default in the Makefile is the following:

default: make -C $(KDIR) ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- M=$(PWD)

mirabilos commented 2 years ago

Athanasios Moschos dixit:

   make -C $(KDIR) ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- M=$(PWD)

Ah, thanks. This was missing from all the documents, but I found similar indication, but several more variables passed, probably cargo-culted, in OpenWrt-near documentation.

bye, //mirabilos -- When he found out that the m68k port was in a pretty bad shape, he did not, like many before him, shrug and move on; instead, he took it upon himself to start compiling things, just so he could compile his shell. How's that for dedication. -- Wouter, about my Debian/m68k revival