天天看点

arm linux swi 例子,ARM SWI 软中断详解

SWI : SoftWare InterruptSWIThis is a simple facility, but possibly the most used. Many

Operating System facilities are provided by SWIs. It is impossible to

imagine RISC OS without SWIs.

Nava Whiteford explains how SWIs work (originally in Frobnicate issue 12½)...

In this article I will attempt to delve into the working of SWIs (SoftWare Interrupts).

What is a SWI?SWI stands for Software Interrupt. In RISC

OS SWIs are used to access Operating System routines or modules

produced by a 3rd party. Many applications use modules to provide low

level external access for other applications.

Examples of SWIs are:The Filer SWIs, which aid reading to and from disc, setting attributes etc.

The Printer Driver SWIs, used to well aid the use of the Parallel port for printing.

The SWIs FreeNet/Acorn TCP/IP stack SWIs used to transmit and

receive data using the TCP/IP protocol usually used for sending data

over the Internet.

When used in this way, SWIs allow the Operating System to have a

modular structure, meaning that the code required to create a complete

operating system can be split up into a number of small parts (modules)

and a module handler.

When the SWI handler gets a request for a particular routine

number it finds the position of the routine and executes it, passing

any data.

So how does it work?Well first lets look at how you use it. A SWI instruction (in assembly language) looks like this: SWI &02or SWI "OS_Write0"Both these instructions are in fact the same, and would therefore

assemble to the same instruction. The only difference is that the

second instruction uses a string to represent the SWI number which is

&02. When a program written using the string is used, the string is

first looked up before execution.

We're not going to deal with the strings here as they do not give

a true representation of what it going on. They are often used to aid

the clarity of a program, but are not the actual instructions that are

executed.

Right lets take a look at the first instruction again:SWI &02What does that mean? Well, literally it means enter the SWI

handler and pass value &02. In RISC OS this means execute routine

number &02.

So how does it do that, how does it passed the SWI number and enter the SWI handler?

If you look at a disassembly of the first 32 bytes of memory

(locations 0-&1C) and disassemble them (look at the actual ARM

instructions) you should see something like this:Address Contents Disassembly

00000000 : 0..å : E5000030 : STR R0,[R0,#-48]

00000004 : .óŸå : E59FF31C : LDR PC,&00000328

00000008 : .óŸå : E59FF31C : LDR PC,&0000032C

0000000C : .óŸå : E59FF31C : LDR PC,&00000330

00000010 : .óŸå : E59FF31C : LDR PC,&00000334

00000014 : .óŸå : E59FF31C : LDR PC,&00000338

00000018 : .óŸå : E59FF31C : LDR PC,&0000033C

0000001C : 2¦ ã : E3A0A632 : MOV R10,#&3200000So what? You may think, well take a closer look.

Excluding the first and last instructions (which are special cases)

you can see that all the instruction load the PC (Program Counter),

which tells the computer where to execute the next instruction from,

with a new value. The value is taken from a address in memory which is

also shown. (you can take a look at this for yourself using the "Read

Memory" option on the !Zap main menu.)

Now, this may seem to bare little relation to SWIs but with the following information it should make more sense.

All a SWI does is change the Mode to Supervisor and set the PC

to execute the next instruction at address &08! Putting the

processor into Supervisor mode switches out 2 registers r13 and r14 and

replaces these with r13_svc and r14_svc.

When entering Supervisor mode, r14_svc will also be set to the address after the SWI instruction.

This is really just like a Branch with Link to address &08 (BL &08) but with space for some data (the SWI number).

As I have said address &08 contains a instruction which

jumps to another address, this is the address where the real SWI

Handler is!

At this point you maybe thinking "Hang on a minute! What about

the SWI number?". Well in fact the value itself is ignored by the

processor. The SWI handler obtains it using the value of r14_svc that

got passed.

This is how it does it (after storing the registers r0-r12):

It subtracts 4 from r14 to obtain the address of the SWI instruction.

Loads the instruction into a register.

Clears the last 8 bits of the instruction, getting rid of the OpCode and giving just the SWI number.

Uses this value to find to address of the routine of the code to be executing (using lookup tables etc.).

Restore the registers r0-r12.

Takes the processor out of Supervisor mode.

Jumps to the address of the routine.Easy! ;)

Here is some example code, from the ARM610 datasheet:0x08 B Supervisor

EntryTable

DCD ZeroRtn

DCD ReadCRtn

DCD WriteIRtn

...

Zero EQU 0

ReadC EQU 256

WriteI EQU 512

; SWI has routine required in bits 8-23 and data

; (if any) in bits 0-7.

; Assumes R13_svc points to a suitable stack

STMFD R13, {r0-r2 , R14}

; Save work registers and return address

LDR R0,[R14,#-4]

; Get SWI instruction.

BIC R0,R0, #0xFF000000

; Clear top 8 bits.

MOV R1, R0, LSR #8

; Get routine offset.

ADR R2, EntryTable

; Get start address of entry

; table.

LDR R15,[R2,R1,LSL #2]

; Branch to appropriate routine.

WriteIRtn

; Wnte with character in R0 bits 0 - 7.

.............

LDMFD R13, {r0-r2 , R15}^

; Restore workspace and return, restoring

; processor mode and flags.That's it, that's the basics of the SWI instruction.

Sources:

The ARM610 datasheet by Advanced Risc Machines

The ARM RISC Chip - A programmers guide by van Someren Atack published by Addison Wesley