这篇文章原来放在CU上的,现在挪过来了。CU上设置不可见了。

1.  目标

这里主要是实验一下uclinux的系统调用。

2.   环境

OS                :vmware + redhat 9

编译器          :arm-elf-gcc 2.95

ARM7模拟器:skyeye

3.   源文件

1个汇编(init.s),3个C文件(main.c, print.c, syscall.c),1个C头文件(unistd.h),1个Makefile,1个链接文件(syscall.lds),1个skyeye的配置文件(skyeye.conf),共8个文件

init.s

.equ INTCON,   0x01e00000
.equ INTMSK, 0x01e0000c
.equ LOCKTIME, 0x01d8000c
.equ PLLCON, 0x01d80000
.equ CLKCON, 0x01d80004
.equ WTCON, 0x01d30000
.equ I_ISPR, 0x01e00020
.equ I_ISPC, 0x01e00024
.equ TCFG0, 0x01d50000
.equ TCFG1, 0x01d50004
.equ TCON, 0x01d50008
.equ TCNTB5, 0X01d50048
.equ UTXH0, 0x01d00020
.equ UFCON0, 0x01d00008
.equ ULCON0, 0x01d00000
.equ UCON0, 0x01d00004
.equ UBRDIV0, 0x01d00028 .globl _start
_start:
b reset
b .
b HandlerSWI
b .
b .
b .
b .
b . reset:
mov r0,#0x80 | 0x40 | 0x13 @ svc, disable irq,fiq
msr cpsr_c,r0 ldr sp, =0x0c700000 ldr r0,=WTCON @ disable watch dog
ldr r1, =0x0
str r1, [r0] ldr r0, =INTCON @ non-vector mode, disable irq, disable fiq
ldr r1, =0x7
str r1, [r0] ldr r0, =LOCKTIME
ldrb r1, =800
strb r1, [r0] ldr r0, =PLLCON
ldr r1, =0x34031
str r1,[r0] ldr r0, =CLKCON
ldr r1, =0x7ff8
str r1, [r0] @ UART 0
ldr r0,=UFCON0
mov r1,#0x0
str r1,[r0] ldr r0,=ULCON0
mov r1,#0x03
str r1,[r0] ldr r0,=UCON0
mov r1,#0x05
str r1,[r0] ldr r0,=UBRDIV0
mov r1,#32
str r1,[r0] ldr r0,=UTXH0 @ print 'C'
mov r1,#'S'
str r1,[r0] @ sp_svc
ldr sp,=0x0c700000 ldr r0, =INTMSK
ldr r1, =0x03ffffff @ disable all irq.
str r1, [r0] @ move to user mode mov r0, #0x80 | 0x40 | 0x10 @ svc, disable irq,fiq
msr cpsr_c,r0 ldr sp, =0x0c600000 mov r0,#'\n'
ldr r1,=UTXH0 @ print 'A'
str r0,[r1] b Main HandlerSWI:
stmfd sp!,{r0-r12,lr} stmfd sp!,{r0-r2} @ in this example, we use only three paramters at most ldr r0,[lr,#-4] @ lr is "swi #x" address, get swi instruction code
bic r0,r0,#0xff000000 @ get #x ldmfd sp!, {r1-r3} bl swi_c_handler @ c function use r0,r1 as parameter, and return result with r0 @ ldr r1,=UTXH0 @ print 'B'
@ str r0,[r1] str r0,[sp] @ change r0 to true result ldmfd sp!, {r0-r12,pc}^ @ ^,不能在用户模式使用 作用: 1.如果寄存器列表有pc, 还要把spsr复制到cpsr, 2.如果没有pc, 那么这些寄存器指的是用户寄存器,而不是当前模式的寄存器

main.c

#include "unistd.h"

static inline __syscall0(void,hello);
static inline __syscall2(int,add,int,a,int,b);
static inline __syscall2(int,sub,int,a,int,b);
static inline __syscall2(int,sum,int *,p,int,count);
static inline __syscall3(int,sub3,int,a,int,b,int,c); int swi_c_handler(int sys_call_num,int param1,int param2,int param3){
int result=; switch(sys_call_num){ case __NR_hello:
sys_hello();
break; case __NR_add:
result = sys_add(param1,param2);
break; case __NR_sub:
result = sys_sub(param1,param2);
break; case __NR_sub3:
result = sys_sub3(param1,param2,param3);
break; case __NR_sum:
result = sys_sum((int *)param1,param2);
break; default:
print("no such call number: %d\n",sys_call_num);
result = -;
} return result;
} void Main(){
char *s="hello,world";
int num[]={,,,,}; // print("%s\n",s); hello();
print("5+8=%d\n",add(,));
print("28-13=%d\n",sub(,));
print("39-13-2=%d\n",sub3(,,));
print("4+7+10+3+8=%d\n",sum(num,)); while();
}

print.c

#include

void print_char(char c){
__asm__ __volatile__ (
"mov r0,%0 \n\t"
"ldr r1,=0x01d00020 \n\t"
"str r0,[r1] \n\t"
:
:"r"((long)(c))
:"r0","r1");
} int itoa(char * buf,int num){
int i=,a=num,b; while(){
b = a % ;
a = a / ;
buf[i++]=b+'';
if(a==) break;
} return i;
} void print(char * fmt, ...){
char out_buf[],itoa_buf[],*s;
int n,i,index=,itoa_len; va_list args;
va_start(args,fmt); for(;*fmt;++fmt){
if(*fmt!='%'){
out_buf[index++]=*fmt;
continue;
}
fmt++;
switch(*fmt){
case 'd':
n = (int)va_arg(args,int);
itoa_len = itoa(itoa_buf,n);
for(i=itoa_len-;i>=;i--){
out_buf[index++]=itoa_buf[i];
}
break;
case 's':
s = (char *)va_arg(args,char *);
for(;*s;s++){
out_buf[index++]=*s;
}
break;
default:
out_buf[index++]=' ';
}
} out_buf[index]=; // NULL for(s=out_buf;*s;s++){
print_char(*s);
} va_end(args);
}

syscall.c

void sys_hello(){
print("hello, S3C44B0X!\n");
} int sys_add(int a,int b){
return a+b;
} int sys_sub(int a,int b){
return a-b;
} int sys_sub3(int a,int b,int c){
return a-b-c;
} int sys_sum(int * pnum, int count){
int sum=,i;
for(i=;i sum+=pnum[i];
}
return sum;
}

unistd.h

#ifndef __UNISTD_H_
#define __UNISTD_H_ #define __NR_SYSCALL_BASE 0X900000 #define __NR_hello (__NR_SYSCALL_BASE + 1)
#define __NR_add (__NR_SYSCALL_BASE + 2)
#define __NR_sub (__NR_SYSCALL_BASE + 3)
#define __NR_sub3 (__NR_SYSCALL_BASE + 4)
#define __NR_sum (__NR_SYSCALL_BASE + 5) #define __sys1(x) #x
#define __sys2(x) __sys1(x) #define __syscall(name) "swi " __sys2(__NR_##name) "\n\t" #define __syscall0(type,name) \
type name(){ \
long __res; \
__asm__ __volatile__ ( \
__syscall(name) \
"mov %0, r0 \n\t" \
:"=r"(__res) \
: \
:"r0","lr"); \
return (type)(__res); \
} #define __syscall1(type,name,type1,arg1){ \
type name(type1 arg1){ \
long __res; \
__asm__ __volatile ( \
"mov r0,%1 \n\t" \
__syscall(name) \
"mov %0,r0 \n\t" \
:"=r"((long)__res) \
:"r"((long)(arg1)) \
:"r0","lr"); \
} #define __syscall2(type,name,type1,arg1,type2,arg2) \
type name(type1 arg1,type2 arg2){ \
long __res; \
__asm__ __volatile ( \
"mov r0,%1 \n\t" \
"mov r1,%2 \n\t" \
__syscall(name) \
"mov %0,r0 \n\t" \
:"=r"((long)__res) \
:"r"((long)(arg1)),"r"((long)(arg2)) \
:"r0","r1","lr"); \
} #define __syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
type name(type1 arg1,type2 arg2,type3 arg3){ \
long __res; \
__asm__ __volatile ( \
"mov r0,%1 \n\t" \
"mov r1,%2 \n\t" \
"mov r2,%3 \n\t" \
__syscall(name) \
"mov %0,r0 \n\t" \
:"=r"((long)__res) \
:"r"((long)(arg1)),"r"((long)(arg2)),"r"((long)(arg3)) \
:"r0","r1","r2","lr"); \
} #endif

syscall.lds

OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000; .text :
{
init.o (.text)
main.o (.text)
print.o (.text)
syscall.o (.text)
} . = ALIGN(); .data :
{
*(.data)
} . = ALIGN(); .bss :
{
*(.bss)
*(.rodata)
} }

Makefile

all: syscall

syscall: init.o main.o print.o syscall.o
arm-elf-ld -T syscall.lds -o syscall init.o main.o print.o syscall.o
arm-elf-objcopy -O binary syscall syscall.bin init.o: init.s
arm-elf-as --gstabs -o init.o init.s main.o: main.c unistd.h
arm-elf-gcc -gstabs -c main.c print.o: print.c
arm-elf-gcc -gstabs -c print.c syscall.o: syscall.c
arm-elf-gcc -gstabs -c syscall.c .PHONY: clean
clean:
rm -f *.o syscall syscall.bin

skyeye.conf

#skyeye config file for S3C44B0X
cpu: arm7tdmi
mach: s3c44b0x # physical memory
mem_bank: map=M, type=RW, addr=0x00000000, size=0x00200000, file=syscall.bin
mem_bank: map=M, type=RW, addr=0x0c000000, size=0x00800000 # peripherals I/O mapping area
mem_bank: map=I, type=RW, addr=0x01c00000, size=0x00400000 # uart
uart: mod=stdio

