I looked through book about writing kernel modules in Linux (actually it's in russian lang). It's oriented on x86 architecture. I fount some not so real but interesting sample with syscall from inline assmebler code and port it to arm architecture. I used codesourcery toolchain.
Some information about arm syscalls in linux. According ARM EABI one use r7 register for syscall number and swi 0 (or svc 0, codesourcery gcc generate the same code) for syscall. One can use also r0-r5 registers for 32 bit parameters (or r0...r6 for 64 bit parameters, but them must be aligned to even number of registers)
+++++++++++++++++[syscall.c]++++++++++++++++++++++++++
.....
static int write_call(char* buf, int n )
{
volatile int block[2];
block[0] = (int)buf;
block[1] = n;
__asm__ volatile (
"mov r0, #1\n\t" /* stdout */
"ldr r1, [%0]\n\t" /* buf */
"ldr r2, [%0, #4]\n\t" /* n */
"mov r7, #4\n\t" /* __NR_write */
"svc 0x0\n" /* write() */
"str r0, [%0]\n\t"
:
: "r" (block)
: "r0","r1","r2","r7"
);
if (block[0] < 0)
block[0] = -1;
return block[0];
}
void do_write( void ) {
char *str = "write syscall string!\n";
int len = strlen( str ) + 1, n;
printf( "string for write length = %d\n", len );
n = write_call(str, len);
printf( "write return :%d\n", n );
}
.......
+++++++++++++++++++++++++++++++++++++++++++
++++++++++++++[ Makefile ]+++++++++++++++++++++
CC=arm-none-linux-gnueabi-gcc
syscall: syscall.c
$(CC) $^ -o syscall
clean:
rm -f syscall core
+++++++++++++++++++++++++++++++++++++++++++
Some information about ARM toolchain from codesourcery from IBM. Also I used valgrind source. For further information about ARM inline assembler one can use this source.
Some information about arm syscalls in linux. According ARM EABI one use r7 register for syscall number and swi 0 (or svc 0, codesourcery gcc generate the same code) for syscall. One can use also r0-r5 registers for 32 bit parameters (or r0...r6 for 64 bit parameters, but them must be aligned to even number of registers)
+++++++++++++++++[syscall.c]++++++++++++++++++++++++++
static int write_call(char* buf, int n )
{
volatile int block[2];
block[0] = (int)buf;
block[1] = n;
__asm__ volatile (
"mov r0, #1\n\t" /* stdout */
"ldr r1, [%0]\n\t" /* buf */
"ldr r2, [%0, #4]\n\t" /* n */
"mov r7, #4\n\t" /* __NR_write */
"svc 0x0\n" /* write() */
"str r0, [%0]\n\t"
:
: "r" (block)
: "r0","r1","r2","r7"
);
if (block[0] < 0)
block[0] = -1;
return block[0];
}
void do_write( void ) {
char *str = "write syscall string!\n";
int len = strlen( str ) + 1, n;
printf( "string for write length = %d\n", len );
n = write_call(str, len);
printf( "write return :%d\n", n );
}
.......
+++++++++++++++++++++++++++++++++++++++++++
++++++++++++++[ Makefile ]+++++++++++++++++++++
CC=arm-none-linux-gnueabi-gcc
syscall: syscall.c
$(CC) $^ -o syscall
clean:
rm -f syscall core
+++++++++++++++++++++++++++++++++++++++++++
Some information about ARM toolchain from codesourcery from IBM. Also I used valgrind source. For further information about ARM inline assembler one can use this source.
No comments:
Post a Comment