Add a new system call at FreeBSD-11 for calculating sum of two values

Hello, I am a beginner in FreeBSD. I installed FreeBSD-11.0-RELEASE-amd64 on VM. I want to add first new system call that it is for calculating sum of two values.
I read a sample in https://www.nostarch.com/rootkits.htm.
Code:
struct sc_example_args {
char *str;
};
static int
sc_example(struct thread *td, void *syscall_args)
{
struct sc_example_args *uap;
uap = (struct sc_example_args *)syscall_args;
printf("%s\n", uap->str);
return(0);
}
Notice that the system call’s arguments are declared within a structure
(sc_example_args). Also, notice that these arguments are accessed within the
system call function by first declaring a struct sc_example_args pointer (uap)
and then assigning the coerced void pointer (syscall_args) to that pointer.
But my function has errors!
myfile.c
Code:
#include <sys/sysproto.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/sysent.h>

#ifndef _SYS_SYSPROTO_H_
  struct myargs {
       unsigned int k0;
       unsigned int k1;
};
#endif

int func (struct thread *td, void *args)
{
     struct myargs *uap;
     unsigned int a,b,c;
     uap = (struct myargs *)args;
     a = uap->k0;
     b = uap->k1;
     c = a + b;
     printf("%u + %u = %u\n",a,b,c);
     return (0);
}

Errors:
Code:
note: forward declaration of 'struct myargs' 
struct myargs *uap;
error: incomplete definition of type 'struct myargs'
a = uap->k0;
 
Why are you enclosing the declaration of the struct myargs in the ifndef/endif guard block? It reads like you expect the sys/sysproto.h header to contain the declaration...
 
Thanks, without #ifndef _SYS_SYSPROTO_H_ it worked!
But, when I call
syscall(550,1,1);
output is:
1 + 0 = 1
But, I send 1+1. I tested it with other numbers again.
Why k1 is zero, always?
 
Why is the second argument of func() a void* and not explicitly a struct myargs*?

Take the time to read the wiki page (and the additional documentation) ShelLuser just mentioned, that should put you on the right tracks and clear up any misunderstanding.
 
Why is the second argument of func() a void* and not explicitly a struct myargs*?

Take the time to read the wiki page (and the additional documentation) ShelLuser just mentioned, that should put you on the right tracks and clear up any misunderstanding.

Hello,
my edited code:

Code:
#include <sys/sysproto.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/sysent.h>

  struct myargs {
       unsigned int k0;
       unsigned int k1;
};

int sys_func(struct thread *td, struct myargs *uap);

int sys_func (struct thread *td, struct myargs *uap)
{
     unsigned int a,b,c;
     a = uap->k0;
     b = uap->k1;
     c = a + b;
     printf("%u + %u = %u\n",a,b,c);
     return (0);
}

But, Errro!
Code:
usr/src/sys/kern/mykern.c:17:5: error: conflicting types for 'sys_func'
int sys_func(struct thread *td, struct myargs *uap)

/usr/src/sys/sys/sysproto.h:2180:5: note: previous declaration is here 
int sys_func(struct thread *, struct func_args *);
I read a part from https://wiki.freebsd.org/AddingSyscalls
Code:
After adding an entry to sys/kern/syscalls.master, you must regenerate the generated files in sys/kern and sys/sys:
$ make -C sys/kern/ sysent
mv -f init_sysent.c init_sysent.c.bak
mv -f syscalls.c syscalls.c.bak
mv -f systrace_args.c systrace_args.c.bak
mv -f ../sys/syscall.h ../sys/syscall.h.bak
mv -f ../sys/syscall.mk ../sys/syscall.mk.bak
mv -f ../sys/sysproto.h ../sys/sysproto.h.bak
sh makesyscalls.sh syscalls.master
I checked sysproto.h file and in it:
Code:
struct func_args {
char uap_l_[PADL_(struct myargs *)]; struct myargs * uap; char uap_r_[PADR_(struct myargs *)];
};



sys_func(struct thread *, struct func_args*);

What is func_args?
Is there any solution?
 
Hello,
What is func_args?
Is there any solution?

suraty, by asking things like these, you expose a lack of knowledge of C basics.... which then lead to a next question: why are you trying to writing kernel code at this stage ?

Writing kernel code is more complex than writing userland programs, due to a variety of rules and restrictions, it seems you want to skip some essential steps ... but that will lead you to frustration only.

You may want to reconsider your learning approach. That said, I'm not a teacher and you are free to proceed as you like.
 
I edited my code, so it has no error. I hope it will be useful for others.
Code:
#include <sys/sysproto.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/sysent.h>

#ifndef _SYS_SYSPROTO_H_
  struct func_args {
       unsigned int k0;
       unsigned int k1;
};
#endif


int sys_func (struct thread *td, struct func_args *uap)
{
     unsigned int a,b,c;
     a = uap->k0;
     b = uap->k1;
     c = a + b;
     printf("%u + %u = %u\n",a,b,c);
     return (0);
}
 
Back
Top