模拟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)是计算机中最重要的系统软件,是这样的一组系统程序的集成:这些系统程序在用户对计算机的使用中 ...
随机推荐
- UVA12493 - Stars(求1-N与N互质的个数)欧拉函数
Sample Input 3 4 5 18 36 360 2147483647 Sample Output 1 1 2 3 6 48 1073741823 题目链接:https://uva.onlin ...
- android-xBuild apk差分与合成,zip差分与合成,lua打包,apk打包,png/jpg图片压缩
android-xBuild 是一项集成了apk差分与合成,zip差分与合成,lua打包.apk打包,png/jpg图片压缩五大功能的开源项目 (github地址:https://github.com ...
- intellij idea的安装步骤---经典
安装IntelliJ IDEA 一.安装JDK 1 下载最新的jdk,这里下的是jdk-8u66 2 将jdk安装到默认的路径C:\Program Files\Java目录下 二.安装IntelliJ ...
- 《Effective Java(中文第二版)》【PDF】下载
<Effective Java(中文第二版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382186 Java(中文第二版)& ...
- 关于Object类下所有方法的简单解析
类Object是类层次结构的根类,是每一个类的父类,所有的对象包括数组,String,Integer等包装类,所以了解Object是很有必要的,话不多说,我们直接来看jdk的源码,开始我们的分析之路 ...
- FileSystemWatcher类监控文件的更改状态并且实时备份文件
首先这是我自己在一个任务需求里面所要用到的,大致的代码如下:我把监视文件和备份文件的方法封装到一个WatcherAndBackup 类中了,但是总感觉封装的不是很好,有大牛能够指出改正之处在此留言,谢 ...
- webpack 3.X学习之多页面打包
简介 我们开发不可能只写一个页面,每次都要写很多页面,这时为了开发效率,我们使用前端自动化工具webpack,那么webpack是如何打包页面的呢?又是如何打包多页面的呢? 单页面打包 我们知道要打包 ...
- [array] leetcode-56. Merge Intervals - Medium
leetcode-56. Merge Intervals - Medium descrition Given a collection of intervals, merge all overlapp ...
- Docker(八):Docker端口映射
1.随机映射 docker run -P -d --name mynginx1 nginx [root@node1 ~]# docker ps -l CONTAINER ID IMAGE COMMAN ...
- Linux第九讲随笔 -进程管理 、ps aux 、
Linux第九讲1,进程管理 Linux在执行每一个程序时,就会在内存中为这个程序建立一个进程,以便让内核可以管理这个运行中的进程,进程是系统分配各种资源,进程调度的基本单位. 怎么查看进程 一.ps ...