From e382b70880fe82176a086f909a027a2f85a884b6 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 11 May 2017 22:12:08 +0200 Subject: added strlcpy (and a host test for it) started to add I/O port code for VGA data and select ports --- src/Makefile | 2 +- src/kernel.c | 2 ++ src/port.asm | 25 +++++++++++++++++++++++++ src/port.c | 11 +++++++++++ src/port.h | 9 +++++++++ src/stdlib.c | 7 +++++++ src/stdlib.h | 6 ++++++ src/string.c | 30 ++++++++++++++++++++++++++++++ src/string.h | 2 ++ src/vga.c | 28 ++++++++++++++++++++++++++++ src/vga.h | 6 ++++++ tests/Makefile | 23 +++++++++++++++++++++++ tests/test_strlcpy.c | 15 +++++++++++++++ 13 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 src/port.asm create mode 100644 src/port.c create mode 100644 src/stdlib.c create mode 100644 src/stdlib.h create mode 100644 tests/Makefile create mode 100644 tests/test_strlcpy.c diff --git a/src/Makefile b/src/Makefile index 4e0755a..45db0f7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -44,7 +44,7 @@ stdlib.o: stdlib.c $(CC) $(CFLAGS) -c -o stdlib.o stdlib.c clean: - -rm -f boot.bin kernel.bin image.bin magic.bin *.o + -rm -f boot.bin kernel.bin image.bin magic.bin *.o kernel.map image.tmp run-qemu: image.bin qemu-system-i386 -m 32 -drive "file=image.bin,if=ide,format=raw" diff --git a/src/kernel.c b/src/kernel.c index a18e2d2..0f09819 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -30,6 +30,8 @@ void entry( void ) } vga_put_char_at( &vga, x_pos, y_pos, '.' ); vga_put_newline( &vga ); + + vga_put_hex( &vga, 4711 ); //~ vga_set_color( &vga, VGA_COLOR_WHITE ); //~ vga_set_background_color( &vga, VGA_COLOR_RED ); diff --git a/src/port.asm b/src/port.asm new file mode 100644 index 0000000..34d1f78 --- /dev/null +++ b/src/port.asm @@ -0,0 +1,25 @@ +[bits 32] + +global port8_write + +port8_write: + mov edx, [ebp+16] + mov eax, (edx) +; mov dx, [ebp+8] +; out ax, dl + ret + + +;~ void port8_init( port8_t *port, uint16_t number ) + + + +;~ global _myfunc +;~ _myfunc: push ebp + ;~ mov ebp,esp + ;~ sub esp,0x40 ; 64 bytes of local stack space + ;~ mov ebx,[ebp+8] ; first parameter to function + ;~ ; some more code + ;~ leave ; mov esp,ebp / pop ebp + ;~ ret + ; __asm__ volatile("outb %0, %1" : : "a" (_data), "Nd" (_port)); diff --git a/src/port.c b/src/port.c new file mode 100644 index 0000000..1a55669 --- /dev/null +++ b/src/port.c @@ -0,0 +1,11 @@ +#include "port.h" + +void port8_init( port8_t *port, uint16_t number ) +{ + port->number = number; +} + +uint8_t port8_read( port8_t *port ) +{ + return 0; +} diff --git a/src/port.h b/src/port.h index a4621de..98f63fc 100644 --- a/src/port.h +++ b/src/port.h @@ -1,5 +1,14 @@ #ifndef PORT_H #define PORT_H +#include + +typedef struct port8_t { + uint16_t number; // port number, e.g. 0x3d4 VGA index register +} port8_t; + +void port8_init( port8_t *port, uint16_t number ); +void port8_write( port8_t *port, uint8_t data ); +uint8_t port8_read( port8_t *port ); #endif /* PORT_H */ diff --git a/src/stdlib.c b/src/stdlib.c new file mode 100644 index 0000000..9a9425f --- /dev/null +++ b/src/stdlib.c @@ -0,0 +1,7 @@ +#include "stdlib.h" + +char *itoa( int v, char *s, int base ) +{ + //~ *s = '\0'; + return s; +} diff --git a/src/stdlib.h b/src/stdlib.h new file mode 100644 index 0000000..fc6e248 --- /dev/null +++ b/src/stdlib.h @@ -0,0 +1,6 @@ +#ifndef STDLIB_H +#define STDLIB_H + +char *itoa( int v, char *s, int base ); + +#endif /* STDLIB_H */ diff --git a/src/string.c b/src/string.c index 6aa46ef..9be5e43 100644 --- a/src/string.c +++ b/src/string.c @@ -40,3 +40,33 @@ size_t strlen( const char *s ) return len; } + +int strcmp( const char *s1, const char *s2 ) +{ + while( *s1 && *s2 && *s1 == *s2 ) { + s1++; + s2++; + } + + return *s1 - *s2; +} + +size_t strlcpy( char *d, const char *s, size_t n ) +{ + size_t len = 0; + + while( len < n && s[len] ) { + d[len] = s[len]; + len++; + } + + while( s[len] ) { + len++; + } + + if( len >= n ) { + d[n-1] = '\0'; + } + + return len; +} diff --git a/src/string.h b/src/string.h index 5efd35a..c3e3145 100644 --- a/src/string.h +++ b/src/string.h @@ -6,5 +6,7 @@ void *memset( void *s, int c, size_t n ); void *memmove( void *d, const void *s, size_t n ); size_t strlen( const char *s ); +int strcmp( const char *s1, const char *s2 ); +size_t strlcpy( char *d, const char *s, size_t n ); #endif /* STRING_H */ diff --git a/src/vga.c b/src/vga.c index 92114d3..0c344f7 100644 --- a/src/vga.c +++ b/src/vga.c @@ -3,6 +3,7 @@ #include #include "string.h" +#include "stdlib.h" static bool params_ok( vga_t *vga, const int x, const int y ); static int calculate_offset( vga_t *vga ); @@ -17,6 +18,10 @@ void vga_init( vga_t *vga ) vga->res_y = VGA_DEFAULT_RES_Y; vga->color = VGA_COLOR_DARK_GREY; vga->background_color = VGA_COLOR_BLACK; + + // set up ports + port8_init( &vga->crtc_index_port, 0x3d4 ); + port8_init( &vga->crtc_data_port, 0x3d5 ); // TODO: get current position from VGA hardware vga_set_cursor_from_hardware( vga ); @@ -41,12 +46,25 @@ void vga_set_cursor( vga_t *vga, const int x, const int y ) vga->cursor_x = x; vga->cursor_y = y; + + // TODO: have a silent mode where we don't update the cursor + vga_set_cursor_on_hardware( vga ); } void vga_set_cursor_from_hardware( vga_t *vga ) { } +void vga_set_cursor_on_hardware( vga_t *vga ) +{ + uint16_t hw_cursor_pos = vga->cursor_x + vga->cursor_y * vga->res_x; + + port8_write( &vga->crtc_index_port, 15 ); + port8_write( &vga->crtc_index_port, hw_cursor_pos & 0xff ); + port8_write( &vga->crtc_index_port, 14 ); + port8_write( &vga->crtc_index_port, hw_cursor_pos >> 8 ); +} + int vga_get_cursor_x( vga_t *vga ) { return vga->cursor_x; @@ -142,6 +160,16 @@ void vga_put_string( vga_t *vga, const char *s ) } } +void vga_put_hex( vga_t *vga, const uint32_t v ) +{ + char buf[9]; + + strlcpy( buf, "0x", 9 ); + vga_put_string( vga, (const char *)buf ); + itoa( v, (char *)buf, 16 ); + vga_put_string( vga, (const char *)buf ); +} + void vga_put_newline( vga_t *vga ) { vga->cursor_x = 0; diff --git a/src/vga.h b/src/vga.h index 70f9d53..aabffab 100644 --- a/src/vga.h +++ b/src/vga.h @@ -1,6 +1,8 @@ #ifndef VGA_H #define VGA_H +#include "port.h" + enum { VGA_DEFAULT_RES_X = 80, VGA_DEFAULT_RES_Y = 25 @@ -32,12 +34,15 @@ typedef struct vga_t { int cursor_y; // current cursor position Y vga_color_t color; vga_color_t background_color; + port8_t crtc_index_port; + port8_t crtc_data_port; } vga_t; void vga_init( vga_t *vga ); void vga_clear_screen( vga_t *vga ); void vga_set_cursor( vga_t *vga, const int x, const int y ); void vga_set_cursor_from_hardware( vga_t *vga ); +void vga_set_cursor_on_hardware( vga_t *vga ); int vga_get_cursor_x( vga_t *vga ); int vga_get_cursor_y( vga_t *vga ); void vga_set_color( vga_t *vga, const vga_color_t color ); @@ -46,6 +51,7 @@ void vga_put_char_at( vga_t *vga, const int x, const int y, const char c ); void vga_put_string_at( vga_t *vga, const int x, const int y, const char *s ); void vga_put_char( vga_t *vga, const char c ); void vga_put_string( vga_t *vga, const char *s ); +void vga_put_hex( vga_t *vga, const uint32_t v ); void vga_put_newline( vga_t *vga ); #endif /* VGA_H */ diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..af20182 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,23 @@ +CC := gcc +CFLAGS := -std=c99 -m32 -ffreestanding -O0 -g -Wall -Werror +INCLUDES = -I../src +LD := ld + +all: test + +test_strlcpy: test_strlcpy.o + +test_strlcpy: test_strlcpy.o ../src/string.o + $(CC) -o test_strlcpy test_strlcpy.o ../src/string.o + +test_strlcpy.o: test_strlcpy.c + $(CC) $(CFLAGS) $(INCLUDES) -c -o test_strlcpy.o test_strlcpy.c + +../src/string.o: ../src/string.c + $(CC) $(CFLAGS) -c -o ../src/string.o ../src/string.c + +test: test_strlcpy + ./test_strlcpy + +clean: + -rm -f test_strlcpy *.o diff --git a/tests/test_strlcpy.c b/tests/test_strlcpy.c new file mode 100644 index 0000000..a23a5bc --- /dev/null +++ b/tests/test_strlcpy.c @@ -0,0 +1,15 @@ +#include "string.h" + +int main( void ) +{ + char *s = "test_string"; + char d[8]; + size_t n; + + // copy into too small string + n = strlcpy( d, s, 4 ); + if( n != 11 ) return 1; + if( strcmp( d, "tes" ) ) return 1; + + return 0; +} -- cgit v1.2.3-54-g00ecf