Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Embedded FreeBSD Cookbook phần 3 potx
Nội dung xem thử
Mô tả chi tiết
36 Embedded FreeBSD
Cookbook
The copyin function copies len bytes of data from the user mode address
uaddr to the kernel mode address kaddr. The copyout function copies
len bytes of data from the kernel mode address kaddr to the user mode
address uaddr.
The sysent Structure
Every system call in the FreeBSD kernel has a sysent structure, defined in
/usr/include/sys/sysent.h. The sysent structure takes two elements,
the number of parameters, which is two as defined by the dumpmem_args
structure, and the name of the system call function. Listing 3-7 defines the
copymem sysent.
static struct sysent copymem_sysent =
{
4, /* number of parameters */
copymem /* system call */
};
Listing 3-7
System calls are contained in the sysent structure, defined in
/sys/kern/init_sysent.c. When a KLD system call is made, a new
entry is added to the kernel global sysent structure. Listing 3-8 contains a
partial listing of the sysent structure.
/* The casts are bogus but will do for now. */
struct sysent sysent[] = {
{ 0, (sy_call_t *)nosys }, /* 0 = syscall */
{ AS(rexit_args), (sy_call_t *)exit }, /* 1 = exit */
{ 0, (sy_call_t *)fork }, /* 2 = fork */
{ AS(read_args), (sy_call_t *)read }, /* 3 = read */
{ AS(write_args), (sy_call_t *)write }, /* 4 = write */
{ AS(open_args), (sy_call_t *)open }, /* 5 = open */
{ AS(close_args), (sy_call_t *)close }, /* 6 = close */
Listing 3-8
The System Call Number
A system call number must be declared; since there is no system call number defined, this value should be set to NO_SYSCALL. The kernel defines
the system call number dynamically.
37 Chapter Three
System Calls
static int32_t syscall_num = NO_SYSCALL;
When the KLD system call is loaded into the kernel, systent entry
copymem_sysent is assigned to the first open index in the kernel global
sysent structure. The index into the sysent array is the system call number.
The specifics of installing a new system call are found in the
syscall_register function listed in /sys/kern/kern_syscalls.c.
Listing 3-9 contains the syscall_register function.
int
syscall_register(int *offset, struct sysent *new_sysent,
struct sysent *old_sysent)
{
if (*offset == NO_SYSCALL) {
int i;
for (i = 1; i < SYS_MAXSYSCALL; ++i)
if (sysent[i].sy_call == (sy_call_t
*)lkmnosys)
break;
if (i == SYS_MAXSYSCALL)
return ENFILE;
*offset = i;
} else if (*offset < 0 || *offset >= SYS_MAXSYSCALL)
return EINVAL;
else if (sysent[*offset].sy_call != (sy_call_t *)lkmnosys)
return EEXIST;
*old_sysent = sysent[*offset];
sysent[*offset] = *new_sysent;
return 0;
}
Listing 3-9
When a new system call is added, the kernel function syscall_register
is called. The offset and sysent structure for the new call are passed. If the
offset is NO_SYSCALL, syscall_register scans the sysent structure
looking for an empty system call location. If one is found, the system call is
inserted and the offset is set to the index of the sysent structure, where the
call has been inserted.