Puppy Linux Discussion Forum Forum Index Puppy Linux Discussion Forum
Puppy HOME page : puppylinux.com
"THE" alternative forum : puppylinux.info
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

The time now is Sun 21 Dec 2014, 23:44
All times are UTC - 4
 Forum index » Advanced Topics » Cutting edge
improve Xfbdev with kernel patch
Moderators: Flash, Ian, JohnMurga
Post_new_topic   Reply_to_topic View_previous_topic :: View_next_topic
Page 1 of 1 Posts_count  
Author Message
technosaurus


Joined: 18 May 2008
Posts: 4425

PostPosted: Wed 13 Jun 2012, 14:42    Post_subject:  improve Xfbdev with kernel patch  

With Xvesa being deprecated (actually completely gone in xorg), the last remaining small Xserver is Xfbdev, but it has one big hurdle.
One of the things that makes Xorg a necessity is all of the manual kernel command line interaction by the user that is needed to set the resolution of the frame buffer. let's see if we can automate that

AFAIK, all of the code is in arch/x86/boot/video.c
Code:
void set_video(void)
{...
   for (;;) {
      if (mode == ASK_VGA)
         mode = mode_menu();
/* TODO:   if (mode == MAX_VGA) mode = mode_max(); */
      if (!set_mode(mode))
         break;
...}


which would need a function:
static unsigned int mode_max(); /* based on mode_menu()*/
here is my best guess:

Code:
static void modemax(void)
{
   struct card_info *card;
   struct mode_info *mi;
   int i;
   int nmodes;
   int visible;
   u16 mode_max;
   u16 res_max = 0;

   nmodes = 0;
   for (card = video_cards; card < video_cards_end; card++)
      nmodes += card->nmodes;

   for (card = video_cards; card < video_cards_end; card++) {
      mi = card->modes;
      for (i = 0; i < card->nmodes; i++, mi++) {
         visible = mi->x && mi->y;
         if (!visible)
            continue; /* Hidden mode */
         if (!mi->depth)
            continue; /* I _think_ we need depth */
         if ((mi->x * mi->y * mi->depth) > res_max){
            res_max=(mi->x * mi->y * mi->depth);
            mode_max = mi->mode ? mi->mode : (mi->y << 8)+mi->x;
         }
      }
   }
return (mode_max)
}


assuming we can get the above to work, we'd need to wedge in a vga=max parameter (but for testing we can just use the vga=ask code by replacing mode_menu with the modemax code)

_________________
Web Programming - Pet Packaging 100 & 101
Back to top
View user's profile Send_private_message 
technosaurus


Joined: 18 May 2008
Posts: 4425

PostPosted: Wed 13 Jun 2012, 19:06    Post_subject:  

ok, here is the quick hack that I am going to _try_ to build and test it by using vga=ask
Code:
static unsigned int mode_menu(void)
{
   struct card_info *card;
   struct mode_info *mi;
   int i;
   int visible;
   u16 mode_max;
   u16 res_max = 0;

   for (card = video_cards; card < video_cards_end; card++) {
      mi = card->modes;
      for (i = 0; i < card->nmodes; i++, mi++) {
         visible = mi->x && mi->y;
         if (!visible)
            continue; /* Hidden mode */
         if (!mi->depth)
            continue; /* I _think_ we need depth */
         if ((mi->x * mi->y * mi->depth) > res_max){
            res_max=(mi->x * mi->y * mi->depth);
            mode_max = mi->mode ? mi->mode : (mi->y << 8)+mi->x;
         }
      }
   }
return (mode_max)
}

_________________
Web Programming - Pet Packaging 100 & 101
Back to top
View user's profile Send_private_message 
akash_rawal

Joined: 25 Aug 2010
Posts: 232
Location: ISM Dhanbad, Jharkhand, India

PostPosted: Thu 14 Jun 2012, 03:42    Post_subject:  

I think the code should first try to guess the maximum resolution rather than asking the user. If that doesn't work, then ask the user.

I think set_mode() returns nonzero in case of failure.

Here's the function that finds maximum resolution available. If multiple modes with same resolution exist, one with maximum depth is selected.
Code:
u16 guess_max_resolution(void)
{
   struct card_info *card;
   struct mode_info *mi;
   
   unsigned long long max_pixels = 0;
   unsigned int max_depth = 0;
   u16 sel_mode = 0;
   
   //Iterate for each mode
   for (card = video_cards; card < video_cards_end; card++)
   {
      int i;
      mi = card->modes;
      for (i = 0; i < card->nmodes; i++, mi++)
      {
         //Avoid 'hidden modes'
         int visible = mi->x && mi->y;
         if (!visible) continue;
         
         //Uncomment this if depth is required
         //if (! mi->depth) continue;
         
         unsigned long long one_pixels = mi->x * mi->y;
         u16 onemode = mi->mode ? mi->mode : (mi->y << 8) + mi->x;
         //Check whether this one is higher
         if (one_pixels > max_pixels)
         {
            //Select this one
            sel_mode = onemode;
            max_pixels = one_pixels;
            max_depth = mi->depth;
         }
         else if (one_pixels == max_pixels)
         {
            //Check for maximum depth
            if (mi->depth)
            {
               if (mi->depth > max_depth)
               {
                  //Select this one
                  sel_mode = onemode;
                  max_depth = mi->depth;
               }
            }
         }
      }
   }
   
   return sel_mode;
}

It could be integrated like this:
Code:

void set_video(void)
{
   ...
   int not_guessed = 1;
   for (;;)
   {
      if (mode == ASK_VGA)
      {
         //If guessing maximum resolution hasn't been tried yet try it now
         if (not_guessed)
         {
            mode = guess_max_resolution();
            not_guessed = 0;
         }
         else
            mode = mode_menu();
      }
      
      if (!set_mode(mode))
         break;
      
      printf("Undefined video mode number: %x\n", mode);
      mode = ASK_VGA;
   }
   ...
}
Back to top
View user's profile Send_private_message 
PANZERKOPF

Joined: 16 Dec 2009
Posts: 280
Location: Earth

PostPosted: Fri 15 Jun 2012, 15:53    Post_subject: Re: improve Xfbdev with kernel patch  

technosaurus wrote:

One of the things that makes Xorg a necessity is all of the manual kernel command line interaction by the user that is needed to set the resolution of the frame buffer.

It seems there is another way to get a working framebuffer. Kernel has several framebuffer modules for particular videocards (nvidiafb, radeonfb etc.). We can
boot in usual text mode, load a module, tune framebuffer with fbset utility then load Xfbdev server. I guess that framebuffer should be faster than VESA one.

_________________
SUUM CUIQUE.
Back to top
View user's profile Send_private_message 
Iguleder


Joined: 11 Aug 2009
Posts: 1927
Location: Israel, somewhere in the beautiful desert

PostPosted: Sat 20 Sep 2014, 07:40    Post_subject:  

I wrote a similar patch for the 3.14.x "longterm" branch (using code from mode_menu(), with akash_rawal's patch as inspiration). I tried to keep the patch as short as possible.

The idea is to force a framebuffer console, to allow the use of Xfbdev instead of Xorg or Xvesa under KMS-incapable hardware. You can find the patch here:

Code:
diff -rup linux-3.14.19-orig/arch/x86/boot/video.c linux-3.14.19/arch/x86/boot/video.c
--- linux-3.14.19-orig/arch/x86/boot/video.c   2014-09-21 20:11:20.662964171 +0300
+++ linux-3.14.19/arch/x86/boot/video.c   2014-09-22 19:22:39.520944994 +0300
@@ -312,6 +312,39 @@ static void restore_screen(void)
    store_cursor_position();
 }
 
+static u16 guess_mode(void) {
+   int i;
+   unsigned long max_pixels = 0UL;
+   u16 max_depth = 0;
+   u16 mode = ASK_VGA;
+   struct card_info *card;
+   struct mode_info *mi;
+
+   for (card = video_cards; card < video_cards_end; card++) {
+      mi = card->modes;
+      for (i = 0; i < card->nmodes; i++, mi++) {
+         int visible = mi->x && mi->y;
+         u16 mode_id = mi->mode ? mi->mode :
+               (mi->y << 8)+mi->x;
+
+         if (!visible)
+            continue; /* Hidden mode */
+
+         unsigned long pixels = mi->x * mi->y;
+         if (pixels > max_pixels) {
+            max_pixels = pixels;
+            max_depth = mi->depth;
+            mode = mode_id;
+         } else if ((pixels == max_pixels) && (mi->depth > max_depth)) {
+            max_depth = mi->depth;
+            mode = mode_id;
+         }
+      }
+   }
+
+   return mode;
+}
+
 void set_video(void)
 {
    u16 mode = boot_params.hdr.vid_mode;
@@ -322,6 +355,9 @@ void set_video(void)
    save_screen();
    probe_cards(0);
 
+   if (mode == ASK_VGA)
+      mode = guess_mode();
+
    for (;;) {
       if (mode == ASK_VGA)
          mode = mode_menu();

_________________
My homepage
My GitHub profile
Back to top
View user's profile Send_private_message Visit_website MSNM 
ICQ 
Display_posts:   Sort by:   
Page 1 of 1 Posts_count  
Post_new_topic   Reply_to_topic View_previous_topic :: View_next_topic
 Forum index » Advanced Topics » Cutting edge
Jump to:  

Rules_post_cannot
Rules_reply_cannot
Rules_edit_cannot
Rules_delete_cannot
Rules_vote_cannot
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group
[ Time: 0.0836s ][ Queries: 11 (0.0051s) ][ GZIP on ]