模拟uClinux系统调用
这篇文章原来放在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系统调用的更多相关文章
- GCC编译器原理(一)------交叉编译器制作和GCC组件及命令
1.1 交叉编译器制作 默认安装的 GCC 编译系统所产生的代码适用于本机,即运行 GCC 的机器,但也可将 GCC 安装成能够生成其他的机器代码.安装一些必须的模块,就可产生多种目标机器代码,而且可 ...
- Rootkit Hacking Technology && Defence Strategy Research
目录 . The Purpose Of Rootkit . Syscall Hijack . LKM Module Hidden . Network Communication Hidden . Fi ...
- SAP S4CRM 1811 服务订单API介绍
Jerry在今年2月28日,SAP Customer Management for S/4HANA 1.0正式问世这个具有纪念意义的日子,同时发布了中英文版的博客进行介绍. 英文版发在SAP社区上,至 ...
- 获取fork+exec启动的程序的PID值
问题背景 业务中有个场景需要自动起一个A程序(由于A程序与 sublime_text 启动后遇到的问题有相似之处,后文就用 sublime_text 来替代A程序,当A程序与 sublime_ ...
- Linux系列(41) - 监听命令Vmstart,Top(还需完善)
一.简介 vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存.进程.CPU活动进行监控:属于sysstat包:它是对系统的整体情况进行统计 ...
- [Linux]Linux系统调用列表
本文列出了大部分常见的Linux系统调用,并附有简要中文说明. 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的 ...
- VB模拟键盘输入的N种方法
VB模拟键盘输入的N种方法http://bbs.csdn.net/topics/90509805hd378发表于: 2006-12-24 14:35:39用VB模拟键盘事件的N种方法 键盘是我们使用计 ...
- 模拟XShell的小项目
不知道大家有没有用过XShell这款工具,这款工具通过windows可以远程操作处于开机状态的linux操作系统,也就是说把你的电脑和一台服务器连入网络,你通过输入服务器所在的IP地址建立一个会话就可 ...
- 别出心裁的Linux系统调用学习法
别出心裁的Linux系统调用学习法 操作系统与系统调用 操作系统(Operating System,简称OS)是计算机中最重要的系统软件,是这样的一组系统程序的集成:这些系统程序在用户对计算机的使用中 ...
随机推荐
- Git 二分调试法,火速定位疑难Bug!
你一定遇到过,一个很久没修改过的功能,莫名其妙的出现了问题?肉眼查代码.屡逻辑完全找不到问题点?前两天还好好的功能,怎么这个今天就不行了?这两天改动了这么多代码,到底是那一次改动引发的 Bug? 这样 ...
- javaweb学习总结(四)——Http协议(转)
转载自 http://www.cnblogs.com/xdp-gacl/p/3751277.html 一.什么是HTTP协议 HTTP是hypertext transfer protocol(超文本传 ...
- VisualStudio程序运行后控制台窗口一闪就没了
这个虽然是千查万查出来的,但也不是原创的.希望对大家有所帮助. 方案一:网上最常见的解决方案是,在程序结尾的 return 0; 之前加 system("pause") 或 get ...
- 自己手写WEB程序框架并执行
1.新建目录,起名MyWeb 2.目录下,新建两个目录 WEB-INF, META-INF,,还能够新建一些jsp,html文件 ,如 index.html 3在WEB-INF中必须存在一个文件WEB ...
- CoordinatorLayout与滚动的处理
本博文专门解说和CoordinatorLayout相关的知识点,这也是Design Support Library中最重要与最难的部分. 概览 CoordinatorLayout实现了多种Materi ...
- js原生的轮播,原理以及实践
轮播,无论是文字轮播还是图片轮播,他们的原理是一样的,都是通过定时器执行循环展示和影藏. 一.手动轮播 (1)原理 一系列的大小相等的图片平铺,利用CSS布局只显示一张图片,其余隐藏.通过计算偏移量利 ...
- 【Java入门提高篇】Day7 Java内部类——局部内部类
今天介绍第二种内部类--局部内部类. 局部内部类是什么?顾名思义,那就是定义在局部内部的类(逃).开玩笑的,局部内部类就是定义在代码块.方法体内.作用域(使用花括号"{}"括起来的 ...
- 阿里云服务器(windows server2008)下安装SVN----杜恩德
我想说的是如何在阿里云上建立SVN版本,供外网访问,上传代码 在阿里云服务器上安装svn与在本地安装是一样的, ----参考 http://blog.csdn.net/m0_37027631/arti ...
- springboot+CXF开发webservice对外提供接口(转)
文章来源:http://www.leftso.com/blog/144.html 1.项目要对外提供接口,用webservcie的方式实现 2.添加的jar包 maven: <dependenc ...
- 6.python内置函数
1. abs() 获取绝对值 >>> abs(-10) 10 >>> a = -10 >>> a.__abs__() 10 2. all() ...