Statistics

Members: 1927
News: 293
Web Links: 1
Visitors: 3962725

Who's Online

We have 2 guests online
Damn Vulnerable LinuxDamn Vulnerable Linux (DVL) is a Linux-based (modified Damn Small Linux) tool for IT-Security & IT-Anti- Security and Attack & Defense. [CLICK HERE FOR MORE INFOS! ]

Featured Conference Video

T16-Recon2006-Joe_Stewart-OllyBonE.gif OllyBone - Semi-Automatic Unpacking on IA-32. View the conference video here!
Home arrow Articles - Programming arrow Assembly arrow Enter fbcon
Enter fbcon
User Rating: / 0
PoorBest 
Written by Konstantin Boldyshev   


Many of Linux users have heard something about fbcon. It is becoming more and more popular, mostly because of capability of getting graphics on usual terminal without X. How to use graphic capabilities of fbcon?

 

 

The /dev/fb# devices represent frame buffer devices; they allow the frame buffer of a video card to be read and written to by a user, and allow a programmer to access the video hardware [and, more importantly, the video memory] through ioctls and memory mapping.

The general approach to using fbcon is pretty simple:

  1. open /dev/fb0
  2. mmap /dev/fb0
  3. .. do the thing .. (use pointer returned by mmap to access videomemory)
  4. munmap /dev/fb0
  5. close /dev/fb0

I've taken one of my old DOS intros made in tasm, and rewritten it for nasm and Linux/fbcon. At 408 bytes, This intro is the smallest implementation of linear transformation with recursion (AFAIK).

Leaves.asm runs for about a minute and a half (depends on machine), and is interruptible at any time with ^C. If everything is ok you should see two branches of green leaves, and kinda wind blowing on them. It MUST be run only in 640x480x256 mode (vga=0x301 in lilo.conf). You will see garbage or incorrect colors in other modes.

Warning! Intro assumes that everything is ok with the system (/dev/fb0 exists, can be opened and mmap()ed, correct video mode is set, and so on). So, if you ain't root, check permissions on /dev/fb0 first, or you will not see anything.

The source is quite portable, you only need to implement putpixel() and initialization part for your OS. To get the basic idea across, here is the fbcon implementation in C:

//========================================================================== // leaves.c : C implementation using /dev/fb0 #include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

typedef unsigned char byte;
typedef unsigned int word;
typedef float dword;

#define MaxX 640
#define MaxY 480
#define VMEM_SIZE MaxX*MaxY

#define xc MaxX/2
#define yc MaxY/2
#define xmin0 100
#define xmax0 -xmin0
#define ymin0 xmin0
#define ymax0 -ymin0

#define colornum 8

int h;
byte *p;

byte ColorTable[colornum] = { 0x00,0x00,0x02,0x00,0x00,0x02,0x0A,0x02 }; int color=0;

dword f=MaxY/(ymax0-ymin0)3/2;
dword x1coef=MaxX-MaxY
4/9-yc;
dword y1coef=MaxY/4+xc;
dword x2coef=MaxY*4/9+yc;
dword x0=110;

dword a=0.7;
dword b=0.2;
dword c=0.5;
dword d=0.3;

void putpixel(word x,word y,byte color) {

(p+yMaxX+x) = color;
}

void leaves(dword x,dword y,byte n)
{
word x1,y1;

if (n>0)
{
y1=f*x+y1coef;

putpixel(x1coef-fy,y1,ColorTable[color]); putpixel(fy+x2coef,y1,ColorTable[color]);

if (++color>colornum-1) color=0;

leaves(ax+by, bx-ay, n-1); leaves(c(x-x0)-dy+x0,d(x-x0)+cy,n-1);

}
}

int main(void)
{
int i;

p=mmap(0,VMEM_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,open("/dev/fb0",O_RDWR),0);

for (i=0;i<VMEM_SIZE;i++) *(p+i) = 0;

leaves(0,0,28);

     munmap(p,VMEM_SIZE);
close(h);

}
//--------------------------------------------------------------------------EOF

Here is the asm source. It is quite short and self-explaining :) Well, actually the source is badly optimized for size, contains some Linux-specific tricks, and can be hard to understand. Please refer to the C source for areas that need clarification

