UKUUG presentation about µCLinux on Pluto 6

download UKUUG presentation about µCLinux on Pluto 6

If you can't read please download the document

Transcript of UKUUG presentation about µCLinux on Pluto 6

Uclinux on the Pluto 6

From this....

To this...

Edwin Langley : Heber

[email protected]

Craig Duffy : University of the West of England

[email protected]

Project Origin

Pluto 6 Fruit machine controller board made by Heber:

Heber have developed their own in-house monitor/executiveIt has drivers written from scratch by Heber

It is fast, and well understood

We provide to customers drivers compiled to Library object files

However there is a problem...Future boards may use more complex peripheral buses

We will require more complex softwareE.G. TCP/IP stack, USB hosting

Project Origin

A version of the Linux kernel for microcontrollers without a MMU

First port in January 1998 by Rt-Control

Differences to Linux - uClinux has:No virtual address spaces; applications must be linked to absolute addresses

No memory protection

To have drivers altered to operate through local bus instead of ISA/PCI, with bigger interrupt vector ranges

Background to uClinux

Create development environmentObtain tool chain

m68k-elf-gdb

Create new board configuration

Edit entry assembly in crt0_ram.SSet variables _rambase, _ramstart, _ramend, _ramvec.

Edit linker script in ram.ldLink to DRAM at 0x60000000

Porting uClinux to the Pluto 6

Crashed in kernel during boot:Assembly variables were wrong#define MEM_SIZE 0x0016fefc

PAGE_OFFSET was wrong

Stack corruptionSet SP to end of external SRAM

MBAR wrongly set to address of SRAM#define MCF_MBAR 0x10000000

Porting uClinux to the Pluto 6

Romfs too big_ramstart calculated > _ramend

Porting uClinux to the Pluto 6

VBR set to start of RAM, overwriting kernel

Set _ramvec to ColdFire internal SRAM

Finally a working kernel!

But...

2Mb of DRAM doesn't give even uClinux much room to do anythingAfter 3 commands, memory is too fragmented to load programs:

Porting uClinux to the Pluto 6

Romfs contents restricted

Tools are required to test drivers

/bin> vi__alloc_pages: 0-order allocation failed (gfp=0x1d2/0)__alloc_pages: 4-order allocation failed (gfp=0x1f0/0)Allocation of length 65000 from process 20 failedFree pages: 136kB ( 0kB HighMem)Zone:DMA freepages: 0kBZone:Normal freepages: 136kBZone:HighMem freepages: 0kB( Active: 5, inactive: 27, free: 34 )= 0kB)6*4kB 2*8kB 2*16kB 0*32kB 1*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB = 136kB)= 0kB)

Running the kernel from VRAM

Problem: program counter incrementing incorrectly

Possibly cache related

Initial solution to use video card RAM

Solution found and borrowed from Heber:

Getting more memory

Finally a working USABLE kernel!

16Mb local bus interface DRAM card

Vacuum Fluorescent DisplaySimple character device

Clock ASCII characters in through 2 line serial port

Time to write some drivers!

/> echo hello\ world! > /dev/vfd0

FPGA controls 256 lamps as 16 strobes of 32, each has 8 brightness levels

Every 1ms, software must:fill 8 32 bit data registers, each bit corresponds to one lamp

Write the strobe number to illuminate to the MPX control register in the FPGA

The FPGA splits the 1ms period into 8 segments, using 1 data register for each

Each bit of each data register = 1/8ms

Multiplexed lamp driver

Problem:Kernel timer used to rewrite lamp registers every millisecond

Interrupt set for next jiffy, which is incremented by timer interrupt

Timer interrupt frequency determined by HZ

HZ default is 100 (every 10ms)

Lamps flash (on for 1ms, off for 9ms)

Increased HZ to 1000

Multiplexed lamp driver

Choosing interface to user spaceWrite a char for brightness of each lamp1 file for all 256 lampsBig overhead to change 1 lamp

1 file for each lamp256*3*2=1536 context switches

Best compromise1 file for each lamp strobe

Multiplexed lamp driver

Multiplexed lamp driver

/> echo 0123456776543210 > /dev/lamps10/> echo 0707070707070707 > /dev/lamps15

Frame buffer driver

Graphics were a key part of project

Two optionsPort a Denx Coral P X server on a PPC board accessed through PCI running full Linux

Write a frame buffer driver from scratch

Fujitsu Calypso 32 Graphics card

Frame buffer driver

Not a lot of design required

But understanding of sub system is required

Values written to Cremson stored in a par structureInitial par instance with set values used for testing1024x768x16

Frame buffer driver

Lots of code mistakes before finally:

Frame buffer driver

Endian issue, added byte swaps to macros in fb_con.h:

Frame buffer driver

Forgot to allocate memory to 16 entry console pseudo palette:

Frame buffer driver

Had a try with 8 bit indirect colour mode

Created a new par instance

Frame buffer driver

Set bit field lengths in fb_var_screeninfo to 8:

Frame buffer driver

Set layer width in Cremson correctly:

Frame buffer driver

Finally, set the palette tables in video memory in cremson_setcolreg():

Nano X

A pain to compile

IDE

Used a generic driver provided by uClinux

FPGA outputs same interrupt level for CompactFlash and Cremson

Lots of trouble with Cremson Vsync interrupt while unmasking in ColdFire for the IDEMask Vsync on Cremson

Unmask interrupt vector on ColdFire

Copied romfs to CompactFlash card

Altered kernel command line to mount as root FS

eXecute In Place

Tried XIP with romfsRomfs scrambled when copying .data and .init from ROM area to RAM area

No need for romfs with a working disk present

Added initial vector table to crt0_rom.S

Split DRAM card into 2 Mb "ROM" and the rest as RAM area

Could finally boot straight into uClinux at power on

MEMORY {flash : ORIGIN = 0x00000000, LENGTH = 0x00200000ram : ORIGIN = 0x00200000, LENGTH = 0x00E00000}

Project was successful

VerdictBoard is rather slow

Accumulated knowledge for future Heber boards

Lessons learnedUnderstand code before startinglearned lesson porting

used lesson on frame buffer

Learned lots about kernel programming

Conclusion

Questions