模拟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)是计算机中最重要的系统软件,是这样的一组系统程序的集成:这些系统程序在用户对计算机的使用中 ...
随机推荐
- MySQL-Select语句高级应用
1.1 SELECT高级应用 1.1.1 前期准备工作 本次测试使用的是world数据库,由mysql官方提供下载地址: https://dev.mysql.com/doc/index-other.h ...
- 网络协议之ipv6
1. 地址分类 比較重要的主要有以下几种: 本地链路地址:用于链路之间相互通信 本地网站地址:用于子网内互相通信,类似于ipv4中的私有地址 全球单播地址:类似于ipv4中的公网地址 组播地址 2. ...
- 打印杨辉三角 --JS
var arr = new Array(); for(var i = 0 ;i < 6 ; i++){ if(i == 0){arr.push(1);} else if(i == 1){arr ...
- vim 命令整理(自己经常使用)
vimm(vimsual)是Linux/UNIX系列OS中通用的全屏编辑器. vimm分为两种状态,即命令状态和编辑状态.在命令状态下.所键入的字符系统均作命令来处理.如:q代表退出,而编辑状态则是用 ...
- stanford-parser for C#
在项目里用到C#对英文句子进行词性标注.比較成熟的英文词性标注软件是stanford-parser.它个C#版本号,也是借助于IKVM完毕JAVA-C#的转换.详细配置过程例如以下: 1.下载stan ...
- 第二十六天 蛰伏的Hibernate遇到春日的暖阳 —Spring MVC 集成Hibernate使用(一)
6月7日.晴."纷纷红紫已成尘,布谷声中夏令新. 夹路桑麻行不尽.始知身是太平人. " Hibernate和Spring的香艳相逢,不仅是Bean和Bean之间电光火 ...
- A. Arrays(Codeforces Round #317 水题)
A. Arrays time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- .NET Core 2.0下载和文档
.NET Core 2.0 RTM 正式版2017/8/14 发布.对应发布 ASP.NET Core 2.0 .EF Core 2.0以及.NET Standard 2.0. 你可以通过 Visua ...
- jmeter的使用---web测试
jmeter的使用---web测试 url:http://127.0.0.1:1080/WebTours/ 1.通过badboy录制脚本 1.1输入url点击右侧的跳转按钮,随后右侧显示url界面 1 ...
- [UWP]了解模板化控件(7):支持Command
以我的经验来说,要让TemplatedControl支持Command的需求不会很多,大部分情况用附加属性解决这个需求会更便利些,譬如UWPCommunityToolkit的HyperlinkExte ...