4. 运行

# skyeye -e syscall

模拟uClinux系统调用的更多相关文章

  1. GCC编译器原理(一)------交叉编译器制作和GCC组件及命令

    1.1 交叉编译器制作 默认安装的 GCC 编译系统所产生的代码适用于本机,即运行 GCC 的机器,但也可将 GCC 安装成能够生成其他的机器代码.安装一些必须的模块,就可产生多种目标机器代码,而且可 ...

  2. Rootkit Hacking Technology && Defence Strategy Research

    目录 . The Purpose Of Rootkit . Syscall Hijack . LKM Module Hidden . Network Communication Hidden . Fi ...

  3. SAP S4CRM 1811 服务订单API介绍

    Jerry在今年2月28日,SAP Customer Management for S/4HANA 1.0正式问世这个具有纪念意义的日子,同时发布了中英文版的博客进行介绍. 英文版发在SAP社区上,至 ...

  4. 获取fork+exec启动的程序的PID值

    问题背景     业务中有个场景需要自动起一个A程序(由于A程序与 sublime_text 启动后遇到的问题有相似之处,后文就用 sublime_text 来替代A程序,当A程序与 sublime_ ...

  5. Linux系列(41) - 监听命令Vmstart,Top(还需完善)

    一.简介 vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存.进程.CPU活动进行监控:属于sysstat包:它是对系统的整体情况进行统计 ...

  6. [Linux]Linux系统调用列表

    本文列出了大部分常见的Linux系统调用,并附有简要中文说明. 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的 ...

  7. VB模拟键盘输入的N种方法

    VB模拟键盘输入的N种方法http://bbs.csdn.net/topics/90509805hd378发表于: 2006-12-24 14:35:39用VB模拟键盘事件的N种方法 键盘是我们使用计 ...

  8. 模拟XShell的小项目

    不知道大家有没有用过XShell这款工具,这款工具通过windows可以远程操作处于开机状态的linux操作系统,也就是说把你的电脑和一台服务器连入网络,你通过输入服务器所在的IP地址建立一个会话就可 ...

  9. 别出心裁的Linux系统调用学习法

    别出心裁的Linux系统调用学习法 操作系统与系统调用 操作系统(Operating System,简称OS)是计算机中最重要的系统软件,是这样的一组系统程序的集成:这些系统程序在用户对计算机的使用中 ...

随机推荐

  1. 【Android Studio快捷键】之导入对应包声明(import packages)

    可能import 单个声明的快捷键大家都非常easy找到.Alt+Enter.可是假设我要一次性import文件里全部的声明.这个快捷键是什么呢,找啊找的,就是没找到,曾经在Eclipse是Ctrl+ ...

  2. 兔子-ps抠图

    介绍2种方法:1.用高速选择工具 2.用铅笔工具 1.高速选择后.ctrl+c复制,新建空白图片,粘贴进去 2.用钢笔工具在图像的边缘定出若二个点,确定完毕之后按crtl+回车键选择.然后复制,新建空 ...

  3. MVC Anti-XSS方案

    1:Form提交模式 在使用Form提交时,MVC框架提供了一个默认的机制.如果数据中含有恶意字,则会自动转向出错页面.   2:Ajax+JSON提交模式. MVC框架未提供对于Json数据的Ant ...

  4. activeMq 使用方法

    一:activeMq介绍 ActiveMQ是一种开源的,实现了JMS1.1规范的,面向消息(MOM)的中间件,为应用程序提供高效的.可扩展的.稳定的和安全的企业级消息通信,下载地址是:http://a ...

  5. 分布式:2PC,3PC,Paxos,Raft,ISR [转]

    本文主要讲述2PC及3PC,以及Paxos以及Raft协议. 两类一致性(操作原子性与副本一致性) 2PC协议用于保证属于多个数据分片上的操作的原子性.这些数据分片可能分布在不同的服务器上,2PC协议 ...

  6. WebGL学习(3) - 3D模型

      原文地址:WebGL学习(3) - 3D模型   相信很多人是以创建逼真酷炫的三维效果为目标而学习webGL的吧,首先我就是

  7. LBSN中的用户行为模式分析

    LBSN中的用户行为模式分析 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouw  2015-12-23   声明: 1)该LBSN的 ...

  8. python爬虫入门学习

    近期写的一个爬虫的Demo,只是简单的用了几个函数.实现了简单的爬取网页的功能(以途牛为例). import urllib2 import re import urlparse import robo ...

  9. java前后端分离是否会成为趋势

    现在项目当中使用的是springboot+springcloud,这套框架也用了半年了,springboot是spring4.0的升级版,简化了springmvc的xml配置,是spring家族中目前 ...

  10. mysql主从备份+keepalived自动切换

    数据库这一层需要做到避免单点故障可以是主从备份和主主备份,主主备份可能有性能损耗和数据同步的问题.这里记录下主从备份, mysql进行备份之前确保mysql的版本是一样的,我这里用的都是mysql5. ...