Removed debug/console.c, we no longer need it. frame_buffer_console_init() is now

called by debug_init_post_vm().
Since the availability of a blue screen specific getchar() is static anyway, there
is no need for the sBlueScreenGetChar variable (only the message "only serial input
available" gets lost, but since that is platform specific anyway...).
Hello blue screen! We now have an on-screen KDL, to be enabled by the kernel
setting "bluescreen", just like on BeOS.
The blue screen does not yet support any cursor actions or backspace, though (need
to grab some stuff from our console driver).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12896 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-05-29 16:23:00 +00:00
parent a332730df7
commit f33c8020e2
11 changed files with 347 additions and 156 deletions
+6 -5
View File
@@ -5,8 +5,8 @@
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#ifndef KERNEL_DBG_CONSOLE_H
#define KERNEL_DBG_CONSOLE_H
#ifndef KERNEL_ARCH_DEBUG_CONSOLE_H
#define KERNEL_ARCH_DEBUG_CONSOLE_H
#include <SupportDefs.h>
@@ -18,16 +18,17 @@ struct kernel_args;
extern "C" {
#endif
char arch_debug_blue_screen_getchar(void);
char arch_debug_serial_getchar(void);
char arch_debug_serial_putchar(char c);
void arch_debug_serial_putchar(char c);
void arch_debug_serial_puts(const char *s);
void arch_debug_serial_early_boot_message(const char *string);
status_t arch_debug_console_init(struct kernel_args *args, char (**blueScreenGetChar)(void));
status_t arch_debug_console_init(struct kernel_args *args);
status_t arch_debug_console_init_settings(struct kernel_args *args);
#ifdef __cplusplus
}
#endif
#endif /* KERNEL_DBG_CONSOLE_H */
#endif /* KERNEL_ARCH_DEBUG_CONSOLE_H */
+1 -1
View File
@@ -31,7 +31,7 @@ extern "C" {
extern status_t debug_init(struct kernel_args *args);
extern status_t debug_init_post_vm(struct kernel_args *args);
extern void debug_early_boot_message(const char *string);
extern char debug_putchar(char c);
extern void debug_putchar(char c);
extern void debug_puts(const char *s);
extern void _user_debug_output(const char *userString);
@@ -26,8 +26,12 @@ struct frame_buffer_boot_info {
extern "C" {
#endif
bool frame_buffer_console_available(void);
status_t frame_buffer_console_init(struct kernel_args *args);
status_t _user_frame_buffer_update(addr_t baseAddress, int32 width, int32 height,
int32 depth, int32 bytesPerRow);
#ifdef __cplusplus
}
#endif
+27 -32
View File
@@ -53,8 +53,29 @@ static bool sBochsOutput = false;
#endif
static char
keyboard_getchar(void)
static void
put_char(const char c)
{
#if BOCHS_DEBUG_HACK
if (sBochsOutput) {
out8(c, 0xe9);
return;
}
#endif
// wait until the transmitter empty bit is set
while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x20) == 0)
;
out8(c, sSerialBasePort + SERIAL_TRANSMIT_BUFFER);
}
// #pragma mark -
char
arch_debug_blue_screen_getchar(void)
{
/* polling the keyboard, similar to code in keyboard
* driver, but without using an interrupt
@@ -102,33 +123,12 @@ keyboard_getchar(void)
}
static void
put_char(const char c)
{
#if BOCHS_DEBUG_HACK
if (sBochsOutput) {
out8(c, 0xe9);
return;
}
#endif
// wait until the transmitter empty bit is set
while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x20) == 0)
;
out8(c, sSerialBasePort + SERIAL_TRANSMIT_BUFFER);
}
// #pragma mark -
char
arch_debug_serial_getchar(void)
{
#if BOCHS_DEBUG_HACK
if (sBochsOutput)
return keyboard_getchar();
return arch_debug_blue_screen_getchar();
#endif
while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x1) == 0)
@@ -138,7 +138,7 @@ arch_debug_serial_getchar(void)
}
char
void
arch_debug_serial_putchar(const char c)
{
if (c == '\n') {
@@ -146,8 +146,6 @@ arch_debug_serial_putchar(const char c)
put_char('\n');
} else if (c != '\r')
put_char(c);
return c;
}
@@ -166,19 +164,16 @@ arch_debug_serial_early_boot_message(const char *string)
{
// this function will only be called in fatal situations
// ToDo: also enable output via text console?!
arch_debug_console_init(NULL, NULL);
arch_debug_console_init(NULL);
arch_debug_serial_puts(string);
}
status_t
arch_debug_console_init(kernel_args *args, char (**_blueScreenGetChar)(void))
arch_debug_console_init(kernel_args *args)
{
uint16 divisor = (uint16)(115200 / kSerialBaudRate);
if (_blueScreenGetChar)
*_blueScreenGetChar = keyboard_getchar;
// only use the port if we could find one, else use the standard port
if (args->platform_args.serial_base_ports[0] != 0)
sSerialBasePort = args->platform_args.serial_base_ports[0];
+1 -1
View File
@@ -3,7 +3,7 @@ SubDir OBOS_TOP src system kernel debug ;
UsePrivateHeaders [ FDirName kernel debug ] ;
KernelMergeObject kernel_debug.o :
console.c
blue_screen.cpp
debug.c
frame_buffer_console.cpp
gdb.c
+190
View File
@@ -0,0 +1,190 @@
/*
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "blue_screen.h"
#include <frame_buffer_console.h>
#include <console.h>
#include <arch/debug_console.h>
#include <string.h>
#include <stdio.h>
#define USE_SCROLLING 0
#define NO_CLEAR 1
struct screen_info {
int32 columns;
int32 rows;
int32 x, y;
uint8 attr;
} sScreen;
console_module_info *sModule;
static inline void
hide_cursor(void)
{
sModule->move_cursor(-1, -1);
}
static inline void
update_cursor(int32 x, int32 y)
{
sModule->move_cursor(x, y);
}
#if USE_SCROLLING
/** scroll from the cursor line up to the top of the scroll region up one line */
static void
scroll_up(void)
{
// move the screen up one
sModule->blit(0, 1, sScreen.columns, sScreen.rows - 1, 0, 0);
// clear the bottom line
sModule->fill_glyph(0, 0, sScreen.columns, 1, ' ', sScreen.attr);
}
#endif
static void
next_line(void)
{
if (sScreen.y == sScreen.rows - 1) {
#if USE_SCROLLING
scroll_up();
#else
sScreen.y = 0;
#endif
} else if (sScreen.y < sScreen.rows - 1) {
sScreen.y++;
}
#if NO_CLEAR
sModule->fill_glyph(0, sScreen.y + 2, sScreen.columns, 1, ' ', sScreen.attr);
#endif
sScreen.x = 0;
}
static void
back_space(void)
{
if (sScreen.x <= 0)
return;
sScreen.x--;
sModule->put_glyph(sScreen.x, sScreen.y, ' ', sScreen.attr);
}
static void
put_character(char c)
{
if (++sScreen.x >= sScreen.columns) {
next_line();
sScreen.x++;
}
sModule->put_glyph(sScreen.x - 1, sScreen.y, c, sScreen.attr);
}
static void
parse_character(char c)
{
// just output the stuff
switch (c) {
case '\n':
next_line();
break;
case 0x8:
back_space();
break;
case '\t':
put_character(' ');
break;
case '\r':
case '\0':
break;
default:
put_character(c);
}
}
// #pragma mark -
status_t
blue_screen_init(void)
{
extern console_module_info gFrameBufferConsoleModule;
// we can't use get_module() here, since it's too early in the boot process
if (!frame_buffer_console_available())
return B_ERROR;
sModule = &gFrameBufferConsoleModule;
return B_OK;
}
void
blue_screen_enter(void)
{
sScreen.attr = 0x0f; // black on white
sScreen.x = sScreen.y = 0;
sModule->get_size(&sScreen.columns, &sScreen.rows);
#if !NO_CLEAR
sModule->clear(sScreen.attr);
#else
sModule->fill_glyph(0, sScreen.y, sScreen.columns, 3, ' ', sScreen.attr);
#endif
}
char
blue_screen_getchar(void)
{
return arch_debug_blue_screen_getchar();
}
void
blue_screen_putchar(char c)
{
hide_cursor();
parse_character(c);
update_cursor(sScreen.x, sScreen.y);
}
void
blue_screen_puts(const char *text)
{
hide_cursor();
while (text[0] != '\0') {
parse_character(text[0]);
text++;
}
update_cursor(sScreen.x, sScreen.y);
}
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef BLUE_SCREEN_H
#define BLUE_SCREEN_H
#include <SupportDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
status_t blue_screen_init(void);
void blue_screen_enter(void);
char blue_screen_getchar(void);
void blue_screen_putchar(char c);
void blue_screen_puts(const char *text);
#ifdef __cplusplus
}
#endif
#endif /* BLUE_SCREEN_H */
-75
View File
@@ -1,75 +0,0 @@
/*
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
/* This file contains the kprintf stuff and console init */
#include <OS.h>
#include <KernelExport.h>
#include <boot/kernel_args.h>
#include <console.h>
#include <frame_buffer_console.h>
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
struct console_op_xy_struct {
int x;
int y;
char buf[256];
};
static int console_fd = -1;
void
kprintf(const char *fmt, ...)
{
int ret = 0;
va_list args;
char temp[256];
if (console_fd >= 0) {
va_start(args, fmt);
ret = vsprintf(temp,fmt,args);
va_end(args);
write_pos(console_fd, 0, temp, ret);
}
}
#if 0
void
kprintf_xy(int x, int y, const char *fmt, ...)
{
int ret = 0;
va_list args;
struct console_op_xy_struct buf;
if (console_fd >= 0) {
va_start(args, fmt);
ret = vsprintf(buf.buf,fmt,args);
va_end(args);
buf.x = x;
buf.y = y;
ioctl(console_fd, CONSOLE_OP_WRITEXY, &buf, ret + sizeof(buf.x) + sizeof(buf.y));
}
}
#endif
int
con_init(kernel_args *args)
{
frame_buffer_console_init(args);
return B_OK;
}
+62 -33
View File
@@ -8,18 +8,18 @@
/* This file contains the debugger */
#include "blue_screen.h"
#include <debug.h>
#include <arch/int.h>
#include <smp.h>
#include <console.h>
#include <frame_buffer_console.h>
#include <gdb.h>
#include <smp.h>
#include <int.h>
#include <vm.h>
#include <driver_settings.h>
#include <arch/debug_console.h>
#include <arch/debug.h>
#include <arch/cpu.h>
#include <stdarg.h>
#include <stdio.h>
@@ -38,12 +38,10 @@ typedef struct debugger_command {
int dbg_register_file[B_MAX_CPU_COUNT][14];
/* XXXmpetit -- must be made generic */
char (*sBlueScreenGetChar)(void) = NULL;
// this will be set by arch_debug_console_init()
static bool sSerialDebugEnabled = false;
static bool sSyslogOutputEnabled = false;
static bool sBlueScreenEnabled = false;
static bool sBlueScreenOutput = false;
static spinlock sSpinlock = 0;
static int sDebuggerOnCPU = -1;
@@ -99,8 +97,8 @@ read_line(char *buf, int max_len)
int cur_history_spot = cur_line;
char (*readChar)(void);
if (sBlueScreenEnabled && sBlueScreenGetChar != NULL)
readChar = sBlueScreenGetChar;
if (sBlueScreenEnabled)
readChar = blue_screen_getchar;
else
readChar = arch_debug_serial_getchar;
@@ -178,7 +176,7 @@ read_line(char *buf, int max_len)
break;
case '$':
case '+':
if (readChar != sBlueScreenGetChar) {
if (!sBlueScreenEnabled) {
/* HACK ALERT!!!
*
* If we get a $ at the beginning of the line
@@ -244,18 +242,14 @@ parse_line(char *buf, char **argv, int *argc, int max_args)
static void
kernel_debugger_loop(void)
{
struct debugger_command *cmd;
int argc;
dprintf("Running on CPU %d\n", smp_get_current_cpu());
if (sBlueScreenEnabled && sBlueScreenGetChar == NULL)
dprintf("Only serial keyboard input available.\n");
sDebuggerOnCPU = smp_get_current_cpu();
cmd = NULL;
for (;;) {
struct debugger_command *cmd = NULL;
int argc;
dprintf("kdebug> ");
read_line(line_buf[cur_line], LINE_BUF_SIZE);
parse_line(line_buf[cur_line], args, &argc, MAX_ARGS);
@@ -333,19 +327,19 @@ cmd_continue(int argc, char **argv)
// #pragma mark -
char
void
debug_putchar(char c)
{
cpu_status state = disable_interrupts();
acquire_spinlock(&sSpinlock);
if (sSerialDebugEnabled)
c = arch_debug_serial_putchar(c);
arch_debug_serial_putchar(c);
if (sBlueScreenOutput)
blue_screen_putchar(c);
release_spinlock(&sSpinlock);
restore_interrupts(state);
return c;
}
@@ -357,6 +351,8 @@ debug_puts(const char *s)
if (sSerialDebugEnabled)
arch_debug_serial_puts(s);
if (sBlueScreenOutput)
blue_screen_puts(s);
release_spinlock(&sSpinlock);
restore_interrupts(state);
@@ -373,7 +369,7 @@ debug_early_boot_message(const char *string)
status_t
debug_init(kernel_args *args)
{
return arch_debug_console_init(args, &sBlueScreenGetChar);
return arch_debug_console_init(args);
}
@@ -389,6 +385,9 @@ debug_init_post_vm(kernel_args *args)
add_debugger_command("exit", &cmd_continue, NULL);
add_debugger_command("es", &cmd_continue, NULL);
frame_buffer_console_init(args);
arch_debug_console_init_settings(args);
// get debug settings
handle = load_driver_settings("kernel");
if (handle != NULL) {
@@ -396,13 +395,14 @@ debug_init_post_vm(kernel_args *args)
sSerialDebugEnabled = true;
if (get_driver_boolean_parameter(handle, "syslog_debug_output", false, false))
sSyslogOutputEnabled = true;
if (get_driver_boolean_parameter(handle, "bluescreen", false, false))
sBlueScreenEnabled = true;
if (get_driver_boolean_parameter(handle, "bluescreen", false, false)) {
if (blue_screen_init() == B_OK)
sBlueScreenEnabled = true;
}
unload_driver_settings(handle);
}
arch_debug_console_init_settings(args);
return arch_debug_init(args);
}
@@ -522,14 +522,20 @@ kernel_debugger(const char *message)
smp_send_broadcast_ici(SMP_MSG_CPU_HALT, 0, 0, 0, NULL, SMP_MSG_FLAG_SYNC);
}
if (message) {
dprintf(message);
dprintf("\n");
if (sBlueScreenEnabled) {
sBlueScreenOutput = true;
blue_screen_enter();
}
dprintf("Welcome to Kernel Debugging Land...\n");
if (message) {
kprintf(message);
kprintf("\n");
}
kprintf("Welcome to Kernel Debugging Land...\n");
kernel_debugger_loop();
sBlueScreenOutput = false;
kernel_startup = false;
restore_interrupts(state);
@@ -548,7 +554,7 @@ set_dprintf_enabled(bool newState)
void
dprintf(const char *fmt, ...)
dprintf(const char *format, ...)
{
cpu_status state;
va_list args;
@@ -563,17 +569,40 @@ dprintf(const char *fmt, ...)
state = disable_interrupts();
acquire_spinlock(&sSpinlock);
va_start(args, fmt);
vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, fmt, args);
va_start(args, format);
vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format, args);
va_end(args);
arch_debug_serial_puts(sOutputBuffer);
if (sBlueScreenOutput)
blue_screen_puts(sOutputBuffer);
release_spinlock(&sSpinlock);
restore_interrupts(state);
}
/** Similar to dprintf() but thought to be used in the kernel
* debugger only.
*/
void
kprintf(const char *format, ...)
{
va_list args;
// ToDo: don't print anything if the debugger is not running!
va_start(args, format);
vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format, args);
va_end(args);
arch_debug_serial_puts(sOutputBuffer);
if (sBlueScreenOutput)
blue_screen_puts(sOutputBuffer);
}
// #pragma mark -
// userland syscalls
@@ -4,6 +4,7 @@
*/
#include <KernelExport.h>
#include <kernel.h>
#include <lock.h>
#include <boot_item.h>
#include <fs/devfs.h>
@@ -298,7 +299,7 @@ console_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
return sConsole.frame_buffer != NULL ? B_OK : B_ERROR;
return frame_buffer_console_available() ? B_OK : B_ERROR;
case B_MODULE_UNINIT:
return B_OK;
@@ -323,10 +324,7 @@ console_module_info gFrameBufferConsoleModule = {
};
// #pragma mark -
status_t
static status_t
frame_buffer_update(addr_t baseAddress, int32 width, int32 height, int32 depth, int32 bytesPerRow)
{
TRACE(("frame_buffer_update(buffer = %p, width = %ld, height = %ld, depth = %ld, bytesPerRow = %ld)\n",
@@ -355,6 +353,16 @@ frame_buffer_update(addr_t baseAddress, int32 width, int32 height, int32 depth,
}
// #pragma mark -
bool
frame_buffer_console_available(void)
{
return sConsole.frame_buffer != NULL;
}
status_t
frame_buffer_console_init(kernel_args *args)
{
@@ -402,3 +410,19 @@ frame_buffer_console_init(kernel_args *args)
return B_OK;
}
// #pragma mark -
status_t
_user_frame_buffer_update(addr_t baseAddress, int32 width, int32 height,
int32 depth, int32 bytesPerRow)
{
if (geteuid() != 0)
return B_NOT_ALLOWED;
if (IS_USER_ADDRESS(baseAddress))
return B_BAD_ADDRESS;
return frame_buffer_update(baseAddress, width, height, depth, bytesPerRow);
}
-4
View File
@@ -12,7 +12,6 @@
#include <OS.h>
#include <boot/kernel_args.h>
#include <console.h>
#include <debug.h>
#include <arch/faults.h>
#include <ksyscalls.h>
@@ -214,9 +213,6 @@ main2(void *unused)
TRACE(("Mount boot file system\n"));
vfs_mount_boot_file_system(&ka);
TRACE(("Init console\n"));
con_init(&ka);
//net_init_postdev(&ka);
//module_test();