Yüklenebilir bir çekirdek modülünden bir kullanıcı uygulamasına bir sinyal çağrısı yapmayı denerim. Uygulama, sinyal çağrısını işlemek için sigaction
kullanır ve daha sonra switch
ve case
tarafından farklı eylemleri işlemek için sival_int
kullanır. Çekirdek tarafındaÇekirdek: sigqueue işlevlerini kullanma
void signalHandler_function (int signum,
siginfo_t *siginfo,
void *ucontext)
{
printf("signum: %i\n", signum);
printf("sigval: %d\n", siginfo->si_value.sival_int);
}
int main(){
int ret;
int pid = getpid();
char pidc[4];
struct sigaction sig;
memcpy(pidc,&pid,4);
// configure signal handler
sig.sa_flags = SA_SIGINFO;
sig.sa_sigaction = signalHandler_function;
sigaction(SIGIO, &sig, NULL);
g_fdCharDev = open(EXPDEV_DEVPATHNAME, O_RDWR);
printf("My process ID : %d\n", pid);
ret = write(g_fdCharDev, &pid, 1);
...
}
I (birlikte sigqueue_alloc()
ve sigqueue_free()
ile) send_sigqueue()
kullanmayı deneyin. Bu, include/linux/sched.h, line 2320'da extern
olarak bildirilmiş ve kernel/signal.c, line 1560'da tanımlanmıştır. Ama bağlayıcı bu fonksiyonlar tanımsız diyor: o bağlanabilir değildir Neden
#include <linux/init.h> /// Macros used to mark up functions e.g. __init __exit
#include <linux/module.h> /// Core header for loading LKMs into the kernel
#include <linux/device.h> /// Header to support the kernel Driver Model
#include <linux/kernel.h> /// Contains types, macros, functions for the kernel
#include <linux/fs.h> /// Header for the Linux file system support
#include <asm/uaccess.h> /// Required for the copy to user function
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/rcupdate.h>
#include <linux/slab.h>
struct siginfo *g_sig_info;
static struct sigqueue *g_sigqueue;
int g_usp_pid;
struct task_struct *g_sig_task;
static int __init expdev_init(void)
{
...
// setup signal
g_sigqueue = sigqueue_alloc();
g_sigqueue->info.si_signo = SIGIO;
g_sigqueue->info.si_signo = SI_QUEUE;
g_sigqueue->info.si_errno = 0;
...
}
static void __exit expdev_exit(void)
{
sigqueue_free(g_sigqueue);
...
}
static ssize_t dev_write(struct file *filep,
const char *buffer,
size_t len,
loff_t *offset)
{
...
memcpy(&g_usp_pid,buffer,4); // we know the PID comes with the buffer
// find task to the given PID
rcu_read_lock();
g_sig_task = pid_task(find_pid_ns(g_usp_pid, &init_pid_ns),
PIDTYPE_PID);
//send signal to user land
g_sigqueue->info.si_value.sival_int = 33;
ret = send_sigqueue(g_sigqueue, g_sig_task, 0);
...
}
:
İştemake -C /lib/modules/3.19.0-58-generic/build/ M=/home/alex/git/Kernel3/SignalHandling modules
make[1]: Verzeichnis »/usr/src/linux-headers-3.19.0-58-generic« wird betreten
CC [M] /home/alex/git/Kernel3/SignalHandling/ExpDev.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "sigqueue_free" [/home/alex/git/Kernel3/SignalHandling/ExpDev.ko] undefined!
WARNING: "sigqueue_alloc" [/home/alex/git/Kernel3/SignalHandling/ExpDev.ko] undefined!
WARNING: "send_sigqueue" [/home/alex/git/Kernel3/SignalHandling/ExpDev.ko] undefined!
CC /home/alex/git/Kernel3/SignalHandling/ExpDev.mod.o
LD [M] /home/alex/git/Kernel3/SignalHandling/ExpDev.ko
make[1]: Verzeichnis »/usr/src/linux-headers-3.19.0-58-generic« wird verlassen
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
LKM kısaltılmış kaynağını geliyor? Benim yaklaşımım yanlış mı?
Çekirdek modülünde kullanılabilir olmak için, sembol ** dışa aktarılmalıdır ** (EXPORT_SYMBOL). Başlık dosyasında * extern * olarak basit tanım yeterli değildir. – Tsyvarev
@Tsyvarev Evet, biliyorum. Ama işlev de tanımlanıyor. Ama neden bağlantı kurmuyor? – Alex44
Modül, * verilen işlevi tanımlayan kernel/signal.c' ile derlenmiyor. Modül, yalnızca bunu bildiren başlık dosyalarını görür. Modülde *, modülün * bağlanmasıyla * benzer bir şekilde, sadece * dışa aktarılan * semboller çözülür. Bu nedenle * tanımlanmamış sembol * hatası (uyarı) - verilen fonksiyon modülünüz tarafından tanımlanmadığı gibi modpost aşamasında da çözülmez. – Tsyvarev