RTEMS graphic toolkit and VBE thoughts

Pavel Pisa ppisa4lists at pikron.com
Fri Jul 27 17:25:33 UTC 2012


Hello Alex and others,

I would like to sum up some of my VBE driver
related thoughts because I would not be available
on Internet till August 11.

The VESA BIOS version 3 and above allows to call
functions from protected environment. This way we
can initialize most of graphic cards used with
PC/i386 based system.

To use BIOS from protected mode, it is required
to locate PMInfoBlock structure in ROM, malloc
32kb of RAM, copy BIOS there and fill fields
in PMInfoBlock. There is critical to update
segments selectors for 
  BIOSDataSel
  A0000Sel
  B0000Sel
  B8000Sel
  CodeSegSel

We need to implement function to allow allocate and modify
descriptors ini386  global or local descriptor table.
RTEMS does not have local descriptor table and global one
is of fixed size GDT_SIZE = 3

http://git.rtems.org/rtems/tree/c/src/lib/libbsp/i386/pc386/include/bsp.h

I think, that for the first test and even in future complications
with local descriptor table do not worth the effort.
I would suggest to extend GDT_SIZE to some static predefined,
in the best case compile time configurable value.

Actual _Global_descriptor_table is located in

http://git.rtems.org/rtems/tree/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S#n168

The space for the table should be controlled by GDT_SIZE
and gdtdesc should be filled by GDT_SIZE * 3 -1.
Then there should be some simple counter for selector
allocation. It should start at 3 to point to next free
selector.

We need some function to
  descriptor_number = alloc_gdt_entry()
and
  modify_dt_entry(descriptor_number, set/read, struct user_desc *,
                  count or size);

It should be somehow similar to Linux modify_ldt

int modify_ldt(int func, void *ptr, unsigned long bytecount);

          struct user_desc {
               unsigned int  entry_number;
               unsigned long base_addr;
               unsigned int  limit;
               unsigned int  seg_32bit:1;
               unsigned int  contents:2;
               unsigned int  read_exec_only:1;
               unsigned int  limit_in_pages:1;
               unsigned int  seg_not_present:1;
               unsigned int  useable:1;
           };

Then it is possible to setup required overlay segments, fill descriptors
PMInfoBlock and call functions to setup graphic mode with linear flag
set and obtain linear mapping address.

As for required VBE structures definitions, they can be written
according to VBE specs, found in X11 drivers or they already exists
in MWin package in the file

  microwin-git/src/drivers/djvesa.h
  microwin-git/src/drivers/scr_djvesa.c

Joel, Gedare, please, check license compliance requirements.

Example how to call BIOS functions can be found in PC PCI
code sources

http://git.rtems.org/rtems/tree/c/src/lib/libbsp/i386/shared/pci

In VBE case, we need to use far call to PMInitialize and
then EntryPoint. This means to prepare 16:32 far pointer
which is filled by CodeSegSel:PMInitialize and CodeSegSel:EntryPoint.
The CodeSegSel has to be initialized as 16 code segment,
i.e. seg_32bit=0, contents=MODIFY_LDT_CONTENTS_CODE.

If Alex finds time, he expect to try look at VBE driver option.

The next thing is to think about interface which allows to register
frame buffer(s) at runtime. Basically stub FB driver
with an array of pointers to the structures describing
each registered HW and providing read/write and ioctl
subfunctions.

Best wishes,

               Pavel






More information about the devel mailing list