NOTE:     The following source was taken from asmutils and requires asmutils
macros (*.inc), available from {http://linuxassembly.org};
you can also download binary there (in samples archive)

To compile leaves.asm:

          $ nasm -f elf leaves.asm
$ ld -s -o leaves leaves.o

;========================================================================== ;Copyright (C) 1999 Konstantin Boldyshev <{ This e-mail address is being protected from spam bots, you need JavaScript enabled to view it }> ;
;leaves - fbcon intro in 408 bytes ;
;Ah, /if haven't guessed yet/ license is GPL, so enjoy! :)

%include "system.inc"

%assign SIZE_X 640
%assign SIZE_Y 480
%assign DEPTH 8
%assign VMEM_SIZE SIZE_X*SIZE_Y

%define MaxX 640.0
%define MaxY 480.0
%define xc MaxX/2
%define yc MaxY/2
%define xmin0 100.0
%define xmax0 -xmin0
%define ymin0 xmin0
%define ymax0 -ymin0

CODESEG
;al - color
putpixel:

     push edx       
lea    edx,[ebx+ebx*4]     ;computing offset..
shl    edx,byte 7     ;multiply on 640
add  edx,[esp+8]    ;
mov  [edx+esi],al   ;write to frame buffer
pop  edx
_return:
ret

; recursive function itself
leaves:

        mov    ecx,[esp+12]
test   cl,cl
jz   _return
mov    [esp-13],cl
mov    eax,[edi]
push   ecx
sub    esp,byte 8
mov  edx,esp
fld  dword [ebp+16] ;[f]
fld  st0
fld  st0
fmul dword [edx+16]
fadd dword [ebp+24] ;[y1coef]
fistp     dword [edx]
mov    ebx,[edx]
fmul dword [edx+20]
fsubr     dword [ebp+20] ;[x1coef]
fistp     dword [edx]
call   putpixel
fmul dword [edx+20]
fadd dword [ebp+28] ;[x2coef]
fistp     dword [edx]
call   putpixel
inc  edi
cmp    edi,ColorEnd
jl     .rec
sub  edi,byte ColorEnd-ColorBegin

.rec:

     fld  dword [ebp+4]  ;[b]
fld  dword [ebp]    ;[a]
fld  st1
fld  st1
fxch
fmul dword [edx+16]
fxch
fmul dword [edx+20]
fsubp     st1
fstp dword [edx-8]
fmul dword [edx+16]
fxch
fmul dword [edx+20]
faddp     st1
dec  ecx
push   ecx
sub    esp,byte 8
fstp dword [esp]
call   leaves         ;esp+12
mov  edx,esp
fld  dword [ebp+12] ;[d]
fld  dword [edx+28]
fld  dword [ebp+8]  ;[c]
fld  dword [ebp+32] ;[x0]
fsub to st2
fld  st3
fld  st2
fxch
fmul st4
fxch
fmul dword [edx+32]
faddp     st1
fstp dword [edx-8]
fxch
fmulp     st2
fxch st2
fmul dword [edx+32]
fsubp     st1
faddp     st1
push   ecx
sub    esp,byte 8
fstp dword [esp]
call   leaves
add    esp,byte 12*2+8
pop    ecx
.return:
ret

;------------------------------------- main() START:
;prepare structure for mmap on the stack

     mov  edi,VMEM_SIZE
mov  esi,esp
mov  [esi-16],edi                  ;.len
mov  [esi-12],byte PROT_READ|PROT_WRITE ;.prot
mov  [esi-8],byte MAP_SHARED            ;.flags
mov  [esi],edx                ;.offset

;init fb

     mov  ebp,Params
lea  ebx,[ebp+0x2C] ;fb-Params
sys_open EMPTY,O_RDWR
test eax,eax        ;have we opened file?
js   exit
mov  [esi-4],eax    ;mm.fd
lea  ebx,[esi-20]
sys_mmap
test eax,eax        ;have we mmaped file?
js   exit
mov  esi,eax

;clear screen

     mov  ecx,edi
mov  edi,esi
xor  eax,eax
rep  stosb

;leaves

     lea  edi,[ebp+0x24] ;ColorBegin-Params
push   byte 28        ;recursion depth
push eax
push eax
call   leaves

;close fb

     sys_munmap esi,VMEM_SIZE
sys_close [mm.fd]
exit

sys_exit

;----------------------------Parameters Params:

a dd 0.7
b dd 0.2
c dd 0.5
d dd 0.3

f    dd   0xc0400000     ;MaxY/(ymax0-ymin0)3/2  
x1coef    dd   0x433b0000     ;MaxX-MaxY4/9-yc
y1coef    dd   0x43dc0000     ;MaxY/4+xc
x2coef    dd   0x43e28000     ;MaxY*4/9+yc

x0 dd 112.0

ColorBegin

db 0,0,2,0,0,2,10,2

ColorEnd

fb db "/dev/fb0";,NULL

END
;===========================================================================EOF

More information on the frame buffer device can be found in the Linux kernel documentation [ usually /usr/src/linux/Documentation ] files framebuffer.txt, internals.txt, matroxfb.txt, tgafb.txt, and vesafb.txt. The /dev/fbcon# ioctls are defined in /usr/include/linux/fb.h .

Enjoy the demo!