纠结的系统调用

本文主要研究的内容如下:

1. 什么是系统调用?

2. 系统调用的作用?

3. 系统调用的过程 ?

我们知道从不同的角度可以把操作系统看作不同的作用, 操作系统其实就是管理系统硬件资源的一些代码,协调系统良好的运行, 那么我们要怎样才能够访问系统的资源呢?其实一个方法是系统调用, 因为我们把操作系统分为内核态与用户态(主要是为了安全, 因为有些特权指令只有在内核态才能够访问), 我们编写的应用程序要访问和心态的代码必须用一种适当的方法进入内核, 其实系统调用也是分析系统内核的一种方法(也可以从系统加电到初始化完成的角度去理解Linux的内核), 我们编写代码调用系统调用总的来说有两种方法, 一种是采用汇编语言直接用调用号进入内核, 另外一种方法就是用库的形式(如glibc库)由封装库进入内核, 然后执行完内核服务后返回到用户层。


[flydream@flydream ThinkingInC++]$ gcc -g -Wall -static -m32 test_system_call.c  //采用静态链接

/usr/bin/ld: cannot find -lc

collect2: ld returned 1 exit status  是缺少glibc-static.i686 yum 安装之

-m32 (编译32为程序, 如果系统是64位的则默认回编译64位)


[flydream@flydream ThinkingInC++]$ gcc -g -Wall -static -m32 test_system_call.c //编译成功
[flydream@flydream ThinkingInC++]$ ls
a.out   hello.cpp  test.cpp          test_system_call.c  test_system_call.o
fork.c  open.c     test_system_call  test_system_call.i  test_system_call.s
[flydream@flydream ThinkingInC++]$ ./a.out
Input a num : 89
The return from kernel is 89 !
[flydream@flydream ThinkingInC++]$ 


下面我们来看看系统调用的详细过程:

现看看我们的测试代码:

[flydream@flydream ThinkingInC++]$ cat test_system_call.c
#include <stdio.h>
#include <unistd.h>
#include <syscall.h>

int main(void)
{
    int input;

    printf("Input a num : ");
    scanf("%d",&input);
    
    long rval = syscall(347, input); //这里的347 自己添加的系统调用号. 这个程序也说明了怎么自己添加系统调用
    printf("The return from kernel is %ld !\n", rval);
    return 0;
}
[flydream@flydream ThinkingInC++]$

对上面的代码说明:

1. 关于syscall的申明与实现 (关于如何知道在那个头文件中声明的可以用 man查看)

[root@flydream ThinkingInC++]# cat -n /usr/include/unistd.h | grep syscall
  1075       In Unix, `syscall' sets `errno' for all errors and most calls return -1
  1082    extern long int syscall (long int __sysno, ...) __THROW; 
[root@flydream ThinkingInC++]#  man syscall


SYSCALL(2)                            Linux Programmer's Manual                            SYSCALL(2)

NAME
       syscall - indirect system call

SYNOPSIS
       #define _GNU_SOURCE         /* See feature_test_macros(7) */
       #include <unistd.h>  //从这里可以知道在那个头文件声明
       #include <sys/syscall.h>   /* For SYS_xxx definitions */

       int syscall(int number, ...);


2. syscall函数的实现, 我下载了glibc源码库, 因为syscall函数的实现是在glibc库里面。

[flydream@flydream glibc-2.14.1]$ vim sysdeps/unix/sysv/linux/i386/syscall.S

 .........

 24         .text
 25 ENTRY (syscall) //syscall函数的实现
 26
 27         PUSHARGS_6              /* Save register contents.  */  在这里保存寄存器上下文, 由宏实现,具体代码参看库源码
 28         _DOARGS_6(44)           /* Load arguments.  */    在这里保存用户传递给系统调用的参数, 如果参数大于等于6个则参数会保存在内存中, 然后由EBX指向参数栈
 29         movl 20(%esp), %eax     /* Load syscall number into %eax.  */  这里就是保存系统调用号到EAX寄存器, 不同的体系结构可能不一样。
 30         ENTER_KERNEL            /* Do the system call.  */     这个宏实现进入内核, 下面讨论
 31         POPARGS_6               /* Restore register contents.  */  在这里由系统调用返回, 也就是请求内核服务完成了, 内核执行成功与否有EAX中的值确定
 32         cmpl $-4095, %eax       /* Check %eax for error.  */   
 33         jae SYSCALL_ERROR_LABEL /* Jump to error handler if error.  */  错误处理
 34 L(pseudo_end):
 35         ret                     /* Return to caller.  */
 36
..............


3. 上面两部都只是在用户空间, 其实是在执行glibc库的一些代码现在看看   ENTER_KERNEL            /* Do the system call.  */
 23
 24         .text
 25 ENTRY (syscall)
 26
 27         PUSHARGS_6              /* Save register contents.  */
 28         _DOARGS_6(44)           /* Load arguments.  */
 29         movl 20(%esp), %eax     /* Load syscall number into %eax.  */
 30         ENTER_KERNEL            /* Do the system call.  */
 31         POPARGS_6               /* Restore register contents.  */
 32         cmpl $-4095, %eax       /* Check %eax for error.  */
 33         jae SYSCALL_ERROR_LABEL /* Jump to error handler if error.  */
 34 L(pseudo_end):
 35         ret                     /* Return to caller.  */
 36
 37 PSEUDO_END (syscall)
  # pri kind tag               file
  1 F   d    ENTER_KERNEL      ./sysdeps/unix/sysv/linux/i386/sysdep.h
               195
  2 F   d    ENTER_KERNEL      ./sysdeps/unix/sysv/linux/i386/sysdep.h
               197
  3 F   d    ENTER_KERNEL      ./sysdeps/unix/sysv/linux/i386/sysdep.h
               200

在文件/sysdeps/unix/sysv/linux/i386/sysdep.h中

191 /* The original calling convention for system calls on Linux/i386 is
192    to use int $0x80.  */
193 #ifdef I386_USE_SYSENTER
194 # ifdef SHARED
195 #  define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
196 # else
197 #  define ENTER_KERNEL call *_dl_sysinfo
198 # endif
199 #else
200 # define ENTER_KERNEL int $0x80 //软中断陷入内核, 关于这条指令详解见下面, 执行这条指令后CPU就执行内核态代码了
201 #endif  
202         

4.  经过上面三步就执行内核态代码了, 然而怎么执行内核态代码的呢?

关键在于 int $0x80都做了些什么, 其实0x80是中断向量号, 我们可以从中断向量表里面根据终端向量号可以找到中断服务程序的入口地址, 然而中断向量表的初始化是在内核初始化中完成的在/opt/linux-3.0.4/init/main.c的start_kernel中


508         setup_log_buf(0);
509         pidhash_init();
510         vfs_caches_init_early();
511         sort_main_extable();
512         trap_init();
513         mm_init();

进入trap_init()函数

 2 F   f    trap_init         ./arch/x86/kernel/traps.c

来到了 ./arch/x86/kernel/traps.c文件中

 void __init trap_init(void)
825 {
826         int i;
827
828 #ifdef CONFIG_EISA
829         void __iomem *p = early_ioremap(0x0FFFD9, 4);
830                
831         if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
832                 EISA_bus = 1;
833         early_iounmap(p, 4);
834 #endif
835
836         set_intr_gate(0, &divide_error);
837         set_intr_gate_ist(2, &nmi, NMI_STACK);
838         /* int4 can be called from all */
839         set_system_intr_gate(4, &overflow);
840         set_intr_gate(5, &bounds);
841         set_intr_gate(6, &invalid_op);
842         set_intr_gate(7, &device_not_available);
843 #ifdef CONFIG_X86_32
844         set_task_gate(8, GDT_ENTRY_DOUBLEFAULT_TSS);
845 #else
846         set_intr_gate_ist(8, &double_fault, DOUBLEFAULT_STACK);
847 #endif
848         set_intr_gate(9, &coprocessor_segment_overrun);
849         set_intr_gate(10, &invalid_TSS);
850         set_intr_gate(11, &segment_not_present);
851         set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK);
852         set_intr_gate(13, &general_protection);
853         set_intr_gate(15, &spurious_interrupt_bug);
854         set_intr_gate(16, &coprocessor_error);
855         set_intr_gate(17, &alignment_check);
856 #ifdef CONFIG_X86_MCE       
857         set_intr_gate_ist(18, &machine_check, MCE_STACK);
858 #endif
859         set_intr_gate(19, &simd_coprocessor_error);
860
861         /* Reserve all the builtin and the syscall vector: */
862         for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
863                 set_bit(i, used_vectors);
864
865 #ifdef CONFIG_IA32_EMULATION
866         set_system_intr_gate(IA32_SYSCALL_VECTOR, ia32_syscall);
867         set_bit(IA32_SYSCALL_VECTOR, used_vectors);
868 #endif
869
870 #ifdef CONFIG_X86_32
871         set_system_trap_gate(SYSCALL_VECTOR, &system_call);
872         set_bit(SYSCALL_VECTOR, used_vectors);
873 #endif
874
875         /*
876          * Should be a barrier for any external CPU state:
877          */
878         cpu_init();
879
880         x86_init.irqs.trap_init();
881 }

