Arm Linux 2.6.24 添加系统调用


# gedit  arch/arm/kernel/sys_arm.c
-----------------------------------------------------------
asmlinkage long sys_arm_fadvise64_64(int fd, int advice,
                     loff_t offset, loff_t len)
{
    return sys_fadvise64_64(fd, offset, len, advice);
}

asmlinkage int sys_kmd(unsigned int p_addr)
{
    printk("p_addr = 0x%x\n", p_addr);
    return p_addr;
}


# gedit  include/asm-arm/unistd.h
-----------------------------------------------------------
#define __NR_fallocate            (__NR_SYSCALL_BASE+352)
#define __NR_kmd                 (__NR_SYSCALL_BASE+353)

 

# gedit arch/arm/kernel/calls.S
-----------------------------------------------------------
        CALL(sys_fallocate)
        CALL(sys_kmd)


测试提供调用
-----------------------------------------------------------
#define _GNU_SOURCE        /* or _BSD_SOURCE or _SVID_SOURCE */
#include <unistd.h>
#include <sys/syscall.h>   /* For SYS_xxx definitions */

#define __NR_kmd                 (__NR_SYSCALL_BASE+353)

int kmd (unsigned int p_addr)
{
    syscall (__NR_kmd, p_addr);
    return 0;
}

int main ()
{
    kmd (0x100000);
}

 

# arm-linux-gcc kmd.c -static
# cp a.out /tftpboot/
# tftp -g -r a.out 192.168.1.160
# ./a.out
p_addr = 0x100000

#if 1
#define DISP_LINE_LEN              (16)
#define MAX_LINE_LENGTH_BYTES     (64)
#define DEFAULT_LINE_LENGTH_BYTES (16)

#define int8_t      char
#define int16_t     short
#define int32_t     long
#define int64_t     long long
#define uint8_t     u_char
#define uint16_t    u_short
#define uint32_t    u_long
#define uint64_t    unsigned long long
#define t_scalar_t  int
#define t_uscalar_t unsigned int
#define uintptr_t   unsigned long

/*
 * Print data buffer in hex and ascii form to the terminal.
 *
 * data reads are buffered so that each memory address is only read once.
 * Useful when displaying the contents of volatile registers.
 *
 * parameters:
 *    addr: Starting address to display at start of line
 *    data: pointer to data buffer
 *    width: data value width.  May be 1, 2, or 4.
 *    count: number of values to display
 *    linelen: Number of values to print per line; specify 0 for default length
 */
int print_buffer (ulong addr, void *data, uint width, uint count, uint linelen)
{
    uint8_t linebuf[MAX_LINE_LENGTH_BYTES];
    uint32_t *uip = (void *) linebuf;
    uint16_t *usp = (void *) linebuf;
    uint8_t  *ucp = (void *) linebuf;
    int i;
    if (linelen * width > MAX_LINE_LENGTH_BYTES)
        linelen = MAX_LINE_LENGTH_BYTES / width;
    if (linelen < 1)
        linelen = DEFAULT_LINE_LENGTH_BYTES / width;
    while (count)
    {
        printk ("%08lx:", addr);

        /* check for overflow condition */
        if (count < linelen)
            linelen = count;

        /* Copy from memory into linebuf and print hex values */
        for (i = 0; i < linelen; i++)
        {
            if (width == 4)
            {
                uip[i] = *(volatile uint32_t *) data;
                printk (" %08x", (unsigned int)uip[i]);
            }
            else if (width == 2)
            {
                usp[i] = *(volatile uint16_t *) data;
                printk (" %04x", usp[i]);
            }
            else
            {
                ucp[i] = *(volatile uint8_t *) data;
                printk (" %02x", ucp[i]);
            } data += width;
        }

#if 0
        /* Print data in ASCII characters */
        printk ("    ");
        for (i = 0; i < linelen * width; i++)
            fputc (isprint (ucp[i]) && (ucp[i] < 0x80) ? ucp[i] : '.', stdout);

        fputc ('\n', stdout);
#endif
        printk("\n");
        /* update references */
        addr += linelen * width;
        count -= linelen;
    }
    return 0;
}

asmlinkage int sys_kmd(unsigned int v_addr)
{
    ulong length = 64, p_addr = 0, size = 4;
    if (0 == v_addr)
    {
        printk("v_addr = %x\n", (unsigned int)v_addr);
        return -1;
    }
    p_addr = virt_to_phys((void *)v_addr);
    printk("v_addr   <--> p_addr\n");
    printk("%08x <--> %08x\n", (unsigned int)v_addr,
                    (unsigned int)p_addr);
    print_buffer (v_addr, (void *) v_addr, size, length,
                        DISP_LINE_LEN / size);

    return 0;
}
#endif

相关内容