To communicate in kernel mode and user space, I am using this C program. I am using following Makefile to create .ko file to load.
bj-m := sysctl_test.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
After successful execution, and loading the .ko file, it should have create /proc/sys/net/test directory, and value1 and value2 file in that directory.
When I load this module, it doesn't create any file or directory. Am I doing something wrong here or code need some changes?
I have tried by modifying values in structures as:
static ctl_table test_net_table[] = {
{
...
.procname = "/proc/sys/net/test",
...
},
{ .ctl_name = 0 }
};
static ctl_table test_root_table[] = {
{
...
.procname = "/proc/sys/net/",
...
},
{ .ctl_name = 0 }
};
The original values was test and net respectively.
Thanks for your time!
Try changing
bj-m := sysctl_test.o
to
obj-m := sysctl_test.o
it worked for me.
PS:Its an old question, but I update answer for those who come across same error and stop her.
Related
I'm trying to compile and run a "Hello World" module from the book "Linux Device Drivers"
the program ~/ldd3/hello.c I'm trying to compile is:
/*
* $Id: hello.c,v 1.5 2004/10/26 03:32:21 corbet Exp $
*/
#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);
And the Makefile is:
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
When I run make, the compilation seems ok:
root#deb:/home/deb/ldd3# make
make -C /lib/modules/4.14.86/build M=/home/deb/ldd3 modules
make[1]: Entering directory '/home/deb/src/linux-4.14.86'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory '/home/deb/src/linux-4.14.86'
But when I run :
root#deb:/home/deb/ldd3# insmod ./hello.ko
root#deb:/home/deb/ldd3#
the "Hello World" message doesnt get printed.
Nor do I get a message printed when I run
rmmod hello
Can you tell me why?
Thanks
In order to see kernel messages, you can use dmesg.
Alternatively, you can see the syslog tail var/log/syslog.
I wrote a recipe to build a shared library. Here is the recipe
SUMMARY = "test library"
SRC_URI = " file://file1.c \
file://file2.c \
file://internal.h"
LICENSE = "CLOSED"
FILES_${PN} = "libtest.so"
do_compile() {
${CC} -fPIC -c ${WORKDIR}/file1.c -o ${WORKDIR}/file1.o
${CC} -fPIC -c ${WORKDIR}/file2.c -o ${WORKDIR}/file2.o
${CC} -shared -o ${WORKDIR}/libesys.so ${WORKDIR}/file1.o ${WORKDIR}/file2.o
}
do_install() {
install -d ${D}${libdir}
install -m 0644 ${WORKDIR}/libtest.so ${D}${libdir}/
}
It fails with the following errors:
ERROR: test-0.1-r0 do_package_qa: QA Issue: -dev package contains non-symlink .so: test-dev path '/work/corei7-64-poky-linux/test/0.1-r0/packages-split/test-dev/usr/lib64/libtest.so' [dev-elf]
ERROR: test-0.1-r0 do_package_qa: QA Issue: No GNU_HASH in the elf binary: '/home/jamal/repotest1/build/tmp/work/corei7-64-poky-linux/test/0.1-r0/packages-split/test-dev/usr/lib64/libtest.so' [ldflags]
ERROR: test-0.1-r0 do_package_qa: QA run found fatal errors. Please consider fixing them.
ERROR: test-0.1-r0 do_package_qa: Function failed: do_package_qa
ERROR: Logfile of failure stored in: /home/jamal/repotest1/build/tmp/work/corei7-64-poky-linux/test/0.1-r0/temp/log.do_package_qa.20989
ERROR: Task (/home/jamal/repotest1/sources/meta-test/recipes-support/test/test_0.1.bb:do_package_qa) failed with exit code '1'
Can you please help me in to find out the issue.. Appreciate your efforts.
Default packaging rules assumes that libraries are versioned, and your libraries are not.
Either install versioned libraries, or if you really don't want to https://wiki.yoctoproject.org/wiki/TipsAndTricks/Packaging_Prebuilt_Libraries#Non-versioned_Libraries shows you how to manipulate the rules.
LICENSE = "CLOSED"
SRC_URI = "file://greetings.c \
file://greetings.h \
"
S = "${WORKDIR}"
TARGET_CC_ARCH += "${LDFLAGS}"
#INHIBIT_PACKAGE_STRIP = "1"
#INHIBIT_SYSROOT_STRIP = "1"
SOLIBS = ".so"
FILES_SOLIBSDEV = ""
do_configure () {
# Specify any needed configure commands here
:
}
do_compile () {
${CC} -fPIC -c ${WORKDIR}/greetings.c -o ${WORKDIR}/greetings.o
${CC} -shared -o ${WORKDIR}/libtest.so ${WORKDIR}/greetings.o
#g++ -fPIC -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.1.0
}
do_install () {
install -d ${D}${libdir}
install -d ${D}${includedir}
#oe_soinstall ${WORKDIR}/libtest.so ${D}${libdir}
install -m 0644 ${WORKDIR}/libtest.so ${D}${libdir}
install -m 0755 ${S}/*.h ${D}${includedir}
}
My Android project has been going for a couple of years using Eclipse and ADT. The project makes use of 3 precompiled static libraries (curl, ssl, and crypto), and then compiles and statically links libxml2 in. The relevant lines from Android.mk are:
LOCAL_MODULE := my_shim
LOCAL_SRC_FILES := $(LOCAL_FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_CFLAGS := -DCURL_DISABLE_TYPECHECK
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog -lz
LOCAL_SHARED_LIBRARIES :=
LOCAL_STATIC_LIBRARIES += xml2 curl ssl crypto
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../c_module
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../libxml2/include
include $(BUILD_SHARED_LIBRARY)
include $(APP_LOCAL_PATH)/../../libxml2/Android.mk
I'm now switching to Android Studio 2 using Gradle Experimental, but I'm having problems getting the Gradle configuration right. I think I've managed to sort out the dependencies on log and z, and the statically compiled curl, ssl, and crypto libraries, but I can't work out how to tell it to build and then statically link the libxml2 module.
Any clues? This is what I have so far:
model {
android {
...
}
android.ndk {
moduleName "my_shim"
platformVersion 19
abiFilters.addAll(["armeabi", "x86"])
CFlags.add("-DCURL_DISABLE_TYPECHECK")
ldLibs.addAll(["log", "z"])
stl "stlport_static"
}
android.sources {
main {
jni {
dependencies {
library "crypto" linkage "static"
library "curl" linkage "static"
library "ssl" linkage "static"
library "xml2" linkage "static"
}
}
}
}
repositories {
libs(PrebuiltLibraries) {
crypto {
binaries.withType(StaticLibraryBinary) {
def cryptoLibPath = "src/main/jni/includes/${targetPlatform.getName()}/libcrypto.a"
staticLibraryFile = file("${cryptoLibPath}")
}
}
}
libs(PrebuiltLibraries) {
curl {
binaries.withType(StaticLibraryBinary) {
def curlLibPath = "src/main/jni/includes/${targetPlatform.getName()}/libcurl.a"
staticLibraryFile = file("${curlLibPath}")
}
}
}
libs(PrebuiltLibraries) {
ssl {
binaries.withType(StaticLibraryBinary) {
def sslLibPath = "src/main/jni/includes/${targetPlatform.getName()}/libssl.a"
staticLibraryFile = file("${sslLibPath}")
}
}
}
}
}
There're two ways, I think.
Prebuild libxml2 manually and put it with other prebuilt libraries.
Make a dependency (and separate project for xml2 library) It's described here
I'm trying to build a shared library using NDK. My folder structure has two folders, one written in C++ (the core) and one written in Java, called project, which is an Android Studio project. The C++ library is compiled fine and the .a file is generated, but then it's not linking with the shared library. Here's my build.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
classpath 'net.sf.proguard:proguard-gradle:5.2.1'
}
}
apply plugin: 'android-library'
android {
compileSdkVersion 16
buildToolsVersion "23.0.1"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk {
moduleName "core"
cFlags "-std=c++11 -fexceptions -I../core/includes"
stl "stlport_shared"
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
jniLibs.srcDir 'libs'
jni.srcDirs = ['src/main/jni', 'src/main/jni/', 'jni/']
}
}
task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
def ndkDir = plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()
commandLine "$ndkDir/ndk-build",
'-C', file('jni').absolutePath,
'-j', Runtime.runtime.availableProcessors(),
'all',
'NDK_DEBUG=1'
}
task cleanNative(type: Exec, description: 'Clean JNI object files') {
def ndkDir = plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()
commandLine "$ndkDir/ndk-build",
'-C', file('jni').absolutePath,
'clean'
}
task cleanBinaryFolders(type: Delete, description: 'Clean binary folders') {
delete 'libs', 'obj'
}
clean.dependsOn 'cleanNative'
clean.dependsOn 'cleanBinaryFolders'
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
}
dependencies {
compile 'com.android.support:support-v4:20.0.0'
}
Here's my Android.mk:
SHELL = /bin/bash
MY_HOMEDIR = $(realpath $(shell pwd)/../..)
MY_COREDIR = $(MY_HOMEDIR)/core
MY_ANDROIDDIR = $(MY_HOMEDIR)/project
MY_CORESOURCES = $(shell find $(MY_COREDIR)/src -type f -name "*.cpp")
MY_BRIDGESOURCES = $(shell find $(MY_ANDROIDDIR)/jni -type f -name "*.cpp")
LOCAL_PATH = $(MY_HOMEDIR)
# Generate a static library from the core implementation
include $(CLEAR_VARS)
LOCAL_MODULE = core
LOCAL_SRC_FILES = $(MY_CORESOURCES)
TARGET_PLATFORM = android-16
TARGET_ARCH_ABI = all
LOCAL_C_INCLUDES = $(MY_COREDIR)/includes
#LOCAL_LDLIBS = -llog
LOCAL_CFLAGS = -llog -I$(MY_COREDIR)/includes
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE = project
LOCAL_SRC_FILES = $(MY_BRIDGESOURCES)
TARGET_PLATFORM = android-16
TARGET_ARCH_ABI = all
LOCAL_STATIC_LIBRARIES = core
LOCAL_C_INCLUDES = $(MY_COREDIR)/includes
LOCAL_LDLIBS = -lcore # I’m not sure about this
LOCAL_CFLAGS = -llog -I$(MY_COREDIR)/includes
include $(BUILD_SHARED_LIBRARY)
When compiling like this I get a bunch of undefined reference errors, even though the methods are implemented by the core module. What am I missing?
https://stackoverflow.com/a/22401410/755804 reads:
Only use LOCAL_LDLIBS for system library dependencies. If you want to point to another library, it's much better to list them in either LOCAL_STATIC_LIBRARIES and LOCAL_SHARED_LIBRARIES (even if this means defining a PREBUILT_XXX module for them), because this lets the build system work out dependencies and ordering automatically for you.
Hello stackoverflowers :)
For the last several hours I've been trying to compile+load a multiple file module. The compilation emits a strange warning and the module fails to load. Here are the module, Makefile, compilation output and dmesg.
header:
// header.h
#ifndef _HEADER_H
#define _HEADER_H
void do_module_func(void);
void do_other_func(void);
#endif
'main' module file:
//mymodule.c
#include <linux/module.h>
#include <linux/kernel.h>
#include "header.h"
void do_module_func(void)
{
printk(KERN_INFO "module_func\n");
}
static int mymodule_init(void)
{
printk(KERN_INFO "Hello world\n");
do_other_func();
return 0;
}
module_init(mymodule_init);
static void mymodule_exit(void)
{
printk(KERN_INFO "Goodbye, cruel world\n");
}
module_exit(mymodule_exit);
MODULE_LICENSE("GPL")
other c file, which calls do_module_func() that sits in the 'main' module
//other_file.c
#include "header.h"
#include <linux/kernel.h>
void do_other_func(void)
{
printk(KERN_INFO "other_func\n");
do_module_func();
}
Makefile
//Makefile
obj-m := mymodule.o
mymodule-objs := other_file.o
CROSS:=arm-unknown-linux-gnueabi-
KERNEL:= ~/work/linux-davinci-2.6.38/
ARCH:=arm
PWD:=$(shell pwd)
all:
$(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) modules
clean:
$(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) clean
I'm cross compiling but I believe this shouldn't be a problem.
make output:
make CROSS_COMPILE....
make[1]: Entering directory .../linux-davinci-2.6.38
CC [M] .../other_file.o
LD [M] .../mymodule.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "do_module_func" [.../mymodule.o] undefined! <--- warning here
CC .../mymodule.mod.o
LD [M] .../mymodule.ko
make[1]: Leaving directory .../linux-davinci-2.6.38
insmod output:
can't insert 'mymodule.ko': unknown symbol in module, or unknown parameter
dmesg:
mymodule: Unknown symbol do_mdule_func (err 0)
Thus the module compiles with a (linkage?) warning and the module doesn't load.
Now, I see that in the make output there appears to be a linkage attempt after compiling other_file.c, but shouldn't there be a compilation of also mymodule.c before the linkage?
Thanks! :)
Turns out the problem was in the Makefile. The 'trick' is that you define in obj-m the module that will be compiled (into a .ko) and in the -objs you write all the source files.
Thus the definitions in this Makefile turn to:
obj-m := moduleko.o
moduleko-objs := other_file.o mymodule.o
and this is compiled into moduleko.ko.
This is because file_2 required file_1 symbol reference for building file_2 as LKM.
To overcome this, build file_1(LKM) and place the Module.symvers of file_1 in file_2 location. And build the file_2 again.
all:
$(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) modules
instead try like this
$(MAKE) -C $(KERNEL) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS) M=$(PWD) /
this will run each file and links with object.hope this would solve your problem