看到这个函数中最重要的一行

871         set_system_trap_gate(SYSCALL_VECTOR, &system_call);

参数SYSCALL_VECTOR来自文件

"./arch/x86/include/asm/irq_vectors.h" 185L, 5237C

 49 #define IA32_SYSCALL_VECTOR             0x80
 50 #ifdef CONFIG_X86_32
 51 # define SYSCALL_VECTOR                 0x80
 52 #endif 

参数 system_call 来自文件[flydream@flydream linux-3.0.4]$ vim arch/x86/kernel/entry_32.S

 498 ENTRY(system_call)
 499         RING0_INT_FRAME                 # can't unwind into user space anyway
 500         pushl_cfi %eax                  # save orig_eax
 501         SAVE_ALL
 502         GET_THREAD_INFO(%ebp)
 503                                         # system call tracing in operation / emulation
 504         testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
 505         jnz syscall_trace_entry
 506         cmpl $(nr_syscalls), %eax
 507         jae syscall_badsys
 508 syscall_call:
 509      
  call *sys_call_table(,%eax,4)
 510         movl %eax,PT_EAX(%esp)          # store the retu


set_system_trap_gate这个函数就不详细讲解了, 主要是初始化中断向量表, 我们从这里看到了从系统调用一直走到这里说明从glibc库里面的那个int $0x80要执行的函数在初始化的时候已经注册好了, 那么现在就要去执行上面汇编语言编写的system_call函数了一直到509行

看到 509行    call *sys_call_table(,%eax,4)

我们看看sys_call_table在那里定义的呢?

在下面这个文件中:

