From 48af29819f8c2b748dd54cf540f18fb3d39f4fe9 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Wed, 5 Jul 2017 10:28:08 +0200 Subject: some kernel code cleanup renamed 'proc' command to 'task' and make it show number of tasks and context switches --- src/kernel/kernel.c | 142 ++++++++++++++++++++++++++++++---------------------- src/kernel/tasks.c | 4 ++ src/kernel/tasks.h | 1 + 3 files changed, 86 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 57f6d28..50d5e6b 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -41,6 +41,7 @@ typedef enum { typedef struct { vga_text_t vga_text; driver_manager_t driver_manager; + task_manager_t task_manager; vga_t vga; mode_t mode; mouse_t mouse; @@ -56,7 +57,10 @@ static global_context_t global_context; static void funcA( void ); static void funcB( void ); static void refresh_screen( void ); - +static void switch_to_graphics_mode( global_context_t *global_context ); +static void switch_to_text_mode( global_context_t *global_context ); +static void print_task_status( global_context_t *global_context ); + // must be first entry in kernel.bin (0x8800) as stage 2 of // the boot loader expects the entry point to be here! void kernel_main( void ) @@ -88,21 +92,20 @@ void kernel_main( void ) } // TODO: two demo tasks for now, later we should do something useful in a task - task_manager_t task_manager; - task_manager_init( &task_manager ); + task_manager_init( &global_context.task_manager ); task_t taskA; task_init( &taskA, GDT_CODE_SEGMENT_SELECTOR, &funcA ); - task_manager_add_task( &task_manager, &taskA ); + task_manager_add_task( &global_context.task_manager, &taskA ); task_t taskB; task_init( &taskB, GDT_CODE_SEGMENT_SELECTOR, &funcB ); - task_manager_add_task( &task_manager, &taskB ); + task_manager_add_task( &global_context.task_manager, &taskB ); task_t taskRefreshScreen; task_init( &taskRefreshScreen, GDT_CODE_SEGMENT_SELECTOR, &refresh_screen ); - task_manager_add_task( &task_manager, &taskRefreshScreen ); + task_manager_add_task( &global_context.task_manager, &taskRefreshScreen ); puts( "Initializing interrupts" ); interrupt_t interrupt; - interrupts_init( &interrupt, GDT_CODE_SEGMENT_SELECTOR, &task_manager ); + interrupts_init( &interrupt, GDT_CODE_SEGMENT_SELECTOR, &global_context.task_manager ); puts( "Initializing drivers" ); driver_manager_init( &global_context.driver_manager ); @@ -204,64 +207,21 @@ static void handle_keyboard_event( keyboard_event_t *event, void *context ) puts( "halt - terminate os" ); puts( "mem - show memory usage" ); puts( "driver - show status of drivers" ); - puts( "proc - show process status" ); + puts( "task - show task status" ); puts( "clear - clear screen" ); puts( "mode - switch between text/graphics mode" ); } else if( strcmp( buf, "halt" ) == 0 ) { longjmp( panic_jmp_buf, 0 ); } else if( strcmp( buf, "mem" ) == 0 ) { // TODO: print memory usage - } else if( strcmp( buf, "proc" ) == 0 ) { - // TODO: print scheduler status + } else if( strcmp( buf, "task" ) == 0 ) { + print_task_status( global_context ); } else if( strcmp( buf, "driver" ) == 0 ) { driver_manager_print_info_all( driver_manager ); } else if( strcmp( buf, "clear" ) == 0 ) { vga_text_clear_screen( vga_text ); } else if( strcmp( buf, "mode" ) == 0 ) { - // TODO: move mode switches to and from graphics/text mode here, - // for now when we enter the graphics mode we remain there - switch( global_context->mode ) { - case MODE_TEXT: - if( vga_set_mode( vga, vga_make_mode( VGA_MODE_TYPE_GRAPHICS, 320, 200, 8 ) ) ) { - vga_text_save( vga_text ); - - desktop_init( &global_context->desktop, 320, 200, VGA_COLOR_BLUE ); - - window_init( &global_context->window1, (widget_t *)&global_context->desktop, 60, 90, 60, 70, VGA_COLOR_LIGHT_GREY ); - // TODO: this looks clunky! - ((composite_widget_vtable_t *)global_context->desktop.base.base.vtable)->add_child( &global_context->desktop, (widget_t *)&global_context->window1 ); - - window_init( &global_context->window2, (widget_t *)&global_context->desktop, 130, 80, 60, 70, VGA_COLOR_GREEN ); - ((composite_widget_vtable_t *)global_context->desktop.base.base.vtable)->add_child( &global_context->desktop, (widget_t *)&global_context->window2 ); - - char s[100]; - - char *p = s; - for( char c = ' '; c <= '~'; c++ ) { - *p++ = c; - } - *p = '\0'; - - window_init( &global_context->window3, (widget_t *)&global_context->desktop, 55, 5, vga->mode.x - 65, 100, VGA_COLOR_CYAN ); - ((composite_widget_vtable_t *)global_context->desktop.base.base.vtable)->add_child( &global_context->desktop, (widget_t *)&global_context->window3 ); - - text_widget_init( &global_context->widget3, (widget_t *)&global_context->window3, 1, 1, global_context->window3.base.base.w - 2, global_context->window3.base.base.h - 2, VGA_COLOR_RED, s ); - ((composite_widget_vtable_t *)global_context->window3.base.base.vtable)->add_child( (composite_widget_t *)&global_context->window3, (widget_t *)&global_context->widget3 ); - - mouse_set_resolution( mouse, vga->mode.x, vga->mode.y ); - - // enable Z buffering - vga_use_z_buffer( &global_context->vga, true ); - - global_context->mode = MODE_GRAPHICS; - } - - break; - - case MODE_GRAPHICS: - - break; - } + switch_to_graphics_mode( global_context ); } else { printf( "ERR: Unknown pre-boot command '%s'\n", buf ); } @@ -283,13 +243,7 @@ static void handle_keyboard_event( keyboard_event_t *event, void *context ) if( event->key == KEYBOARD_KEY_ASCII ) { ((widget_t *)desktop)->vtable->on_key_down( &global_context->desktop, event->ascii_key ); } else if( event->key == KEYBOARD_KEY_ESC ) { - vga_text_restore( vga_text ); - - if( vga_set_mode( vga, vga_make_mode( VGA_MODE_TYPE_TEXT, 640, 480, 4 ) ) ) { - vga_text_set_cursor( vga_text, vga_text->cursor_x, vga_text->cursor_y ); - mouse_set_resolution( mouse, vga_text->res_x, vga_text->res_y ); - global_context->mode = MODE_TEXT; - } + switch_to_text_mode( global_context ); } } break; @@ -393,3 +347,69 @@ static void refresh_screen( void ) } } +static void switch_to_graphics_mode( global_context_t *global_context ) +{ + vga_t *vga = &global_context->vga; + vga_text_t *vga_text = &global_context->vga_text; + mouse_t *mouse = &global_context->mouse; + desktop_t *desktop = &global_context->desktop; + + if( vga_set_mode( vga, vga_make_mode( VGA_MODE_TYPE_GRAPHICS, 320, 200, 8 ) ) ) { + vga_text_save( vga_text ); + + desktop_init( desktop, 320, 200, VGA_COLOR_BLUE ); + + window_init( &global_context->window1, (widget_t *)desktop, 60, 90, 60, 70, VGA_COLOR_LIGHT_GREY ); + // TODO: this looks clunky! + ((composite_widget_vtable_t *)global_context->desktop.base.base.vtable)->add_child( desktop, (widget_t *)&global_context->window1 ); + + window_init( &global_context->window2, (widget_t *)desktop, 130, 80, 60, 70, VGA_COLOR_GREEN ); + ((composite_widget_vtable_t *)global_context->desktop.base.base.vtable)->add_child( desktop, (widget_t *)&global_context->window2 ); + + char s[100]; + + char *p = s; + for( char c = ' '; c <= '~'; c++ ) { + *p++ = c; + } + *p = '\0'; + + window_init( &global_context->window3, (widget_t *)desktop, 55, 5, vga->mode.x - 65, 100, VGA_COLOR_CYAN ); + ((composite_widget_vtable_t *)global_context->desktop.base.base.vtable)->add_child( desktop, (widget_t *)&global_context->window3 ); + + text_widget_init( &global_context->widget3, (widget_t *)&global_context->window3, 1, 1, global_context->window3.base.base.w - 2, global_context->window3.base.base.h - 2, VGA_COLOR_RED, s ); + ((composite_widget_vtable_t *)global_context->window3.base.base.vtable)->add_child( (composite_widget_t *)&global_context->window3, (widget_t *)&global_context->widget3 ); + + mouse_set_resolution( mouse, vga->mode.x, vga->mode.y ); + + // enable Z buffering + vga_use_z_buffer( &global_context->vga, true ); + + global_context->mode = MODE_GRAPHICS; + } +} + +static void switch_to_text_mode( global_context_t *global_context ) +{ + vga_t *vga = &global_context->vga; + vga_text_t *vga_text = &global_context->vga_text; + mouse_t *mouse = &global_context->mouse; + + vga_text_restore( vga_text ); + + if( vga_set_mode( vga, vga_make_mode( VGA_MODE_TYPE_TEXT, 640, 480, 4 ) ) ) { + vga_text_set_cursor( vga_text, vga_text->cursor_x, vga_text->cursor_y ); + mouse_set_resolution( mouse, vga_text->res_x, vga_text->res_y ); + global_context->mode = MODE_TEXT; + } +} + +static void print_task_status( global_context_t *global_context ) +{ + task_manager_t *task_manager = &global_context->task_manager; + + for( int i = 0; i < task_manager->nof_tasks; i++ ) { + printf( "%d %d\n", i, task_manager->task[i]->nof_switches ); + } +} + diff --git a/src/kernel/tasks.c b/src/kernel/tasks.c index 4dd7f38..30b138b 100644 --- a/src/kernel/tasks.c +++ b/src/kernel/tasks.c @@ -6,6 +6,8 @@ void task_init( task_t *task, uint16_t gdt_code_segment_selector, task_func_t entrypoint ) { memset( task, 0, sizeof( task_t ) ); + + task->nof_switches = 0; task->cpu_state = (cpu_state_t *)( task->stack + TASK_STACK_SIZE - sizeof( cpu_state_t ) ); @@ -71,6 +73,8 @@ cpu_state_t *task_manager_schedule_task( task_manager_t *manager, cpu_state_t *c if( manager->current_task >= manager->nof_tasks ) { manager->current_task = 0; } + + manager->task[manager->current_task]->nof_switches++; return manager->task[manager->current_task]->cpu_state; } diff --git a/src/kernel/tasks.h b/src/kernel/tasks.h index 523631b..dddf9bb 100644 --- a/src/kernel/tasks.h +++ b/src/kernel/tasks.h @@ -43,6 +43,7 @@ typedef struct { typedef struct { uint8_t stack[TASK_STACK_SIZE]; cpu_state_t *cpu_state; + int nof_switches; } task_t; typedef void (*task_func_t)( void ); -- cgit v1.2.3-54-g00ecf