Hello,
please, can you consider the bbsplash patch I sent on march 7.
I try to resend it.
Thanks.
Michele
diff -urP busybox/include/applets.h busybox_bbsplash/include/applets.h
--- busybox/include/applets.h 2008-03-07 09:20:14.000000000 +0100
+++ busybox_bbsplash/include/applets.h 2008-03-07 10:55:00.000000000 +0100
@@ -86,6 +86,7 @@
USE_BASENAME(APPLET_NOFORK(basename, basename, _BB_DIR_USR_BIN, _BB_SUID_NEVER, basename))
USE_BBCONFIG(APPLET(bbconfig, _BB_DIR_BIN, _BB_SUID_NEVER))
//USE_BBSH(APPLET(bbsh, _BB_DIR_BIN, _BB_SUID_NEVER))
+USE_BBSPLASH(APPLET(bbsplash, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_BRCTL(APPLET(brctl, _BB_DIR_USR_SBIN, _BB_SUID_NEVER))
USE_BUNZIP2(APPLET(bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
USE_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER, bzcat))
diff -urP busybox/include/usage.h busybox_bbsplash/include/usage.h
--- busybox/include/usage.h 2008-03-07 09:20:14.000000000 +0100
+++ busybox_bbsplash/include/usage.h 2008-03-07 14:42:17.000000000 +0100
@@ -119,6 +119,19 @@
"$ basename /foo/bar.txt .txt\n" \
"bar"
+#define bbsplash_trivial_usage \
+ "[-c] [-d /dev/fbN] [-i /path_of_inifile] [-f /path_of_fifo]"
+#define bbsplash_full_usage \
+ "Options:\n" \
+ " -c Hide the cursor\n" \
+ " -d Select the framebuffer device (default /dev/fb0)\n" \
+ " -i Select the bbsplash .ini file (default /etc/bbsplash/bbsplash.ini)\n" \
+ " -f Select the bbsplash fifo (default /dev/bbsplash_fifo)\n"
+#define bbsplash_example_usage \
+ "$ setsid bbsplash [-cdif] (start the daemon)" \
+ "$ echo val > /dev/bbsplash_fifo (where val=0..100 - show a progress bar of value val)\n" \
+ "$ echo exit > /dev/bbsplash_fifo (kill the daemon)\n"
+
#define brctl_trivial_usage \
"COMMAND [BRIDGE [INTERFACE]]"
#define brctl_full_usage \
diff -urP busybox/miscutils/bbsplash.c busybox_bbsplash/miscutils/bbsplash.c
--- busybox/miscutils/bbsplash.c 1970-01-01 01:00:00.000000000 +0100
+++ busybox_bbsplash/miscutils/bbsplash.c 2008-03-07 14:54:24.000000000 +0100
@@ -0,0 +1,427 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * boot splash implementation for busybox
+ *
+ * Copyright (C) 2008 Michele Sanges <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ * If you want logging messages on /dev/bbsplash_log, change the DEBUG define to 1 in the source.
+ *
+ * Usage:
+ * - pass to the kernel the options 'vga=xxx' to enable the framebuffer with the correct resolution
+ * - put somewhere the bbsplash.ini file and the splash image in .ppm format.
+ * - configure the applet by editing the .ini file.
+ * - start the applet: $ setsid bbsplash <params>
+ * where <params> can be:
+ * -c: to hide the cursor; -d /dev/fbN: to select another framebuffer device than /dev/fb0
+ * -i /path_of_inifile: to select another .ini file than /etc/bbsplash/bbsplash.ini;
+ * -f /path_of_fifo: to select another fifo file than /dev/bbsplash_fifo.
+ * - if you want run the applet only in presence of a kernel parameter (for example bbsplash=on), type:
+ * $ grep -q "bbsplash=on" < /proc/cmdline && setsid bbsplash <params>
+ * - send to the /dev/bbsplash_fifo the following messages:
+ * (1) the percentage of the boot process.
+ * (2) 'exit' in order to kill the applet.
+ */
+
+/**
+ * boot splash implementation for busybox
+ * \file: bbsplash.c
+ * \author Michele Sanges <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>
+ * \version 1.0.0
+ * \date 07/03/2008
+ */
+
+#include "libbb.h"
+#include <linux/fb.h>
+
+#define DEBUG 0
+#define BYTES_PER_PIXEL 2
+
+struct globals {
+#if DEBUG
+ bool bdebug_messages; ///< flag for enable/disable writing messages in logfile
+ FILE *logfile_fd; ///< log file
+#endif
+ int fbfd; ///< descriptor of framebuffer device
+ FILE *theme_file; ///< splash file
+ unsigned char *addr; ///< pointer to framebuffer memory
+ unsigned nbar_width; ///< progress bar width
+ unsigned nbar_height; ///< progress bar height
+ unsigned nbar_posx; ///< progress bar orizzontal position
+ unsigned nbar_posy; ///< progress bar vertical position
+ unsigned char nbar_colr; ///< progress bar colour red component
+ unsigned char nbar_colg; ///< progress bar colour green component
+ unsigned char nbar_colb; ///< progress bar colour blue component
+ char *pstrsplash_theme; ///< pointer to the name of the splash file
+ struct fb_var_screeninfo screen_infovar;
+ struct fb_fix_screeninfo screen_infofix;
+};
+
+#define G (*ptr_to_globals)
+#define DATA unsigned short
+
+/// function used for debug purpose
+#if DEBUG
+#define DEBUG_MESSAGE(strMessage, args...) \
+ if (G.bdebug_messages) { \
+ fprintf(G.logfile_fd, "[%s][%s] - %s\n", \
+ __FILE__, __FUNCTION__, strMessage); \
+ }
+#else
+#define DEBUG_MESSAGE(...) ((void)0)
+#endif
+
+
+/**
+ * open and initialize the framebuffer device.
+ * \param *strfb_device pointer to framebuffer device
+ */
+static void fb_open(char *strfb_device)
+{
+ G.fbfd = xopen(strfb_device, O_RDWR);
+
+ G.theme_file = xfopen(G.pstrsplash_theme, "r");
+
+ // framebuffer properties
+ xioctl(G.fbfd, FBIOGET_VSCREENINFO, &G.screen_infovar);
+ xioctl(G.fbfd, FBIOGET_FSCREENINFO, &G.screen_infofix);
+
+ if (G.screen_infovar.bits_per_pixel != 16)
+ bb_error_msg_and_die("only 16 bpp is supported");
+
+ // map the device in memory
+ G.addr = mmap(NULL,
+ G.screen_infovar.xres * G.screen_infovar.yres * (G.screen_infovar.bits_per_pixel / 8),
+ PROT_WRITE, MAP_SHARED, G.fbfd, 0);
+
+ if (G.addr == (unsigned char *)-1) {
+#if DEBUG
+ char strMex[30];
+ sprintf(strMex, "can't mmap %s", strfb_device);
+ DEBUG_MESSAGE(strMex);
+#endif
+ exit(EXIT_FAILURE);
+ }
+}
+
+
+/**
+ * draws a rectangle on framebuffer
+ * \param nx1pos,ny1pos upper left position
+ * \param nx2pos,ny2pos down right position
+ * \param nred24,ngreen24,nblue24 rgb colour
+ */
+static void fb_drawrectangle(int nx1pos, int ny1pos, int nx2pos, int ny2pos,
+ unsigned char nred, unsigned char ngreen, unsigned char nblue)
+{
+ int cnt;
+ DATA thispix;
+ DATA *ptr1, *ptr2;
+
+ nred >>= 3; // 5-bit red
+ ngreen >>= 2; // 6-bit green
+ nblue >>= 3; // 5-bit blue
+ thispix = nblue + (ngreen << 5) + (nred << (5+6));
+
+ // horizontal lines
+ ptr1 = (DATA*)(G.addr + (ny1pos * G.screen_infovar.xres + nx1pos) * BYTES_PER_PIXEL);
+ ptr2 = (DATA*)(G.addr + (ny2pos * G.screen_infovar.xres + nx1pos) * BYTES_PER_PIXEL);
+ cnt = nx2pos - nx1pos;
+ do {
+ *ptr1++ = thispix;
+ *ptr2++ = thispix;
+ } while (--cnt >= 0);
+
+ // vertical lines
+ ptr1 = (DATA*)(G.addr + (ny1pos * G.screen_infovar.xres + nx1pos) * BYTES_PER_PIXEL);
+ ptr2 = (DATA*)(G.addr + (ny1pos * G.screen_infovar.xres + nx2pos) * BYTES_PER_PIXEL);
+ cnt = ny2pos - ny1pos;
+ do {
+ *ptr1 = thispix; ptr1 += G.screen_infovar.xres;
+ *ptr2 = thispix; ptr2 += G.screen_infovar.xres;
+ } while (--cnt >= 0);
+}
+
+
+/**
+ * draws a full rectangle on framebuffer
+ * \param nx1pos,ny1pos upper left position
+ * \param nx2pos,ny2pos down right position
+ * \param nred24,ngreen24,nblue24 rgb colour
+ */
+static void fb_drawfullrectangle(int nx1pos, int ny1pos, int nx2pos, int ny2pos,
+ unsigned char nred, unsigned char ngreen, unsigned char nblue)
+{
+ int cnt1, cnt2, nypos;
+ DATA thispix;
+ DATA *ptr;
+
+ nred >>= 3; // 5-bit red
+ ngreen >>= 2; // 6-bit green
+ nblue >>= 3; // 5-bit blue
+ thispix = nblue + (ngreen << 5) + (nred << (5+6));
+
+ cnt1 = ny2pos - ny1pos;
+ nypos = ny1pos;
+ do {
+ ptr = (DATA*)(G.addr + (nypos * G.screen_infovar.xres + nx1pos) * BYTES_PER_PIXEL);
+ cnt2 = nx2pos - nx1pos;
+ do {
+ *ptr++ = thispix;
+ } while (--cnt2 >= 0);
+
+ nypos++;
+ } while(--cnt1 >= 0);
+}
+
+
+/**
+ * draws a progress bar on framebuffer
+ * \param nPercent percentage of loading
+ */
+static void fb_drawprogressbar(unsigned char nPercent)
+{
+ int i;
+
+ fb_drawrectangle(G.nbar_posx, G.nbar_posy,
+ G.nbar_posx + G.nbar_width, G.nbar_posy + G.nbar_height,
+ G.nbar_colr/2, G.nbar_colg/2, G.nbar_colb/2);
+
+ fb_drawfullrectangle(G.nbar_posx + 1, G.nbar_posy + 1,
+ G.nbar_posx + G.nbar_width - 1, G.nbar_posy + G.nbar_height - 1,
+ G.nbar_colr, G.nbar_colg, G.nbar_colb);
+
+ if (nPercent > 0) {
+ for (i = 1; i < (G.nbar_height - 1); i++)
+ fb_drawfullrectangle(G.nbar_posx + 1, G.nbar_posy + i,
+ G.nbar_posx + 1 + (G.nbar_width - 2)*nPercent/100,
+ G.nbar_posy + (i+1), 200-(100*(i-1))/(G.nbar_height - 2),
+ 200-(100*(i-1))/(G.nbar_height - 2),
+ 200-(100*(i-1))/(G.nbar_height - 2));
+ }
+}
+
+
+/**
+ * draws the theme image
+ */
+static void fb_drawimage(void)
+{
+ uint i, j, x, y, z;
+ char head[256];
+ char s[80];
+ unsigned char pix[3];
+
+ memset(head, 0, sizeof(head));
+
+ rewind(G.theme_file);
+ while (1) {
+ // parse ppm header
+ fgets(s, 80, G.theme_file);
+
+ if (s[0] == '#')
+ continue;
+
+ if (strlen(head) + strlen(s) > 255)
+ exit(3);
+
+ strcat(head, s);
+ if (head[0]!='P' || head[1]!='6')
+ exit(4);
+
+ if (sscanf(head, "P6 %i %i %i", &x, &y, &z) == 3)
+ break;
+// BUG: can go into infinite loop.
+// Imagine a file with the following contents: "P6 123"
+ }
+
+ for (j=0; j<y; j++) {
+ unsigned thispix;
+ for (i = 0; i < x; i++) {
+ int idx;
+ fread(pix, 1, 3, G.theme_file);
+ if (i >= G.screen_infovar.xres)
+ continue;
+ if (j >= G.screen_infovar.yres)
+ continue;
+
+ idx = j * G.screen_infofix.line_length + i*2;
+ thispix = (((short)pix[0] << 8) & 0xf800)
+ | (((short)pix[1] << 3) & 0x07e0)
+ | ((short)pix[2] >> 3);
+
+ *(DATA *)(G.addr + idx) = thispix;
+ }
+ }
+}
+
+
+/**
+ * initializes the application with the data taken from the configuration file.
+ */
+static void init(char *strini_file)
+{
+ FILE *pinifile;
+ char *buf;
+ static const char const param_value[] ALIGN1 =
+ "DEBUG_MESSAGES\0""SPLASH_THEME\0""BAR_WIDTH\0""BAR_HEIGHT\0"
+ "BAR_POS_X\0""BAR_POS_Y\0""BAR_R_COL\0""BAR_G_COL\0""BAR_B_COL\0";
+
+ pinifile = xfopen(strini_file, "r");
+
+ while ((buf = xmalloc_getline(pinifile)) != NULL) {
+ char *pvalue;
+ int nindex;
+
+ if (*buf == '#') { // it's a comment
+ free(buf);
+ continue;
+ }
+
+ pvalue = strchrnul(buf, '=');
+ if (*pvalue) *pvalue++ = '\0';
+
+ nindex = index_in_strings(param_value, buf);
+
+ switch(nindex) {
+ case 0:
+#if DEBUG
+ G.bdebug_messages = (strcmp(pvalue, "ON") == 0);
+ if (G.bdebug_messages)
+ G.logfile_fd = xfopen("/dev/bbsplash_log", "w");
+#endif
+ break;
+ case 1:
+ // name of the splash theme
+ G.pstrsplash_theme = pvalue;
+ break;
+ case 2:
+ // progress bar width
+ G.nbar_width = atoi(pvalue);
+ break;
+ case 3:
+ // progress bar height
+ G.nbar_height = atoi(pvalue);
+ break;
+ case 4:
+ // progress bar orizzontal position
+ G.nbar_posx = atoi(pvalue);
+ break;
+ case 5:
+ // progress bar vertical position
+ G.nbar_posy = atoi(pvalue);
+ break;
+ case 6:
+ // progress bar colour - red component
+ G.nbar_colr = atoi(pvalue);
+ break;
+ case 7:
+ // progress bar colour - green component
+ G.nbar_colg = atoi(pvalue);
+ break;
+ case 8:
+ // progress bar colour - blue component
+ G.nbar_colb = atoi(pvalue);
+ break;
+ }
+
+ free(buf);
+ }
+
+ fclose(pinifile);
+}
+
+
+int bbsplash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int bbsplash_main(int argc, char **argv)
+{
+ int i, fd, len;
+ char buf[255];
+ char *pstrfb_device, *pstrini_file, *pstrfifo_file;
+ bool bCursorOff = false;
+
+ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G)));
+
+ // command line option
+ opterr = 0; // disables writing on stderr
+ i = getopt32(argv, "cd:i:f:", &pstrfb_device, &pstrini_file, &pstrfifo_file);
+
+ bCursorOff = (i & 0x01);
+
+ if ((i & 0x02) == 0)
+ pstrfb_device = (char *)"/dev/fb0";
+
+ if ((i & 0x04) == 0)
+ pstrini_file = (char *)"/etc/bbsplash/bbsplash.ini";
+
+ if ((i & 0x08) == 0)
+ pstrfifo_file = (char *)"/dev/bbsplash_fifo";
+
+ // initializes the application with the data taken from the configuration file.
+ init(pstrini_file);
+
+ // hide the cursor
+ if (bCursorOff) {
+ printf("\E[?25l\n");
+ }
+
+ // change the file mode mask
+ umask(0);
+
+ // open the fifo used for receiving commands
+ mkfifo(pstrfifo_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+
+ // open the command fifo
+ fd = xopen(pstrfifo_file, O_RDWR | O_NOCTTY/* | O_NONBLOCK*/);
+
+ fb_open(pstrfb_device);
+ fb_drawimage();
+ fb_drawprogressbar(0);
+
+ while(1) {
+ int nVal;
+
+ len = read(fd, buf, 255);
+ if (len == -1) {
+ DEBUG_MESSAGE("error reading the fifo");
+ break;
+ }
+
+ buf[len] = '\0';
+
+ // parse the commands
+ if (strcmp(buf, "exit\n") == 0) {
+ DEBUG_MESSAGE("exit");
+ break;
+ }
+ nVal = atoi(buf);
+ if ((nVal >= 0) && (nVal <= 100)) {
+#if DEBUG
+ char strVal[10];
+ sprintf(strVal, "%d", nVal);
+ DEBUG_MESSAGE(strVal);
+#endif
+ fb_drawprogressbar(nVal);
+ }
+ }
+
+#if DEBUG
+ // closing log file
+ if (G.bdebug_messages)
+ fclose(G.logfile_fd);
+#endif
+
+ // restoring the cursor
+ if (bCursorOff) {
+ printf("\E[?25h\n");
+ }
+
+ // close the fifo
+ close(fd);
+
+ // remove the fifo
+ unlink(pstrfifo_file);
+
+ return EXIT_SUCCESS;
+}
diff -urP busybox/miscutils/bbsplash.ini busybox_bbsplash/miscutils/bbsplash.ini
--- busybox/miscutils/bbsplash.ini 1970-01-01 01:00:00.000000000 +0100
+++ busybox_bbsplash/miscutils/bbsplash.ini 2008-03-07 15:02:53.000000000 +0100
@@ -0,0 +1,18 @@
+# debug messages: ON or OFF
+DEBUG_MESSAGES=OFF
+# splash theme
+SPLASH_THEME=/etc/bbsplash/splash.ppm
+# progress bar width
+BAR_WIDTH=300
+# progress bar height
+BAR_HEIGHT=20
+# progress bar orizzontal position
+BAR_POS_X=170
+# progress bar vertical position
+BAR_POS_Y=300
+# progress bar colour red component
+BAR_R_COL=80
+# progress bar colour green component
+BAR_G_COL=80
+# progress bar colour blue component
+BAR_B_COL=130
diff -urP busybox/miscutils/Config.in busybox_bbsplash/miscutils/Config.in
--- busybox/miscutils/Config.in 2008-03-07 09:20:14.000000000 +0100
+++ busybox_bbsplash/miscutils/Config.in 2008-03-07 14:51:28.000000000 +0100
@@ -19,6 +19,29 @@
The bbconfig applet will print the config file with which
busybox was built.
+config BBSPLASH
+ bool "bbsplash"
+ default n
+ help
+ Shows a splash image and a progress bar on framebuffer device.
+ Can be used during the boot phase of a embedded device.
+ If you want logging messages on /dev/bbsplash_log, change the DEBUG define to 1 in the source.
+ Adds 1742 bytes.
+
+ Usage:
+ - pass to the kernel the options 'vga=xxx' to enable the framebuffer with the correct resolution
+ - put somewhere the bbsplash.ini file and the splash image in .ppm format.
+ - configure the applet by editing the .ini file.
+ - start the applet: $ setsid bbsplash <params>
+ where <params> can be: -c: to hide the cursor; -d /dev/fbN: to select another framebuffer device than /dev/fb0;
+ -i /path_of_inifile: to select another .ini file than /etc/bbsplash/bbsplash.ini;
+ -f /path_of_fifo: to select another fifo file than /dev/bbsplash_fifo.
+ - if you want run the applet only in presence of a kernel parameter (for example bbsplash=on), type:
+ $ grep -q "bbsplash=on" < /proc/cmdline && setsid bbsplash <params>
+ - send to the bbsplash fifo the following messages:
+ (1) the percentage of the boot process.
+ (2) 'exit' in order to kill the applet.
+
config CHAT
bool "chat"
default n
diff -urP busybox/miscutils/Kbuild busybox_bbsplash/miscutils/Kbuild
--- busybox/miscutils/Kbuild 2008-03-07 09:20:14.000000000 +0100
+++ busybox_bbsplash/miscutils/Kbuild 2008-03-07 10:55:00.000000000 +0100
@@ -7,6 +7,7 @@
lib-y:=
lib-$(CONFIG_ADJTIMEX) += adjtimex.o
lib-$(CONFIG_BBCONFIG) += bbconfig.o
+lib-$(CONFIG_BBSPLASH) += bbsplash.o
lib-$(CONFIG_CHAT) += chat.o
lib-$(CONFIG_CHRT) += chrt.o
lib-$(CONFIG_CROND) += crond.o
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox