Color management for procedures using vga_putchar

As seen in some BSD operating systems, you can now push and pop foreground and background colors onto a stack to change the colors you see on the screen whenever kprintf/kputchar is used.

This could become useful if one wants to see kernel space kprintfs in other colors than user space printfs or error messages in red and other debugging purposes.

Beware: This is just a small and dirty hack which protects the colorstack with locks and so on. But on task switching the color will not be switched. That makes different colors for different colors persistent for all the time difficult/impossible. But I considered adding colors to the task structures a bit overdone for a small debugging-help.

[Sorry for those commit-and-pull-back-mails. Forgot that I had this stuff on the master branch while pushing my own branch onto the server.]
This commit is contained in:
Jacek Galowicz 2011-05-21 11:51:22 +02:00
parent fc17e7710d
commit 394befa3a8
4 changed files with 110 additions and 5 deletions

View file

@ -209,15 +209,15 @@ int vga_puts(const char *text)
}
/* Sets the forecolor and backcolor we will use */
//void settextcolor(unsigned char forecolor, unsigned char backcolor)
//{
void settextcolor(unsigned char forecolor, unsigned char backcolor)
{
/*
* Top 4 bytes are the background, bottom 4 bytes
* are the foreground color
*/
// attrib = (backcolor << 4) | (forecolor & 0x0F);
//}
attrib = ((backcolor & 0x0F) << 4) | (forecolor & 0x0F);
}
/* Sets our text-mode VGA pointer, then clears the screen for us */
void vga_init(void)

View file

@ -74,6 +74,45 @@ int koutput_init(void);
*/
int kvprintf(char const *fmt, void (*func) (int, void *), void *arg, int radix, va_list ap);
/** @brief Set a new foreground color for kprintf and kputchar.
*
* The color change will affect any procedure using vga_putchar()/vga_puts().
* This procedure pushes the color onto a colorstack making you
* able to revert this change just with a popfg().
* */
void pushfg(unsigned char fgcol);
/** @brief Set a new background color for kprintf and kputchar.
*
* The color change will affect any procedure using vga_putchar()/vga_puts().
* This procedure pushes the color onto a colorstack making you
* able to revert this change just with a popbg().
* */
void pushbg(unsigned char bgcol);
#define COL_BLACK 0
#define COL_BLUE 1
#define COL_GREEN 2
#define COL_CYAN 3
#define COL_RED 4
#define COL_MAGENTA 5
#define COL_BROWN 6
#define COL_LGRAY 7
#define COL_DGRAY 8
#define COL_LBLUE 9
#define COL_LGREEN 10
#define COL_LCYAN 11
#define COL_LRED 12
#define COL_LMAGENTA 13
#define COL_LYELLOW 14
#define COL_WHITE 15
/** @brief Revert the last foreground color change introduced by pushfg() */
void popfg();
/** @brief Revert the last background color change introduced by pushfg() */
void popbg();
#ifdef __cplusplus
}
#endif

View file

@ -82,7 +82,10 @@ int main(void)
{
lowlevel_init();
kprintf("This is MetalSVM %s Build %u, %u\n", METALSVM_VERSION, &__BUILD_DATE, &__BUILD_TIME);
pushbg(COL_BLUE);
kprintf("This is MetalSVM %s Build %u, %u\n",
METALSVM_VERSION, &__BUILD_DATE, &__BUILD_TIME);
popbg();
system_init();
irq_init();

View file

@ -45,6 +45,7 @@
*/
#include <metalsvm/string.h>
#include <metalsvm/spinlock.h>
#define __64BIT__
@ -74,6 +75,14 @@ char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
#define MAXNBUF (sizeof(intmax_t) * NBBY + 1)
#define COLOR_STACK_SIZE 10
static int fgstack[COLOR_STACK_SIZE] = {0xf};
static int bgstack[COLOR_STACK_SIZE] = {0x0};
static unsigned int fgstack_pos = 0;
static unsigned int bgstack_pos = 0;
static spinlock_t fglock = SPINLOCK_INIT;
static spinlock_t bglock = SPINLOCK_INIT;
/*
* Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
* order; return an optional length and a pointer to the last character
@ -483,3 +492,57 @@ int kprintf(const char *fmt, ...)
return ret;
}
extern void settextcolor(unsigned char forecolor, unsigned char backcolor);
void pushfg(unsigned char fgcol)
{
spinlock_lock(&fglock);
/* Ignore this request if the stack is full */
if (fgstack_pos == COLOR_STACK_SIZE) goto rel_pushfglock;
++fgstack_pos;
fgstack[fgstack_pos] = fgcol;
settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]);
rel_pushfglock:
spinlock_unlock(&fglock);
}
void pushbg(unsigned char bgcol)
{
spinlock_lock(&bglock);
/* Ignore this request if the stack is full */
if (bgstack_pos == COLOR_STACK_SIZE) goto rel_pushbglock;
++bgstack_pos;
bgstack[bgstack_pos] = bgcol;
settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]);
rel_pushbglock:
spinlock_unlock(&bglock);
}
void popfg()
{
spinlock_lock(&fglock);
/* Ignore if we're already at the stack's bottom */
if (!fgstack_pos) goto rel_popfglock;
--fgstack_pos;
settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]);
rel_popfglock:
spinlock_unlock(&fglock);
}
void popbg()
{
spinlock_lock(&bglock);
/* Ignore if we're already at the stack's bottom */
if (!bgstack_pos) goto rel_popbglock;
--bgstack_pos;
settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]);
rel_popbglock:
spinlock_unlock(&bglock);
}