[flydream@flydream linux-3.0.4]$ cat -n  arch/x86/kernel/syscall_table_32.S
     1    ENTRY(sys_call_table)
     2        .long sys_restart_syscall    /* 0 - old "setup()" system call, used for restarting */
     3        .long sys_exit
     4        .long ptregs_fork
     5        .long sys_read
     6        .long sys_write
     7        .long sys_open        /* 5 */
     8        .long sys_close
     9        .long sys_waitpid
    10        .long sys_creat
    11        .long sys_link
    12        .long sys_unlink    /* 10 */
    13        .long ptregs_execve
    14        .long sys_chdir
    15        .long sys_time
    16        .long sys_mknod
    17        .long sys_chmod        /* 15 */
    18        .long sys_lchown16
    19        .long sys_ni_syscall    /* old break syscall holder */
    20        .long sys_stat
    21        .long sys_lseek
    22        .long sys_getpid    /* 20 */
    23        .long sys_mount
    24        .long sys_oldumount
    25        .long sys_setuid16
    26        .long sys_getuid16
    27        .long sys_stime        /* 25 */
    28        .long sys_ptrace
    29        .long sys_alarm
    30        .long sys_fstat
    31        .long sys_pause
    32        .long sys_utime        /* 30 */
    33        .long sys_ni_syscall    /* old stty syscall holder */
    34        .long sys_ni_syscall    /* old gtty syscall holder */
    35        .long sys_access
    36        .long sys_nice
    37        .long sys_ni_syscall    /* 35 - old ftime syscall holder */
    38        .long sys_sync
    39        .long sys_kill
    40        .long sys_rename
    41        .long sys_mkdir
    42        .long sys_rmdir        /* 40 */
    43        .long sys_dup
    44        .long sys_pipe
    45        .long sys_times
    46        .long sys_ni_syscall    /* old prof syscall holder */
    47        .long sys_brk        /* 45 */
    48        .long sys_setgid16
    49        .long sys_getgid16
    50        .long sys_signal
    51        .long sys_geteuid16
    52        .long sys_getegid16    /* 50 */
    53        .long sys_acct
    54        .long sys_umount    /* recycled never used phys() */
    55        .long sys_ni_syscall    /* old lock syscall holder */
    56        .long sys_ioctl
    57        .long sys_fcntl        /* 55 */
    58        .long sys_ni_syscall    /* old mpx syscall holder */
    59        .long sys_setpgid
    60        .long sys_ni_syscall    /* old ulimit syscall holder */
    61        .long sys_olduname
    62        .long sys_umask        /* 60 */
    63        .long sys_chroot
    64        .long sys_ustat
    65        .long sys_dup2
    66        .long sys_getppid
    67        .long sys_getpgrp    /* 65 */
    68        .long sys_setsid
    69        .long sys_sigaction
    70        .long sys_sgetmask
    71        .long sys_ssetmask
    72        .long sys_setreuid16    /* 70 */
    73        .long sys_setregid16
    74        .long sys_sigsuspend
    75        .long sys_sigpending
    76        .long sys_sethostname
    77        .long sys_setrlimit    /* 75 */
    78        .long sys_old_getrlimit
    79        .long sys_getrusage
    80        .long sys_gettimeofday
    81        .long sys_settimeofday
    82        .long sys_getgroups16    /* 80 */
    83        .long sys_setgroups16
    84        .long sys_old_select
    85        .long sys_symlink
    86        .long sys_lstat
    87        .long sys_readlink    /* 85 */
    88        .long sys_uselib
    89        .long sys_swapon
    90        .long sys_reboot
    91        .long sys_old_readdir
    92        .long sys_old_mmap    /* 90 */
    93        .long sys_munmap
    94        .long sys_truncate
    95        .long sys_ftruncate
    96        .long sys_fchmod
    97        .long sys_fchown16    /* 95 */
    98        .long sys_getpriority
    99        .long sys_setpriority
   100        .long sys_ni_syscall    /* old profil syscall holder */
   101        .long sys_statfs
   102        .long sys_fstatfs    /* 100 */
   103        .long sys_ioperm
   104        .long sys_socketcall
   105        .long sys_syslog
   106        .long sys_setitimer
   107        .long sys_getitimer    /* 105 */
   108        .long sys_newstat
   109        .long sys_newlstat
   110        .long sys_newfstat
   111        .long sys_uname
   112        .long ptregs_iopl    /* 110 */
   113        .long sys_vhangup
   114        .long sys_ni_syscall    /* old "idle" system call */
   115        .long ptregs_vm86old
   116        .long sys_wait4
   117        .long sys_swapoff    /* 115 */
   118        .long sys_sysinfo
   119        .long sys_ipc
   120        .long sys_fsync
   121        .long ptregs_sigreturn
   122        .long ptregs_clone    /* 120 */
   123        .long sys_setdomainname
   124        .long sys_newuname
   125        .long sys_modify_ldt
   126        .long sys_adjtimex
   127        .long sys_mprotect    /* 125 */
   128        .long sys_sigprocmask
   129        .long sys_ni_syscall    /* old "create_module" */
   130        .long sys_init_module
   131        .long sys_delete_module
   132        .long sys_ni_syscall    /* 130:    old "get_kernel_syms" */
   133        .long sys_quotactl
   134        .long sys_getpgid
   135        .long sys_fchdir
   136        .long sys_bdflush
   137        .long sys_sysfs        /* 135 */
   138        .long sys_personality
   139        .long sys_ni_syscall    /* reserved for afs_syscall */
   140        .long sys_setfsuid16
   141        .long sys_setfsgid16
   142        .long sys_llseek    /* 140 */
   143        .long sys_getdents
   144        .long sys_select
   145        .long sys_flock
   146        .long sys_msync
   147        .long sys_readv        /* 145 */
   148        .long sys_writev
   149        .long sys_getsid
   150        .long sys_fdatasync
   151        .long sys_sysctl
   152        .long sys_mlock        /* 150 */
   153        .long sys_munlock
   154        .long sys_mlockall
   155        .long sys_munlockall
   156        .long sys_sched_setparam
   157        .long sys_sched_getparam   /* 155 */
   158        .long sys_sched_setscheduler
   159        .long sys_sched_getscheduler
   160        .long sys_sched_yield
   161        .long sys_sched_get_priority_max
   162        .long sys_sched_get_priority_min  /* 160 */
   163        .long sys_sched_rr_get_interval
   164        .long sys_nanosleep
   165        .long sys_mremap
   166        .long sys_setresuid16
   167        .long sys_getresuid16    /* 165 */
   168        .long ptregs_vm86
   169        .long sys_ni_syscall    /* Old sys_query_module */
   170        .long sys_poll
   171        .long sys_nfsservctl
   172        .long sys_setresgid16    /* 170 */
   173        .long sys_getresgid16
   174        .long sys_prctl
   175        .long ptregs_rt_sigreturn
   176        .long sys_rt_sigaction
   177        .long sys_rt_sigprocmask    /* 175 */
   178        .long sys_rt_sigpending
   179        .long sys_rt_sigtimedwait
   180        .long sys_rt_sigqueueinfo
   181        .long sys_rt_sigsuspend
   182        .long sys_pread64    /* 180 */
   183        .long sys_pwrite64
   184        .long sys_chown16
   185        .long sys_getcwd
   186        .long sys_capget
   187        .long sys_capset    /* 185 */
   188        .long ptregs_sigaltstack
   189        .long sys_sendfile
   190        .long sys_ni_syscall    /* reserved for streams1 */
   191        .long sys_ni_syscall    /* reserved for streams2 */
   192        .long ptregs_vfork    /* 190 */
   193        .long sys_getrlimit
   194        .long sys_mmap_pgoff
   195        .long sys_truncate64
   196        .long sys_ftruncate64
   197        .long sys_stat64    /* 195 */
   198        .long sys_lstat64
   199        .long sys_fstat64
   200        .long sys_lchown
   201        .long sys_getuid
   202        .long sys_getgid    /* 200 */
   203        .long sys_geteuid
   204        .long sys_getegid
   205        .long sys_setreuid
   206        .long sys_setregid
   207        .long sys_getgroups    /* 205 */
   208        .long sys_setgroups
   209        .long sys_fchown
   210        .long sys_setresuid
   211        .long sys_getresuid
   212        .long sys_setresgid    /* 210 */
   213        .long sys_getresgid
   214        .long sys_chown
   215        .long sys_setuid
   216        .long sys_setgid
   217        .long sys_setfsuid    /* 215 */
   218        .long sys_setfsgid
   219        .long sys_pivot_root
   220        .long sys_mincore
   221        .long sys_madvise
   222        .long sys_getdents64    /* 220 */
   223        .long sys_fcntl64
   224        .long sys_ni_syscall    /* reserved for TUX */
   225        .long sys_ni_syscall
   226        .long sys_gettid
   227        .long sys_readahead    /* 225 */
   228        .long sys_setxattr
   229        .long sys_lsetxattr
   230        .long sys_fsetxattr
   231        .long sys_getxattr
   232        .long sys_lgetxattr    /* 230 */
   233        .long sys_fgetxattr
   234        .long sys_listxattr
   235        .long sys_llistxattr
   236        .long sys_flistxattr
   237        .long sys_removexattr    /* 235 */
   238        .long sys_lremovexattr
   239        .long sys_fremovexattr
   240        .long sys_tkill
   241        .long sys_sendfile64
   242        .long sys_futex        /* 240 */
   243        .long sys_sched_setaffinity
   244        .long sys_sched_getaffinity
   245        .long sys_set_thread_area
   246        .long sys_get_thread_area
   247        .long sys_io_setup    /* 245 */
   248        .long sys_io_destroy
   249        .long sys_io_getevents
   250        .long sys_io_submit
   251        .long sys_io_cancel
   252        .long sys_fadvise64    /* 250 */
   253        .long sys_ni_syscall
   254        .long sys_exit_group
   255        .long sys_lookup_dcookie
   256        .long sys_epoll_create
   257        .long sys_epoll_ctl    /* 255 */
   258        .long sys_epoll_wait
   259         .long sys_remap_file_pages
   260         .long sys_set_tid_address
   261         .long sys_timer_create
   262         .long sys_timer_settime        /* 260 */
   263         .long sys_timer_gettime
   264         .long sys_timer_getoverrun
   265         .long sys_timer_delete
   266         .long sys_clock_settime
   267         .long sys_clock_gettime        /* 265 */
   268         .long sys_clock_getres
   269         .long sys_clock_nanosleep
   270        .long sys_statfs64
   271        .long sys_fstatfs64
   272        .long sys_tgkill    /* 270 */
   273        .long sys_utimes
   274         .long sys_fadvise64_64
   275        .long sys_ni_syscall    /* sys_vserver */
   276        .long sys_mbind
   277        .long sys_get_mempolicy
   278        .long sys_set_mempolicy
   279        .long sys_mq_open
   280        .long sys_mq_unlink
   281        .long sys_mq_timedsend
   282        .long sys_mq_timedreceive    /* 280 */
   283        .long sys_mq_notify
   284        .long sys_mq_getsetattr
   285        .long sys_kexec_load
   286        .long sys_waitid
   287        .long sys_ni_syscall        /* 285 */ /* available */
   288        .long sys_add_key
   289        .long sys_request_key
   290        .long sys_keyctl
   291        .long sys_ioprio_set
   292        .long sys_ioprio_get        /* 290 */
   293        .long sys_inotify_init
   294        .long sys_inotify_add_watch
   295        .long sys_inotify_rm_watch
   296        .long sys_migrate_pages
   297        .long sys_openat        /* 295 */
   298        .long sys_mkdirat
   299        .long sys_mknodat
   300        .long sys_fchownat
   301        .long sys_futimesat
   302        .long sys_fstatat64        /* 300 */
   303        .long sys_unlinkat
   304        .long sys_renameat
   305        .long sys_linkat
   306        .long sys_symlinkat
   307        .long sys_readlinkat        /* 305 */
   308        .long sys_fchmodat
   309        .long sys_faccessat
   310        .long sys_pselect6
   311        .long sys_ppoll
   312        .long sys_unshare        /* 310 */
   313        .long sys_set_robust_list
   314        .long sys_get_robust_list
   315        .long sys_splice
   316        .long sys_sync_file_range
   317        .long sys_tee            /* 315 */
   318        .long sys_vmsplice
   319        .long sys_move_pages
   320        .long sys_getcpu
   321        .long sys_epoll_pwait
   322        .long sys_utimensat        /* 320 */
   323        .long sys_signalfd
   324        .long sys_timerfd_create
   325        .long sys_eventfd
   326        .long sys_fallocate
   327        .long sys_timerfd_settime    /* 325 */
   328        .long sys_timerfd_gettime
   329        .long sys_signalfd4
   330        .long sys_eventfd2
   331        .long sys_epoll_create1
   332        .long sys_dup3            /* 330 */
   333        .long sys_pipe2
   334        .long sys_inotify_init1
   335        .long sys_preadv
   336        .long sys_pwritev
   337        .long sys_rt_tgsigqueueinfo    /* 335 */
   338        .long sys_perf_event_open
   339        .long sys_recvmmsg
   340        .long sys_fanotify_init
   341        .long sys_fanotify_mark
   342        .long sys_prlimit64        /* 340 */
   343        .long sys_name_to_handle_at
   344        .long sys_open_by_handle_at
   345        .long sys_clock_adjtime
   346        .long sys_syncfs
   347        .long sys_sendmmsg        /* 345 */
   348        .long sys_setns                /* 346 */

  349    .long sys_RIRI        /* 347  This is added by JYP for syscall 347 这一项是我自己测试添加的 */

说明这里的系统调用号为347

[flydream@flydream linux-3.0.4]$


回到call *sys_call_table(,%eax,4), 那么会执行我们指定系统调用号的函数, 这些函数都是内核的核心函数, 也就是为什么说我们可以用系统调用进入到内核态。


上面列出的sys_***函数的实现主要是在/opt/linux-3.0.4/kernel目录下

比如在/opt/linux-3.0.4/kernel/sys.c中就有很多, 如果自己添加系统调用就可以在这个文件中添加相关的实现。 我自己添加的在/opt/linux-3.0.4/kernel/sys.c文件中:『下面的程序来源于网络』

 939 SYSCALL_DEFINE1(RIRI, int, num)
 940 {
 941     struct task_struct *pos;
 942     struct list_head *current_head;
 943     int count=0;
 944     printk("Traversal module is working..\n");
 945     current_head=&(current->tasks);
 946     list_for_each_entry(pos,current_head,tasks)
 947     {
 948            count++;
 949            printk("[process %d]: %s's pid is %d\n",count,pos->comm,pos->pid);
 950     }
 951     printk(KERN_ALERT"The number of process is %d\n",count);
 952     printk(KERN_ALERT"This is a sample test output from kernel!\nAnd this is added by JYP !\n");
 953     return (long)num;
 954 }

其他的系统调用也是通过上面的原理实现的。

/opt/linux-3.0.4/kernel/sys.c这个文件中就有很多比如:

[flydream@flydream kernel]$ cat -n sys.c  | grep DEFINE | more
   173    SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
   240    SYSCALL_DEFINE2(getpriority, int, which, int, who)
   388    static DEFINE_MUTEX(reboot_mutex);
   398    SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
   514    SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
   561    SYSCALL_DEFINE1(setgid, gid_t, gid)
   624    SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
   685    SYSCALL_DEFINE1(setuid, uid_t, uid)
   726    SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
   776    SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid)
   791    SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
   830    SYSCALL_DEFINE3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid)
   849    SYSCALL_DEFINE1(setfsuid, uid_t, uid)
   882    SYSCALL_DEFINE1(setfsgid, gid_t, gid)
   926    SYSCALL_DEFINE1(times, struct tms __user *, tbuf)
   939    SYSCALL_DEFINE1(RIRI, int, num)
   968    SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid)
  1039    SYSCALL_DEFINE1(getpgid, pid_t, pid)
  1069    SYSCALL_DEFINE0(getpgrp)
  1076    SYSCALL_DEFINE1(getsid, pid_t, pid)
  1104    SYSCALL_DEFINE0(setsid)
  1176    SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
  1196    SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
  1215    SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
  1250    SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
  1275    SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
  1300    SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
  1323    SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim)
  1341    SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
  1483    SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource,
  1525    SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
  1658    SYSCALL_DEFINE2(getrusage, int, who, struct rusage __user *, ru)
  1666    SYSCALL_DEFINE1(umask, int, mask)
  1672    SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
  1827    SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep,

可以看到很多系统调用的内核态实现都是在这个文件中, 我自己添加的也在里面可以看到

939    SYSCALL_DEFINE1(RIRI, int, num)


这些函数的声明:

