简体   繁体   中英

Building system calls in Linux. Kernel > 3.x.x

My initial attempts to build a system call with the help of this question

My distro information: Linux linux-epq2.site 3.7.10-1.16-default #1 SMP Fri May 31 20:21:23 UTC 2013 (97c14ba) x86_64 x86_64 x86_64 GNU/Linux

In the current version of my program, that will allow me to embed this as a system call does have a main (stupidity to even say that, but just to make things more explicit).

It takes in two inputs from the user, and does some calculations and gives the output as the graph and some data.

My initial attempt was to call that program via execlp available in unistd library like this:

#include<linux/linkage.h>
#include<linux/kernel.h>
#include<unistd.h>

asmlinkage long graph(const char* granularity, char* application)
{
        pid_t child;
        child = fork();
        if (!child) {
                execlp("./system-call", granularity, application, NULL);
        }
        sleep(0.2);
        return 0;
}

But when I am trying to compile the kernel (note: same kernel version) and the old config file (if necessary i'll also upload the config file). I get the following error:

linux-3.7.10 % make             
make[1]: Nothing to be done for `all'.
make[1]: Nothing to be done for `relocs'.
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
make[3]: `arch/x86/realmode/rm/realmode.bin' is up to date.
  CHK     kernel/config_data.h
  CC      test/graph.o
test/graph.c:10:19: fatal error: unistd.h: No such file or directory
compilation terminated.
make[1]: *** [test/graph.o] Error 1
make: *** [test] Error 2
make  4.50s user 1.27s system 75% cpu 7.626 total`

I checked if glibc was installed or no, i see that all the kernel header files ARE available.

zypper search glibc      
Loading repository data...
Reading installed packages...

S | Name                     | Summary                                               | Type   
--+--------------------------+-------------------------------------------------------+--------
i | glibc                    | Standard Shared Libraries (from the GNU C Library)    | package
i | glibc-32bit              | Standard Shared Libraries (from the GNU C Library)    | package
i | glibc-devel              | Include Files and Libraries Mandatory for Development | package
i | glibc-devel-32bit        | Include Files and Libraries Mandatory for Development | package
i | glibc-devel-static       | C library static libraries for -static linking        | package
i | glibc-devel-static-32bit | C library static libraries for -static linking        | package
i | glibc-extra              | Extra binaries from GNU C Library                     | package
i | glibc-info               | Info Files for the GNU C Library                      | package
i | glibc-locale             | Locale Data for Localized Programs                    | package
i | glibc-locale-32bit       | Locale Data for Localized Programs                    | package
i | glibc-utils              | Development utilities from GNU C library              | package
i | linux-glibc-devel        | Linux headers for userspace development               | package

I checked to see if it is availble in the new kernel dump, and it is not available.

IS IT safe to copy unistd.h from /usr/include/unistd.h to the new kernel dump which I want to compile?

OR is there another way around it?

Here is an update:

I had to change it from #include<unistd.h> to #include<asm/unistd.h> But I still get the error

error: implicit declaration of function ‘fork’ [-Werror=implicit-function-declaration]
error: implicit declaration of function ‘execlp’ [-Werror=implicit-function-declaration]
warning: incompatible implicit declaration of built-in function ‘execlp’ [enabled by default]

Really not sure what the problem is.

On fork()/exec() errors: You can not call library code from kernel mode. Think about what you are trying to do, fork spawns a new user process as a clone of the current process, and exec replaces that process with a new one. Fork and exec are themselves system calls (although the functions you normally call is a libc wrapper around the call itself), so trying to create a system call by calling a system call is bit backward.

On implementing graph(): You can not run userspace programs (like your 'graph' program) from kernel mode, at least not easily. You would need to compile the graph program's code into the kernel somewhere (a module would be nice here, but that's harder then just plonking your .c files into the source tree and compiling them in).

It may be possible to call fork and exec directly from kernel mode, but this is not what you want to be doing to create your graph() system call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM