Android 系统调用

http://www.eoeandroid.com/thread-4668-1-1.html

http://blog.chinaunix.net/uid-9078996-id-2010323.html

http://blog.csdn.net/andyhuabing/article/details/7183369

1、Syscall stub:

每个系统调用函数都由一个小的汇编代码段实现(称为”syscall stub”),这是由tools/gensyscalls.py工具自动生成的,它从SYSCALL.TXT中取得输入参数。
SYSCALLS.TXT包含了一份要生成的系统调用块列表,和相应的系统调用数字标识符(ARM和X86不一样),以及它的签署。
如果你要修改这个文件,你可能要使用tools/checksyscalls.py工具,检查它里面是否包含官方linux核心头文件,如果有不合法的syscall ids,它会报告错误。
有时,C库函数其实就是一个包装,它内部调用相应的syscall名称,例如,exit函数由C库提供,它调用了_exit()这个syscall stub.
详细内容请参考SYSCALLS.TXT文件。

2、比如要增加消息队列的函数:
(1). 修改 SYSCALL.TXT
增加:
long ipc(unsigned int call, int first, unsigned long second, unsigned long third, void __user *ptr, long fifth) 117
(2). 执行 tools/gensyscalls.py
(3). 以下内容会由 tools/gensyscalls.py 自动产生:

bionic/libc/arch-mips/syscalls.mk
----------------------------------------------------------------------------------------------------------------------------
syscall_src += arch-mips/syscalls/ipc.S
----------------------------------------------------------------------------------------------------------------------------

bionic/libc/include/sys/linux-syscalls.h
----------------------------------------------------------------------------------------------------------------------------
#define _NR_ipc (_NR_SYSCALL_BASE + 117)
----------------------------------------------------------------------------------------------------------------------------

bionic/libc/include/sys/linux-unistd.h
----------------------------------------------------------------------------------------------------------------------------
int ipc (unsigned int call, int first, int second, int third, void* ptr, long fifth);
----------------------------------------------------------------------------------------------------------------------------

(4). 手动编写
bionic/libc/Android.mk
----------------------------------------------------------------------------------------------------------------------------
ifeq ($(TARGET_ARCH),mips)
libc_common_src_files += \
arch-mips/bionic/sys_ipc.c \

----------------------------------------------------------------------------------------------------------------------------
bionic/libc/arch-mips/bionic/sys_ipc.c
----------------------------------------------------------------------------------------------------------------------------
#include <stdarg.h>
#include <sys/msg.h>

extern int ipc (unsigned int call, int first, int second, int third, void* ptr, long fifth);
int semget (key_t  key, int  nsems, int  semflg)
{
    return ipc(SEMGET, key, nsems, semflg, (void*)NULL, (long)NULL);
}
int semop (int  semid, struct sembuf*  sops, size_t  nsops)
{
    return ipc(SEMOP, semid, (int)nsops, 0, sops, (long)NULL);
}
void* shmat (int  shmid, const void*  shmaddr, int  shmflg)
{
    int rval;
    unsigned long raddr;


    rval = ipc(SHMAT, shmid, shmflg, (int)&raddr, (void*)shmaddr, (long)NULL);
    if (rval < 0)
        return (char *)rval;


    return (char *)raddr;
}

int shmctl (int  shmid, int  cmd, struct shmid_ds*  buf)
{
    return ipc(SHMCTL, shmid, cmd, 0, buf, (long)NULL);
}
int shmget (key_t  key, size_t  size, int  shmflg)
{
    return ipc(SHMGET, key, size, shmflg, (void*)NULL, (long)NULL);
}

int msgctl (int  msqid, int  cmd, struct msqid_ds *buf)
{
    return ipc(MSGCTL, msqid, cmd, 0, buf, (long)NULL);
}

int shmdt (const void*  shmaddr)
{
    return ipc(SHMDT, 0, 0, 0, (void*)shmaddr, (long)NULL);
}

int msgget (key_t  key, int  msgflg)
{
    return ipc(MSGGET, key, msgflg, 0, NULL, (long)NULL);
}
ssize_t msgrcv (int msqid, void *msgp, size_t msgsz, long int msgtyp, int msgflg)
{
    struct ipc_kludge tmp;


    tmp.msgp = msgp;
    tmp.msgtyp = msgtyp;

    return ipc(MSGRCV, msqid, msgsz, msgflg, &tmp, (long)NULL);
}
int msgsnd (int  msqid, const void* msgp, size_t  msgsz, int  msgflg)
{
    return ipc(MSGSND, msqid, msgsz, msgflg, (void*)msgp, (long)NULL);
}



bionic/libc/arch-mips/syscalls/ipc.S
----------------------------------------------------------------------------------------------------------------------------
/* autogenerated by gensyscalls.py */
#include <sys/linux-syscalls.h>
    .text
    .globl ipc
    .align 4
    .ent ipc

ipc:
    .set noreorder
    .cpload $t9
    li $v0, __NR_ipc
    syscall
    bnez $a3, 1f
     move $a0, $v0
    j $ra
     nop
1:
    la $t9,__set_errno
    j $t9
     nop
    .set reorder
    .end ipc

----------------------------------------------------------------------------------------------------------------------------
bionic/libc/include/sys/msg.h
----------------------------------------------------------------------------------------------------------------------------

#ifndef _SYS_MSG_H
#define _SYS_MSG_H

#include <features.h>

#define __need_size_t
#include <stddef.h>

/* Get common definition of System V style IPC.  */
#include <sys/ipc.h>

/* Get system dependent definition of `struct msqid_ds' and more.  */
#include <msq.h>

/* Define types required by the standard.  */
#define    __need_time_t
#include <time.h>

#ifndef __pid_t_defined
typedef __pid_t pid_t;
# define __pid_t_defined
#endif

#ifndef __ssize_t_defined
typedef __ssize_t ssize_t;
# define __ssize_t_defined
#endif

#define SEMOP         1
#define SEMGET         2
#define SEMCTL         3
#define SEMTIMEDOP     4
#define MSGSND        11
#define MSGRCV        12
#define MSGGET        13
#define MSGCTL        14
#define SHMAT        21
#define SHMDT        22
#define SHMGET        23
#define SHMCTL        24
/* The following System V style IPC functions implement a message queue
   system.  The definition is found in XPG2.  */

#ifdef __USE_GNU
/* Template for struct to be used as argument for `msgsnd' and `msgrcv'.  */
struct msgbuf
  {
    long int mtype;        /* type of received/sent message */
    char mtext[1];        /* text of the message */
  };
#endif

struct ipc_kludge {
    struct msgbuf __user *msgp;
    long msgtyp;
};

__BEGIN_DECLS

/* Message queue control operation.  */
extern int msgctl (int __msqid, int __cmd, struct msqid_ds *__buf) ;

/* Get messages queue.  */
extern int msgget (key_t __key, int __msgflg) ;

/* Receive message from message queue.


   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern ssize_t msgrcv (int __msqid, void *__msgp, size_t __msgsz, long int __msgtyp, int __msgflg);

/* Send message to message queue.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int msgsnd (int __msqid, __const void *__msgp, size_t __msgsz,   int __msgflg);

__END_DECLS

#endif /* sys/msg.h */


----------------------------------------------------------------------------------------------------------------------------
Create bionic/libc/include/msq.h

#ifndef _SYS_MSG_H
#error "Never use <msq.h> directly; include <sys/msg.h> instead." 
#endif

#include <sys/types.h>

/* Define options for message queue functions.  */
#define MSG_NOERROR     010000  /* no error if message is too big */

/* Types used in the structure definition.  */
typedef unsigned short int msgqnum_t;
typedef unsigned short int msglen_t;

/* Structure of record for one message inside the kernel.
   The type `struct __msg' is opaque.  */
struct msqid_ds
{
  struct ipc_perm msg_perm;     /* structure describing operation permission */
  __time_t msg_stime;           /* time of last msgsnd command */
  __time_t msg_rtime;           /* time of last msgrcv command */
  __time_t msg_ctime;           /* time of last change */
  msgqnum_t msg_qnum;           /* number of messages currently on queue */
  msglen_t msg_qbytes;          /* max number of bytes allowed on queue */
  __pid_t msg_lspid;            /* pid of last msgsnd() */
  __pid_t msg_lrpid;            /* pid of last msgrcv() */
};


你可能感兴趣的:(android,实现,系统调用)