#c #linux #linux-kernel
#c #linux #linux-ядро
Вопрос:
Проблема
Я не могу скопировать данные.
Пользовательское пространство
Вот мое пользовательское пространство:
#include<stdio.h>
#include<stdlib.h>
#include<linux/kernel.h>
#include<sys/syscall.h>
#include<unistd.h>
#include<pwd.h>
#include<sys/sysinfo.h>
int main (int argc, char *argv[])
{
void *mytask;
short allsize;
struct sysinfo si;
struct passwd *passwdStruct;
// to get the userid of my raspberry pi so i can see all of us processes
const char * usrnm = argv[1];
passwdStruct = getpwnam(usrnm);
uid_t usrid = passwdStruct->pw_uid;
// testing grabbing information
int holder = 7;
void * ptr; // im making this a void pointer b/c copy_to_user takes a void * as parameter
ptr = amp;holder;
printf("old stuff: %dn", holder);
int sys_retval = syscall(398, usrid, allsize, ptr);
printf("new stuff: n");
printf("p: %dn", holder);
return 0;
}
Пространство ядра
Вот мое пространство ядра:
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/sched.h>
#include<linux/syscalls.h>
//#include<linux/pwd.h> // includes the passwd struct which has id
//#include<sys/types.h>
#include "mycall.h"
#include <linux/unistd.h>
asmlinkage long sys_sayhello(uid_t myusername, int siz, void __user *ptr)
{
uid_t myid = myusername;
const void *kern; // 2nd argument for copy_to_user
struct task_struct *mytask;
// collect all the necessary info into the kernel array
for_each_process(mytask)
{
if (myid == mytask->cred->uid.val) // if the process belongs to the pi user
{
kern = amp;(mytask->pid); // I looked up kernel documentation and
copy_to_user(ptr, kern, sizeof(int)); // looks like pid is an INT type
return;
}
}
return 0;
}
Вывод
Программа выводит:
«старый материал: 7 новых материалов: 7»
Вопрос
Число должно было измениться на первое в pid
моем pi
процессе в выходных данных. Как мне решить эту проблему?
Комментарии:
1. Возможно, это не имеет прямого отношения к вашей проблеме, но все приведение указателей не имеет никакого эффекта. Ядру все равно, какой тип, по мнению пользовательской программы, имел указатель; его интересуют только биты. И почему бы просто не создать все
pid_t
вместо того, чтобы гадать о размереint
?2. Возможно, вам следует вставить некоторый printk, чтобы проверить, будет ли ваш
if (myid == ...)
когда-либо успешным. Возможно, вам вообще никогда не удастся выполнитьcopy_to_user
. Если вы это сделаете, вы также можете захотеть проверить возвращаемое значениеcopy_to_user
.3. Действительно, вы пробовали заставить
copy_to_user
работать в более простом случае?int foo = 12345; if(copy_to_user(ptr, amp;foo, sizeof(int)) != 0) printk("failn");
4. Наконец, проверьте значение
sys_retval
и, при необходимости, значениеerrno
. Если вы получитеENOSYS
, ваш системный вызов фактически не вызывается.