![](/upimg/allimg/070327/1729014.gif) |
Kernel jiffies
The Linux kernel maintains a global variable called jiffies , which represents the number of timer ticks since the machine started. This variable is initialized to zero and increments each timer interrupt. You can read jiffies with the get_jiffies_64 function, and then convert this value to milliseconds (msec) with jiffies_to_msecs or to microseconds (usec) with jiffies_to_usecs . The jiffies' global and associated functions are provided in ./linux/include/linux/jiffies.h.
|
|
Listing 2 provides the third function. This function takes two arguments: a long
and a pointer to a long
that's defined as __user
. The __user
macro simply tells the compiler (through noderef
) that the pointer should not be dereferenced (as it's not meaningful in the current address space). This function calculates the difference between two jiffies values, and then provides the result to the user through a user-space pointer. The put_user
function places the result value into user-space at the location that presult
specifies. If an error occurs during this operation, it will be returned, and you'll likewise notify the user-space caller.
For step 2, I update the header files to make room for the new functions in the system call table. For this, I update the header file linux/include/asm/unistd.h with the new system call numbers. The updates are shown in bold in Listing 3.
Listing 3. Updates to unistd.h to make room for the new system calls
#define __NR_getcpu 318
#define __NR_epoll_pwait 319
#define __NR_getjiffies 320
#define __NR_diffjiffies 321
#define __NR_pdiffjiffies 322
#define NR_syscalls 323
|
Now I have my kernel system calls and numbers to represent them. All I need to do now is draw an equivalence among these numbers (table indexes) and the functions themselves. This is step 3, updating the system call table. As shown in Listing 4, I update the file linux/arch/i386/kernel/syscall_table.S for the new functions that will populate the particular indexes shown in Listing 3.
Listing 4. Update the system call table with the new Functions
.long sys_getcpu
.long sys_epoll_pwait
.long sys_getjiffies /* 320 */
.long sys_diffjiffies
.long sys_pdiffjiffies
|
Note: The size of this table is defined by the symbolic constant NR_syscalls
.
At this point, the kernel is updated. I must recompile the kernel and make the new image available for booting before testing the user-space application.
Reading and writing user memory
The Linux kernel provides several functions that you can use to move system call arguments to and from user-space. Options include simple functions for basic types (such as get_user
or put_user
). For moving blocks of data such as structures or arrays, you can use another set of functions: copy_from_user
and copy_to_user
. Moving null-terminated strings have their own calls: strncpy_from_user
and strlen_from_user共8页: 上一页 [1] [2] 3 [4] [5] [6] [7] [8] 下一页