[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