[flydream@flydream linux-3.0.4]$ cat -n  include/linux/syscalls.h  | grep "asmlinkage long sys_"
   189        asmlinkage long sys_##sname(void)
   191    #define SYSCALL_DEFINE0(name)       asmlinkage long sys_##name(void)
   247    #define SYSCALL_DEFINE(name) asmlinkage long sys_##name
   253    asmlinkage long sys_RIRI(int num); /* added by JYP just for test syscall */
   254    asmlinkage long sys_time(time_t __user *tloc);
   255    asmlinkage long sys_stime(time_t __user *tptr);
   256    asmlinkage long sys_gettimeofday(struct timeval __user *tv,
   258    asmlinkage long sys_settimeofday(struct timeval __user *tv,
   260    asmlinkage long sys_adjtimex(struct timex __user *txc_p);
   262    asmlinkage long sys_times(struct tms __user *tbuf);
   264    asmlinkage long sys_gettid(void);
   265    asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp);
   266    asmlinkage long sys_alarm(unsigned int seconds);
   267    asmlinkage long sys_getpid(void);
   268    asmlinkage long sys_getppid(void);
   269    asmlinkage long sys_getuid(void);
   270    asmlinkage long sys_geteuid(void);
   271    asmlinkage long sys_getgid(void);
   272    asmlinkage long sys_getegid(void);
   273    asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid);
   274    asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid);
   275    asmlinkage long sys_getpgid(pid_t pid);
   276    asmlinkage long sys_getpgrp(void);
   277    asmlinkage long sys_getsid(pid_t pid);
   278    asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist);
   280    asmlinkage long sys_setregid(gid_t rgid, gid_t egid);
   281    asmlinkage long sys_setgid(gid_t gid);
   282    asmlinkage long sys_setreuid(uid_t ruid, uid_t euid);
   283    asmlinkage long sys_setuid(uid_t uid);
   284    asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
   285    asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
   286    asmlinkage long sys_setfsuid(uid_t uid);
   287    asmlinkage long sys_setfsgid(gid_t gid);
   288    asmlinkage long sys_setpgid(pid_t pid, pid_t pgid);
   289    asmlinkage long sys_setsid(void);
   290    asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist);
   292    asmlinkage long sys_acct(const char __user *name);
   293    asmlinkage long sys_capget(cap_user_header_t header,
   295    asmlinkage long sys_capset(cap_user_header_t header,
   297    asmlinkage long sys_personality(unsigned int personality);
   299    asmlinkage long sys_sigpending(old_sigset_t __user *set);
   300    asmlinkage long sys_sigprocmask(int how, old_sigset_t __user *set,
   302    asmlinkage long sys_getitimer(int which, struct itimerval __user *value);
   303    asmlinkage long sys_setitimer(int which,
   306    asmlinkage long sys_timer_create(clockid_t which_clock,
   309    asmlinkage long sys_timer_gettime(timer_t timer_id,
   311    asmlinkage long sys_timer_getoverrun(timer_t timer_id);
   312    asmlinkage long sys_timer_settime(timer_t timer_id, int flags,
   315    asmlinkage long sys_timer_delete(timer_t timer_id);
   316    asmlinkage long sys_clock_settime(clockid_t which_clock,
   318    asmlinkage long sys_clock_gettime(clockid_t which_clock,
   320    asmlinkage long sys_clock_adjtime(clockid_t which_clock,
   322    asmlinkage long sys_clock_getres(clockid_t which_clock,
   324    asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags,
   328    asmlinkage long sys_nice(int increment);
   329    asmlinkage long sys_sched_setscheduler(pid_t pid, int policy,
   331    asmlinkage long sys_sched_setparam(pid_t pid,
   333    asmlinkage long sys_sched_getscheduler(pid_t pid);
   334    asmlinkage long sys_sched_getparam(pid_t pid,
   336    asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
   338    asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len,
   340    asmlinkage long sys_sched_yield(void);
   341    asmlinkage long sys_sched_get_priority_max(int policy);
   342    asmlinkage long sys_sched_get_priority_min(int policy);
   343    asmlinkage long sys_sched_rr_get_interval(pid_t pid,
   345    asmlinkage long sys_setpriority(int which, int who, int niceval);
   346    asmlinkage long sys_getpriority(int which, int who);
   348    asmlinkage long sys_shutdown(int, int);
   349    asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd,
   351    asmlinkage long sys_restart_syscall(void);
   352    asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
   356    asmlinkage long sys_exit(int error_code);
   357    asmlinkage long sys_exit_group(int error_code);
   358    asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr,
   360    asmlinkage long sys_waitid(int which, pid_t pid,
   363    asmlinkage long sys_waitpid(pid_t pid, int __user *stat_addr, int options);
   364    asmlinkage long sys_set_tid_address(int __user *tidptr);
   365    asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val,
   369    asmlinkage long sys_init_module(void __user *umod, unsigned long len,
   371    asmlinkage long sys_delete_module(const char __user *name_user,
   374    asmlinkage long sys_rt_sigprocmask(int how, sigset_t __user *set,
   376    asmlinkage long sys_rt_sigpending(sigset_t __user *set, size_t sigsetsize);
   377    asmlinkage long sys_rt_sigtimedwait(const sigset_t __user *uthese,
   381    asmlinkage long sys_rt_tgsigqueueinfo(pid_t tgid, pid_t  pid, int sig,
   383    asmlinkage long sys_kill(int pid, int sig);
   384    asmlinkage long sys_tgkill(int tgid, int pid, int sig);
   385    asmlinkage long sys_tkill(int pid, int sig);
   386    asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo);
   387    asmlinkage long sys_sgetmask(void);
   388    asmlinkage long sys_ssetmask(int newmask);
   389    asmlinkage long sys_signal(int sig, __sighandler_t handler);
   390    asmlinkage long sys_pause(void);
   392    asmlinkage long sys_sync(void);
   393    asmlinkage long sys_fsync(unsigned int fd);
   394    asmlinkage long sys_fdatasync(unsigned int fd);
   395    asmlinkage long sys_bdflush(int func, long data);
   396    asmlinkage long sys_mount(char __user *dev_name, char __user *dir_name,
   399    asmlinkage long sys_umount(char __user *name, int flags);
   400    asmlinkage long sys_oldumount(char __user *name);
   401    asmlinkage long sys_truncate(const char __user *path, long length);
   402    asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
   403    asmlinkage long sys_stat(const char __user *filename,
   405    asmlinkage long sys_statfs(const char __user * path,
   407    asmlinkage long sys_statfs64(const char __user *path, size_t sz,
   409    asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user *buf);
   410    asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz,
   412    asmlinkage long sys_lstat(const char __user *filename,
   414    asmlinkage long sys_fstat(unsigned int fd,
   416    asmlinkage long sys_newstat(const char __user *filename,
   418    asmlinkage long sys_newlstat(const char __user *filename,
   420    asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf);
   421    asmlinkage long sys_ustat(unsigned dev, struct ustat __user *ubuf);
   423    asmlinkage long sys_stat64(const char __user *filename,
   425    asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf);
   426    asmlinkage long sys_lstat64(const char __user *filename,
   428    asmlinkage long sys_truncate64(const char __user *path, loff_t length);
   429    asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length);
   432    asmlinkage long sys_setxattr(const char __user *path, const char __user *name,
   434    asmlinkage long sys_lsetxattr(const char __user *path, const char __user *name,
   436    asmlinkage long sys_fsetxattr(int fd, const char __user *name,
   438    asmlinkage long sys_getxattr(const char __user *path, const char __user *name,
   440    asmlinkage long sys_lgetxattr(const char __user *path, const char __user *name,
   442    asmlinkage long sys_fgetxattr(int fd, const char __user *name,
   444    asmlinkage long sys_listxattr(const char __user *path, char __user *list,
   446    asmlinkage long sys_llistxattr(const char __user *path, char __user *list,
   448    asmlinkage long sys_flistxattr(int fd, char __user *list, size_t size);
   449    asmlinkage long sys_removexattr(const char __user *path,
   451    asmlinkage long sys_lremovexattr(const char __user *path,
   453    asmlinkage long sys_fremovexattr(int fd, const char __user *name);
   455    asmlinkage long sys_brk(unsigned long brk);
   456    asmlinkage long sys_mprotect(unsigned long start, size_t len,
   458    asmlinkage long sys_mremap(unsigned long addr,
   461    asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
   464    asmlinkage long sys_msync(unsigned long start, size_t len, int flags);
   465    asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice);
   466    asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice);
   467    asmlinkage long sys_munmap(unsigned long addr, size_t len);
   468    asmlinkage long sys_mlock(unsigned long start, size_t len);
   469    asmlinkage long sys_munlock(unsigned long start, size_t len);
   470    asmlinkage long sys_mlockall(int flags);
   471    asmlinkage long sys_munlockall(void);
   472    asmlinkage long sys_madvise(unsigned long start, size_t len, int behavior);
   473    asmlinkage long sys_mincore(unsigned long start, size_t len,
   476    asmlinkage long sys_pivot_root(const char __user *new_root,
   478    asmlinkage long sys_chroot(const char __user *filename);
   479    asmlinkage long sys_mknod(const char __user *filename, int mode,
   481    asmlinkage long sys_link(const char __user *oldname,
   483    asmlinkage long sys_symlink(const char __user *old, const char __user *new);
   484    asmlinkage long sys_unlink(const char __user *pathname);
   485    asmlinkage long sys_rename(const char __user *oldname,
   487    asmlinkage long sys_chmod(const char __user *filename, mode_t mode);
   488    asmlinkage long sys_fchmod(unsigned int fd, mode_t mode);
   490    asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
   492    asmlinkage long sys_fcntl64(unsigned int fd,
   495    asmlinkage long sys_pipe(int __user *fildes);
   496    asmlinkage long sys_pipe2(int __user *fildes, int flags);
   497    asmlinkage long sys_dup(unsigned int fildes);
   498    asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd);
   499    asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags);
   500    asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on);
   501    asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd,
   503    asmlinkage long sys_flock(unsigned int fd, unsigned int cmd);
   504    asmlinkage long sys_io_setup(unsigned nr_reqs, aio_context_t __user *ctx);
   505    asmlinkage long sys_io_destroy(aio_context_t ctx);
   506    asmlinkage long sys_io_getevents(aio_context_t ctx_id,
   511    asmlinkage long sys_io_submit(aio_context_t, long,
   513    asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
   515    asmlinkage long sys_sendfile(int out_fd, int in_fd,
   517    asmlinkage long sys_sendfile64(int out_fd, int in_fd,
   519    asmlinkage long sys_readlink(const char __user *path,
   521    asmlinkage long sys_creat(const char __user *pathname, int mode);
   522    asmlinkage long sys_open(const char __user *filename,
   524    asmlinkage long sys_close(unsigned int fd);
   525    asmlinkage long sys_access(const char __user *filename, int mode);
   526    asmlinkage long sys_vhangup(void);
   527    asmlinkage long sys_chown(const char __user *filename,
   529    asmlinkage long sys_lchown(const char __user *filename,
   531    asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group);
   533    asmlinkage long sys_chown16(const char __user *filename,
   535    asmlinkage long sys_lchown16(const char __user *filename,
   537    asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group);
   538    asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid);
   539    asmlinkage long sys_setgid16(old_gid_t gid);
   540    asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid);
   541    asmlinkage long sys_setuid16(old_uid_t uid);
   542    asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid);
   543    asmlinkage long sys_getresuid16(old_uid_t __user *ruid,
   545    asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid);
   546    asmlinkage long sys_getresgid16(old_gid_t __user *rgid,
   548    asmlinkage long sys_setfsuid16(old_uid_t uid);
   549    asmlinkage long sys_setfsgid16(old_gid_t gid);
   550    asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t __user *grouplist);
   551    asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist);
   552    asmlinkage long sys_getuid16(void);
   553    asmlinkage long sys_geteuid16(void);
   554    asmlinkage long sys_getgid16(void);
   555    asmlinkage long sys_getegid16(void);
   558    asmlinkage long sys_utime(char __user *filename,
   560    asmlinkage long sys_utimes(char __user *filename,
   562    asmlinkage long sys_lseek(unsigned int fd, off_t offset,
   564    asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high,
   567    asmlinkage long sys_read(unsigned int fd, char __user *buf, size_t count);
   568    asmlinkage long sys_readahead(int fd, loff_t offset, size_t count);
   569    asmlinkage long sys_readv(unsigned long fd,
   572    asmlinkage long sys_write(unsigned int fd, const char __user *buf,
   574    asmlinkage long sys_writev(unsigned long fd,
   577    asmlinkage long sys_pread64(unsigned int fd, char __user *buf,
   579    asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf,
   581    asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec,
   583    asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec,
   585    asmlinkage long sys_getcwd(char __user *buf, unsigned long size);
   586    asmlinkage long sys_mkdir(const char __user *pathname, int mode);
   587    asmlinkage long sys_chdir(const char __user *filename);
   588    asmlinkage long sys_fchdir(unsigned int fd);
   589    asmlinkage long sys_rmdir(const char __user *pathname);
   590    asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user *buf, size_t len);
   591    asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special,
   593    asmlinkage long sys_getdents(unsigned int fd,
   596    asmlinkage long sys_getdents64(unsigned int fd,
   600    asmlinkage long sys_setsockopt(int fd, int level, int optname,
   602    asmlinkage long sys_getsockopt(int fd, int level, int optname,
   604    asmlinkage long sys_bind(int, struct sockaddr __user *, int);
   605    asmlinkage long sys_connect(int, struct sockaddr __user *, int);
   606    asmlinkage long sys_accept(int, struct sockaddr __user *, int __user *);
   607    asmlinkage long sys_accept4(int, struct sockaddr __user *, int __user *, int);
   608    asmlinkage long sys_getsockname(int, struct sockaddr __user *, int __user *);
   609    asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *);
   610    asmlinkage long sys_send(int, void __user *, size_t, unsigned);
   611    asmlinkage long sys_sendto(int, void __user *, size_t, unsigned,
   613    asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
   614    asmlinkage long sys_sendmmsg(int fd, struct mmsghdr __user *msg,
   616    asmlinkage long sys_recv(int, void __user *, size_t, unsigned);
   617    asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned,
   619    asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags);
   620    asmlinkage long sys_recvmmsg(int fd, struct mmsghdr __user *msg,
   623    asmlinkage long sys_socket(int, int, int);
   624    asmlinkage long sys_socketpair(int, int, int, int __user *);
   625    asmlinkage long sys_socketcall(int call, unsigned long __user *args);
   626    asmlinkage long sys_listen(int, int);
   627    asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
   629    asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
   631    asmlinkage long sys_old_select(struct sel_arg_struct __user *arg);
   632    asmlinkage long sys_epoll_create(int size);
   633    asmlinkage long sys_epoll_create1(int flags);
   634    asmlinkage long sys_epoll_ctl(int epfd, int op, int fd,
   636    asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
   638    asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events,
   642    asmlinkage long sys_gethostname(char __user *name, int len);
   643    asmlinkage long sys_sethostname(char __user *name, int len);
   644    asmlinkage long sys_setdomainname(char __user *name, int len);
   645    asmlinkage long sys_newuname(struct new_utsname __user *name);
   646    asmlinkage long sys_uname(struct old_utsname __user *);
   647    asmlinkage long sys_olduname(struct oldold_utsname __user *);
   649    asmlinkage long sys_getrlimit(unsigned int resource,
   652    asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim);
   654    asmlinkage long sys_setrlimit(unsigned int resource,
   656    asmlinkage long sys_prlimit64(pid_t pid, unsigned int resource,
   659    asmlinkage long sys_getrusage(int who, struct rusage __user *ru);
   660    asmlinkage long sys_umask(int mask);
   662    asmlinkage long sys_msgget(key_t key, int msgflg);
   663    asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp,
   665    asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp,
   667    asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf);
   669    asmlinkage long sys_semget(key_t key, int nsems, int semflg);
   670    asmlinkage long sys_semop(int semid, struct sembuf __user *sops,
   672    asmlinkage long sys_semctl(int semid, int semnum, int cmd, union semun arg);
   673    asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops,
   676    asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg);
   677    asmlinkage long sys_shmget(key_t key, size_t size, int flag);
   678    asmlinkage long sys_shmdt(char __user *shmaddr);
   679    asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
   680    asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
   683    asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr);
   684    asmlinkage long sys_mq_unlink(const char __user *name);
   685    asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec __user *abs_timeout);
   686    asmlinkage long sys_mq_timedreceive(mqd_t mqdes, char __user *msg_ptr, size_t msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeout);
   687    asmlinkage long sys_mq_notify(mqd_t mqdes, const struct sigevent __user *notification);
   688    asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqstat, struct mq_attr __user *omqstat);
   690    asmlinkage long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn);
   691    asmlinkage long sys_pciconfig_read(unsigned long bus, unsigned long dfn,
   694    asmlinkage long sys_pciconfig_write(unsigned long bus, unsigned long dfn,
   698    asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
   700    asmlinkage long sys_swapon(const char __user *specialfile, int swap_flags);
   701    asmlinkage long sys_swapoff(const char __user *specialfile);
   702    asmlinkage long sys_sysctl(struct __sysctl_args __user *args);
   703    asmlinkage long sys_sysinfo(struct sysinfo __user *info);
   704    asmlinkage long sys_sysfs(int option,
   706    asmlinkage long sys_nfsservctl(int cmd,
   709    asmlinkage long sys_syslog(int type, char __user *buf, int len);
   710    asmlinkage long sys_uselib(const char __user *library);
   711    asmlinkage long sys_ni_syscall(void);
   712    asmlinkage long sys_ptrace(long request, long pid, unsigned long addr,
   715    asmlinkage long sys_add_key(const char __user *_type,
   721    asmlinkage long sys_request_key(const char __user *_type,
   726    asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3,
   729    asmlinkage long sys_ioprio_set(int which, int who, int ioprio);
   730    asmlinkage long sys_ioprio_get(int which, int who);
   731    asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
   733    asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
   736    asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
   741    asmlinkage long sys_mbind(unsigned long start, unsigned long len,
   746    asmlinkage long sys_get_mempolicy(int __user *policy,
   751    asmlinkage long sys_inotify_init(void);
   752    asmlinkage long sys_inotify_init1(int flags);
   753    asmlinkage long sys_inotify_add_watch(int fd, const char __user *path,
   755    asmlinkage long sys_inotify_rm_watch(int fd, __s32 wd);
   757    asmlinkage long sys_spu_run(int fd, __u32 __user *unpc,
   759    asmlinkage long sys_spu_create(const char __user *name,
   762    asmlinkage long sys_mknodat(int dfd, const char __user * filename, int mode,
   764    asmlinkage long sys_mkdirat(int dfd, const char __user * pathname, int mode);
   765    asmlinkage long sys_unlinkat(int dfd, const char __user * pathname, int flag);
   766    asmlinkage long sys_symlinkat(const char __user * oldname,
   768    asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
   770    asmlinkage long sys_renameat(int olddfd, const char __user * oldname,
   772    asmlinkage long sys_futimesat(int dfd, const char __user *filename,
   774    asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode);
   775    asmlinkage long sys_fchmodat(int dfd, const char __user * filename,
   777    asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
   779    asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
   781    asmlinkage long sys_newfstatat(int dfd, const char __user *filename,
   783    asmlinkage long sys_fstatat64(int dfd, const char __user *filename,
   785    asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *buf,
   787    asmlinkage long sys_utimensat(int dfd, const char __user *filename,
   789    asmlinkage long sys_unshare(unsigned long unshare_flags);
   791    asmlinkage long sys_splice(int fd_in, loff_t __user *off_in,
   795    asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov,
   798    asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags);
   800    asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
   802    asmlinkage long sys_sync_file_range2(int fd, unsigned int flags,
   804    asmlinkage long sys_get_robust_list(int pid,
   807    asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
   809    asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache);
   810    asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask);
   811    asmlinkage long sys_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, int flags);
   812    asmlinkage long sys_timerfd_create(int clockid, int flags);
   813    asmlinkage long sys_timerfd_settime(int ufd, int flags,
   816    asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr);
   817    asmlinkage long sys_eventfd(unsigned int count);
   818    asmlinkage long sys_eventfd2(unsigned int count, int flags);
   819    asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len);
   820    asmlinkage long sys_old_readdir(unsigned int, struct old_linux_dirent __user *, unsigned int);
   821    asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *,
   824    asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int,
   827    asmlinkage long sys_fanotify_init(unsigned int flags, unsigned int event_f_flags);
   828    asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags,
   831    asmlinkage long sys_syncfs(int fd);
   836    asmlinkage long sys_perf_event_open(
   840    asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len,
   843    asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg);
   844    asmlinkage long sys_name_to_handle_at(int dfd, const char __user *name,
   847    asmlinkage long sys_open_by_handle_at(int mountdirfd,
   850    asmlinkage long sys_setns(int fd, int nstype);
[flydream@flydream linux-3.0.4]$


到这里为止可以清除系统调用的具体实现流程了, 也知道自己怎么添加系统调用了。


其实系统调用可以绕开Glibc直接有汇编语言实现比如:


[flydream@flydream Assembler]$ cat hello1.s
#hello1.s

.section .data #这里是数据段
prompt_str: .ascii "Enter Your Name : "
pstr_end: .set STR_SIZE, pstr_end - prompt_str
greet_str: .ascii "你好:"
gstr_end: .set GSTR_SIZE, gstr_end - greet_str

.section .bss
.lcomm     buff, 32
.macro     write str, str_size
    movl $4, %eax
    movl $1, %ebx
    movl \str, %ecx
    movl \str_size, %edx
    int $0x80
.endm
.macro     read buff, buff_size
    movl $3, %eax
    movl $0, %ebx
    movl \buff, %ecx
    movl \buff_size, %edx
    int $0x80
.endm

.section .text
.global _start
_start:
    write $prompt_str, $STR_SIZE
    read $buff, $32
    pushl %eax
    write $greet_str, $GSTR_SIZE
    popl %edx
    write $buff, %edx

_exit:
    movl $1, %eax
    movl $0, %ebx
    int $0x80

[flydream@flydream Assembler]$

上面是一段汇编, 直接通过寄存器传递参数:

EAX, 系统调用号

EBX ,第一个参数

ECX ,第二个参数

EDX ,第三个参数


当参数超过5个的时候就要用栈来保存参数列表, 然后用EBX指向这个栈列表地址。

上面直接用汇编语言直接用系统调用号与用库然后进入内核有什么区别呢, 用汇编可以减少对动态链接库的支持, 速度也要快一些:


[flydream@flydream Assembler]$ as hello1.s -o hello1.o
[flydream@flydream Assembler]$ ld hello1.o -o hello1
[flydream@flydream Assembler]$ ldd hello1 //没有链接库
    not a dynamic executable
[flydream@flydream Assembler]$ ./hello1
Enter Your Name : jiang
你好:jiang
[flydream@flydream Assembler]$ 


[flydream@flydream ThinkingInC++]$ gcc -g -Wall test_system_call.c  -o test_system_call
[flydream@flydream ThinkingInC++]$ ldd test_system_call
    linux-gate.so.1 =>  (0xb77dd000)
    libc.so.6 => /lib/libc.so.6 (0x4ea1d000)
    /lib/ld-linux.so.2 (0x4e9f8000)

[flydream@flydream ThinkingInC++]$ ./test_system_call  //自己添加的系统调用成功运行
Input a num : 89
The return from kernel is 89 !

[flydream@flydream ThinkingInC++]$

 [root@flydream ThinkingInC++]# dmesg -C //清空日志消息

然后在运行

[root@flydream ThinkingInC++]# ./test_system_call
Input a num : 77
The return from kernel is 77 !
[root@flydream ThinkingInC++]#

然后看结果:

[root@flydream ThinkingInC++]# dmesg
[17361.393544] Traversal module is working..
[17361.393550] [process 1]: swapper's pid is 0
[17361.393552] [process 2]: systemd's pid is 1
[17361.393555] [process 3]: kthreadd's pid is 2
[17361.393557] [process 4]: ksoftirqd/0's pid is 3
[17361.393560] [process 5]: migration/0's pid is 6
[17361.393562] [process 6]: watchdog/0's pid is 7
[17361.393565] [process 7]: migration/1's pid is 8
[17361.393567] [process 8]: ksoftirqd/1's pid is 10
[17361.393570] [process 9]: watchdog/1's pid is 12
[17361.393572] [process 10]: migration/2's pid is 13
[17361.393574] [process 11]: kworker/2:0's pid is 14
[17361.393575] [process 12]: ksoftirqd/2's pid is 15
[17361.393577] [process 13]: watchdog/2's pid is 16
[17361.393579] [process 14]: migration/3's pid is 17
[17361.393580] [process 15]: ksoftirqd/3's pid is 19
[17361.393582] [process 16]: watchdog/3's pid is 20
[17361.393584] [process 17]: cpuset's pid is 21
[17361.393585] [process 18]: khelper's pid is 22
[17361.393587] [process 19]: netns's pid is 23
[17361.393589] [process 20]: sync_supers's pid is 24
[17361.393591] [process 21]: bdi-default's pid is 25
[17361.393592] [process 22]: kintegrityd's pid is 26
[17361.393594] [process 23]: kblockd's pid is 27
[17361.393596] [process 24]: ata_sff's pid is 28
[17361.393597] [process 25]: khubd's pid is 29
[17361.393599] [process 26]: md's pid is 30
[17361.393600] [process 27]: kswapd0's pid is 32
[17361.393602] [process 28]: ksmd's pid is 33
[17361.393604] [process 29]: khugepaged's pid is 34
[17361.393606] [process 30]: fsnotify_mark's pid is 35
[17361.393608] [process 31]: crypto's pid is 36
[17361.393609] [process 32]: kthrotld's pid is 42
[17361.393611] [process 33]: scsi_eh_0's pid is 45
[17361.393613] [process 34]: scsi_eh_1's pid is 46
[17361.393614] [process 35]: kworker/u:2's pid is 47
[17361.393616] [process 36]: scsi_eh_2's pid is 48
[17361.393618] [process 37]: scsi_eh_3's pid is 49
[17361.393619] [process 38]: kworker/u:3's pid is 50
[17361.393621] [process 39]: kpsmoused's pid is 53
[17361.393623] [process 40]: kworker/3:1's pid is 55
[17361.393625] [process 41]: ttm_swap's pid is 157
[17361.393626] [process 42]: jbd2/sda10-8's pid is 297
[17361.393628] [process 43]: ext4-dio-unwrit's pid is 298
[17361.393630] [process 44]: kauditd's pid is 328
[17361.393632] [process 45]: udevd's pid is 336
[17361.393634] [process 46]: flush-8:0's pid is 346
[17361.393636] [process 47]: systemd-stdout-'s pid is 349
[17361.393637] [process 48]: rpciod's pid is 480
[17361.393639] [process 49]: cfg80211's pid is 497
[17361.393641] [process 50]: ktpacpid's pid is 569
[17361.393642] [process 51]: ktpacpi_nvramd's pid is 572
[17361.393644] [process 52]: hd-audio0's pid is 607
[17361.393646] [process 53]: kvm-irqfd-clean's pid is 642
[17361.393648] [process 54]: jbd2/sda8-8's pid is 732
[17361.393649] [process 55]: ext4-dio-unwrit's pid is 733
[17361.393651] [process 56]: auditd's pid is 771
[17361.393653] [process 57]: audispd's pid is 777
[17361.393654] [process 58]: sedispatch's pid is 780
[17361.393656] [process 59]: abrtd's pid is 789
[17361.393658] [process 60]: NetworkManager's pid is 809
[17361.393660] [process 61]: atd's pid is 811
[17361.393661] [process 62]: acpid's pid is 820
[17361.393663] [process 63]: gpm's pid is 828
[17361.393664] [process 64]: abrt-dump-oops's pid is 829
[17361.393666] [process 65]: systemd-logind's pid is 832
[17361.393668] [process 66]: irqbalance's pid is 833
[17361.393670] [process 67]: system-setup-ke's pid is 834
[17361.393671] [process 68]: avahi-daemon's pid is 836
[17361.393673] [process 69]: avahi-daemon's pid is 838
[17361.393675] [process 70]: mcelog's pid is 840
[17361.393676] [process 71]: crond's pid is 842
[17361.393678] [process 72]: iscsi_eh's pid is 860
[17361.393680] [process 73]: ib_addr's pid is 862
[17361.393681] [process 74]: ib_mcast's pid is 863
[17361.393683] [process 75]: iw_cm_wq's pid is 864
[17361.393685] [process 76]: ib_cm's pid is 865
[17361.393686] [process 77]: rdma_cm's pid is 866
[17361.393688] [process 78]: cnic_wq's pid is 870
[17361.393690] [process 79]: dbus-daemon's pid is 871
[17361.393691] [process 80]: polkitd's pid is 881
[17361.393693] [process 81]: rsyslogd's pid is 885
[17361.393695] [process 82]: modem-manager's pid is 891
[17361.393697] [process 83]: iscsiuio's pid is 893
[17361.393698] [process 84]: iscsid's pid is 901
[17361.393700] [process 85]: iscsid's pid is 902
[17361.393702] [process 86]: sshd's pid is 912
[17361.393703] [process 87]: xinetd's pid is 913
[17361.393705] [process 88]: rpc.idmapd's pid is 918
[17361.393707] [process 89]: libvirtd's pid is 932
[17361.393708] [process 90]: rpcbind's pid is 936
[17361.393710] [process 91]: rpc.statd's pid is 1039
[17361.393712] [process 92]: gdm-binary's pid is 1059
[17361.393714] [process 93]: mysqld's pid is 1172
[17361.393715] [process 94]: /usr/sbin/httpd's pid is 1181
[17361.393717] [process 95]: dnsmasq's pid is 1226
[17361.393719] [process 96]: gdm-simple-slav's pid is 1244
[17361.393720] [process 97]: Xorg's pid is 1249
[17361.393722] [process 98]: console-kit-dae's pid is 1306
[17361.393724] [process 99]: /usr/sbin/httpd's pid is 1307
[17361.393726] [process 100]: /usr/sbin/httpd's pid is 1308
[17361.393728] [process 101]: /usr/sbin/httpd's pid is 1309
[17361.393729] [process 102]: /usr/sbin/httpd's pid is 1310
[17361.393731] [process 103]: /usr/sbin/httpd's pid is 1311
[17361.393733] [process 104]: /usr/sbin/httpd's pid is 1312
[17361.393735] [process 105]: /usr/sbin/httpd's pid is 1313
[17361.393736] [process 106]: accounts-daemon's pid is 1314
[17361.393738] [process 107]: /usr/sbin/httpd's pid is 1315
[17361.393740] [process 108]: upowerd's pid is 1398
[17361.393742] [process 109]: rtkit-daemon's pid is 1452
[17361.393743] [process 110]: gdm-session-wor's pid is 1485
[17361.393745] [process 111]: gnome-keyring-d's pid is 1492
[17361.393747] [process 112]: gnome-session's pid is 1498
[17361.393749] [process 113]: dbus-launch's pid is 1508
[17361.393751] [process 114]: dbus-daemon's pid is 1509
[17361.393752] [process 115]: imsettings-daem's pid is 1520
[17361.393754] [process 116]: gvfsd's pid is 1523
[17361.393756] [process 117]: gvfs-fuse-daemo's pid is 1535
[17361.393758] [process 118]: gconfd-2's pid is 1633
[17361.393759] [process 119]: gnome-settings-'s pid is 1644
[17361.393761] [process 120]: pulseaudio's pid is 1650
[17361.393763] [process 121]: gconf-helper's pid is 1653
[17361.393765] [process 122]: cupsd's pid is 1658
[17361.393766] [process 123]: gsd-printer's pid is 1660
[17361.393768] [process 124]: gvfs-gdu-volume's pid is 1668
[17361.393770] [process 125]: udisks-daemon's pid is 1670
[17361.393772] [process 126]: udisks-daemon's pid is 1671
[17361.393774] [process 127]: gvfs-afc-volume's pid is 1677
[17361.393775] [process 128]: gvfs-gphoto2-vo's pid is 1680
[17361.393777] [process 129]: colord's pid is 1682
[17361.393779] [process 130]: gnome-shell's pid is 1685
[17361.393781] [process 131]: dconf-service's pid is 1691
[17361.393782] [process 132]: nautilus's pid is 1695
[17361.393784] [process 133]: deja-dup-monito's pid is 1698
[17361.393786] [process 134]: evolution-alarm's pid is 1699
[17361.393788] [process 135]: abrt-applet's pid is 1702
[17361.393789] [process 136]: tracker-miner-f's pid is 1703
[17361.393791] [process 137]: tracker-store's pid is 1708
[17361.393793] [process 138]: gnome-screensav's pid is 1714
[17361.393795] [process 139]: nm-applet's pid is 1727
[17361.393796] [process 140]: gdu-notificatio's pid is 1730
[17361.393798] [process 141]: cairo-dock's pid is 1738
[17361.393800] [process 142]: zeitgeist-datah's pid is 1757
[17361.393802] [process 143]: zeitgeist-daemo's pid is 1818
[17361.393803] [process 144]: udevd's pid is 1913
[17361.393805] [process 145]: udevd's pid is 1914
[17361.393807] [process 146]: e-calendar-fact's pid is 1918
[17361.393808] [process 147]: e-addressbook-f's pid is 1991
[17361.393810] [process 148]: goa-daemon's pid is 2003
[17361.393812] [process 149]: ibus-daemon's pid is 2129
[17361.393814] [process 150]: gvfsd-trash's pid is 2134
[17361.393815] [process 151]: gvfsd-computer's pid is 2142
[17361.393817] [process 152]: gnome-shell-cal's pid is 2147
[17361.393819] [process 153]: mission-control's pid is 2152
[17361.393821] [process 154]: gvfsd-network's pid is 2158
[17361.393823] [process 155]: gvfsd-dnssd's pid is 2174
[17361.393824] [process 156]: gpasted's pid is 2194
[17361.393826] [process 157]: libsocialweb-co's pid is 2202
[17361.393828] [process 158]: gvfsd-burn's pid is 2209
[17361.393829] [process 159]: gvfsd-metadata's pid is 2218
[17361.393831] [process 160]: ibus-dconf's pid is 2227
[17361.393833] [process 161]: python's pid is 2229
[17361.393835] [process 162]: ibus-x11's pid is 2231
[17361.393836] [process 163]: ibus-engine-pin's pid is 2235
[17361.393838] [process 164]: ibus-engine-xkb's pid is 2236
[17361.393840] [process 165]: dhclient's pid is 2253
[17361.393841] [process 166]: sendmail's pid is 2317
[17361.393843] [process 167]: sendmail's pid is 2385
[17361.393845] [process 168]: firefox's pid is 2724
[17361.393846] [process 169]: plugin-containe's pid is 3065
[17361.393848] [process 170]: gnome-terminal's pid is 3334
[17361.393849] [process 171]: gnome-pty-helpe's pid is 3341
[17361.393851] [process 172]: bash's pid is 3342
[17361.393853] [process 173]: kworker/1:2's pid is 10234
[17361.393855] [process 174]: bash's pid is 21235
[17361.393856] [process 175]: kworker/0:1's pid is 22101
[17361.393858] [process 176]: kworker/2:1's pid is 22432
[17361.393860] [process 177]: kworker/1:1's pid is 22552
[17361.393861] [process 178]: kworker/0:2's pid is 22947
[17361.393863] [process 179]: kworker/3:2's pid is 23134
[17361.393865] [process 180]: kworker/1:0's pid is 23168
[17361.393867] [process 181]: su's pid is 23549
[17361.393868] [process 182]: bash's pid is 23553
[17361.393870] [process 183]: kworker/0:0's pid is 23650
[17361.393872] The number of process is 183
[17361.393874] This is a sample test output from kernel!
[17361.393875] And this is added by JYP !
[root@flydream ThinkingInC++]#

还有一种不需要动态链接库的就是静态编译, 对比静态编译和动态编译

[root@flydream ThinkingInC++]# gcc -g -Wall -static -m32 test_system_call.c -o test_system_call
[root@flydream ThinkingInC++]# ldd test_system_call
    not a dynamic executable
[root@flydream ThinkingInC++]# du -sh test_system_call
736K    test_system_call
[root@flydream ThinkingInC++]# ./test_system_call
Input a num : 89
The return from kernel is 89 !
[root@flydream ThinkingInC++]# gcc -g -Wall test_system_call.c -o test_system_call
[root@flydream ThinkingInC++]# ldd test_system_call
    linux-gate.so.1 =>  (0xb7893000)
    libc.so.6 => /lib/libc.so.6 (0x4ea1d000)
    /lib/ld-linux.so.2 (0x4e9f8000)
[root@flydream ThinkingInC++]# ./test_system_call
Input a num : 78
The return from kernel is 78 !
[root@flydream ThinkingInC++]# du -sh test_system_call
8.0K    test_system_call

好了总算写完了。。。。。。。。。。。。。。。。。。。。。。。。。。。




搞忘了总结了:

其实系统调用执行的流程如下:

用户代码==》系统调用==》进入库函数(/lib/libc.so)==>软中断进入内核==》执行已经有内核初始化注册号了的system_call函数===》执行相关系统调用函数==>一层一层返回。










  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值