[uClinux-dev] Re: Porting Linux programs to uClinux and other
Robin Getz
rgetz at blackfin.uclinux.org
Tue Nov 6 08:40:04 EST 2007
On Tue 6 Nov 2007 04:50, Michael Schnell pondered:
>
> > the Blackfin processor has an MPU which means the
> > Blackfin Linux port can (and does) prevent user space from accessing
> > peripherals.
> While I don't doubt that you are right, I suppose the use of the MPU can
> be disabled, in case the OP really wants to avoid writing a Device Driver.
On Blackfin - no - but this has nothing to do with the MMU/MPU or lack
thereof.
Since the Blackfin supports different runtime states (User, Supervisor, IDLE,
Emulation, Reset) in hardware, Linux takes advantage of these. Any access to
a privileged resource from user mode (userspace) will generate an "Illegal
use of supervisor resource" exception - and the process gets killed. This
would include supervisor only registers, all memory mapped registers
(peripherals), and supervisor only instructions.
You get a nice dump that looks like:
root:~> ./bar
Illegal use of supervisor resource
- Attempted to use a Supervisor register or instruction from User mode.
Supervisor resources are registers and instructions that are reserved
for Supervisor use: Supervisor only registers, all MMRs, and Supervisor
only instructions.
CURRENT PROCESS:
COMM=bar PID=104
TEXT = 0x012ff000-0x012ff6f0 DATA = 0x037d26f0-0x037d2848
BSS = 0x037d2848-0x010c0000 USER-STACK = 0x010dfed0
return address: [0x012ff680]; contents of:
0x012ff660: 000d 0c43 1808 0000 9159 ac5b 3042 e801
0x012ff670: 0000 0051 e801 0000 0010 0000 e800 0000
0x012ff680: [0030] e801 0000 0010 e51a 000a 04c5 e800
0x012ff690: 0003 326a e512 ffff 6fe5 0c7a 1809 0000
SEQUENCER STATUS:
SEQSTAT: 0000002e IPEND: 0030 SYSCFG: 0006
RETE: <0x00000000> /* Maybe null pointer? */
RETN: <0x01040000> [ klogd + 0x0 ]
RETX: <0x012ff680> [ /bar + 0x680 ]
RETS: <0x001f2650> [ /lib/libuClibc-0.9.29.so + 0x32650 ]
DCPLB_FAULT_ADDR: <0x010dfe80> [ bar + 0x1fe80 ]
ICPLB_FAULT_ADDR: <0x012ff680> [ /bar + 0x680 ]
PROCESSOR STATE:
R0 : 00000001 R1 : 010dfed4 R2 : 010dfedc R3 : 00000002
R4 : 037ae54c R5 : 00000001 R6 : 010dfed4 R7 : 037b98a8
P0 : 037ae54c P1 : 012ff67c P2 : 037ba294 P3 : 037d27f0
P4 : 037ae55c P5 : 037bba3c FP : 010dfe80 SP : 0103ff24
LB0: 01f7df51 LT0: 01f7df44 LC0: 00000000
LB1: 01f7cd51 LT1: 01f7cd50 LC1: 00000000
B0 : 00000000 L0 : 00000000 M0 : 00000000 I0 : 012ff6e8
B1 : 00000000 L1 : 00000000 M1 : 00000000 I1 : 012ff6ec
B2 : 00000000 L2 : 00000000 M2 : 00000000 I2 : 00000000
B3 : 00000000 L3 : 00000000 M3 : 00000000 I3 : 00000000
A0.w: 00000000 A0.x: 00000000 A1.w: 00000000 A1.x: 00000000
USP : 010dfe80 ASTAT: 02003025
Hardware Trace:
0 Target : <0x000046a8> { _trap_c + 0x0 }
Source : <0xffa00aac> { _exception_to_level5 + 0xb4 }
1 Target : <0xffa009f8> { _exception_to_level5 + 0x0 }
Source : <0xffa00950> { _ex_trap_c + 0x5c }
2 Target : <0xffa008f4> { _ex_trap_c + 0x0 }
Source : <0xffa00b4c> { _trap + 0x28 }
3 Target : <0xffa00b24> { _trap + 0x0 }
Source : <0x012ff67c> [ /bar + 0x67c ]
4 Target : <0x012ff67c> [ /bar + 0x67c ]
Source : <0x001f264e> [ /lib/libuClibc-0.9.29.so + 0x3264e ]
5 Target : <0x001f2638> [ /lib/libuClibc-0.9.29.so + 0x32638 ]
Source : <0x001d0da0> [ /lib/libuClibc-0.9.29.so + 0x10da0 ]
[snip - this goes on for 16, but in this case it is not interesting]
Stack from 0103ff00:
ffffe000 ffa00ab0 0014f694 0014f694 0014f690 00000001 010dfa94
001ccf44 012ff680 00000030 0000002e 00000000 01040000 012ff680
001f2650 00000001 02003025 01f7cd51 01f7df51 01f7cd50 01f7df44
00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 012ff6ec 012ff6e8 010dfe80 010dfe80
Call Trace:
Illegal instruction
root:~>
We can quickly look on the host for the fault address with objdump:
ICPLB_FAULT_ADDR: <0x012ff680> [ /bar + 0x680 ]
0000067c <_main>:
67c: 00 e8 00 00 LINK 0x0; /* (0) */
680: 30 00 CLI R0;
682: 01 e8 00 00 UNLINK;
686: 10 00 RTS;
CLI is the instruction that Disable Interrupts - and can only be executed by
the kernel - we tried running it from userspace, so our process got killed.
After all - this is what most would expect would happen on Linux - isn't it?
Other processors may not have this understanding of context, and you be able
to do things like turn off interrupts in userspace. Maybe even by accident if
you have a stack overflow, and you execute a few random instructions...
-Robin
More information about the uClinux-dev
mailing list