From 1ebfde4d30acd27d1b3817f33bf9cf76655e3183 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 14 May 2017 17:06:11 +0200 Subject: added a simple serial console output to qemu run mode reading and writing the VGA cursor correctly on hardware --- doc/LINKS.TODO | 4 ++++ src/Makefile | 18 ++++++++++------- src/README | 22 +++++++++++++-------- src/kernel.c | 8 +++++++- src/port.asm | 33 +++++++------------------------ src/serial.c | 44 +++++++++++++++++++++++++++++++++++++++++ src/serial.h | 14 +++++++++++++ src/vga.c | 62 +++++++++++++++++++++++++++------------------------------- src/vga.h | 1 + 9 files changed, 131 insertions(+), 75 deletions(-) create mode 100644 src/serial.c create mode 100644 src/serial.h diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO index f7a602e..a65d4ea 100644 --- a/doc/LINKS.TODO +++ b/doc/LINKS.TODO @@ -8,3 +8,7 @@ https://github.com/FlingOS/FlingOS http://repo.or.cz/w/lightOS.git https://littleosbook.github.io/ http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html + +http://x86.renejeschke.de/html/file_module_x86_id_139.html +http://retired.beyondlogic.org/serial/serial1.htm +https://pdos.csail.mit.edu/6.828/2014/reference.html diff --git a/src/Makefile b/src/Makefile index e0dfedb..fed5c71 100644 --- a/src/Makefile +++ b/src/Makefile @@ -18,9 +18,9 @@ image.bin: boot.bin kernel.bin magic.bin boot.bin: boot.asm gdt.asm stage1_functions.asm stage2_functions.asm switch_mode.asm nasm boot.asm -f bin -o boot.bin -kernel.bin: kernel.o vga.o port.o port_asm.o string.o stdlib.o +kernel.bin: kernel.o vga.o serial.o port.o port_asm.o string.o stdlib.o $(LD) -o kernel.bin -N -n -Ttext 0x8400 --oformat binary \ - kernel.o vga.o port.o port_asm.o string.o stdlib.o + kernel.o vga.o serial.o port.o port_asm.o string.o stdlib.o magic.bin: magic.asm nasm magic.asm -f bin -o magic.bin @@ -28,26 +28,30 @@ magic.bin: magic.asm kernel.o: kernel.c $(CC) $(CFLAGS) -c -o kernel.o kernel.c -port.o: port.c +port.o: port.c port.h $(CC) $(CFLAGS) -c -o port.o port.c -vga.o: vga.c +vga.o: vga.c vga.h $(CC) $(CFLAGS) -c -o vga.o vga.c +serial.o: serial.c serial.h + $(CC) $(CFLAGS) -c -o serial.o serial.c + port_asm.o: port.asm nasm port.asm -f elf32 -o port_asm.o -string.o: string.c +string.o: string.c string.h $(CC) $(CFLAGS) -c -o string.o string.c -stdlib.o: stdlib.c +stdlib.o: stdlib.c stdlib.h $(CC) $(CFLAGS) -c -o stdlib.o stdlib.c clean: -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" + qemu-system-i386 -m 32 -drive "file=image.bin,if=ide,format=raw" \ + -serial file:serial.log run-bochs: bochs -q -f bochs.config 'boot:floppy' 'floppya: 1_44=image.bin, status=inserted' diff --git a/src/README b/src/README index f22867b..f0081b7 100644 --- a/src/README +++ b/src/README @@ -1,12 +1,18 @@ -boot.asm - the main boot sector code using: -* gdt.asm - the early GDT -* stage1_functions.asm - real mode functions of the bootloader -* stage2_functions.asm - protected mode primitive VGA routines -* switch_mode.asm - early GTD loading and switching from real to protected mode -kernel.c - Kernel C entry point 'entry' +* boot.bin - boot sector (stage 1 and 2, total 2k), offset 0x7c00 + * boot.asm - the main boot sector code using: +* kernel.bin - linked kernel with fix start offset 0x8400 + * gdt.asm - the early GDT + * stage1_functions.asm - real mode functions of the bootloader + * stage2_functions.asm - protected mode primitive VGA routines + * switch_mode.asm - early GTD loading and switching from real to protected mode + * kernel.c - Kernel C entry point 'entry' +* magic.bin (512 bytes magic marker sector) + * magic.asm -utility routines +kernel utility routines * vga.c - VGA basic output routines for early kernel output +* port.c, port.asm - I/O ports -c library stub +C library routines * string.c +* stdlib.c diff --git a/src/kernel.c b/src/kernel.c index d5db426..61281e9 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,9 +1,15 @@ #include #include "vga.h" +#include "serial.h" void entry( void ) { + serial_t serial; + serial_init( &serial ); + serial_put_char( &serial, 'A' ); + serial_put_char( &serial, '\n' ); + vga_t vga; vga_init( &vga ); @@ -27,7 +33,7 @@ void entry( void ) } vga_put_char_at( &vga, x_pos, y_pos, '.' ); vga_put_newline( &vga ); - + //~ vga_set_color( &vga, VGA_COLOR_WHITE ); //~ vga_set_background_color( &vga, VGA_COLOR_RED ); //~ vga_clear_screen( &vga ); diff --git a/src/port.asm b/src/port.asm index c7a2b85..4f2b646 100644 --- a/src/port.asm +++ b/src/port.asm @@ -7,11 +7,10 @@ global port8_read port8_write: push ebp mov ebp, esp - mov edx, [ebp+16] - mov eax, (edx) -; mov eax, [epb+8] -; mov dx, [ebp+8] -; out ax, dl + mov ecx, [ebp+8] + mov edx, DWORD [ecx] + movzx ax, BYTE [ebp+12] + out dx, al leave ret @@ -19,26 +18,8 @@ port8_write: port8_read: push ebp mov ebp, esp - mov edx, [ebp+8] - mov eax, [edx] + mov ecx, DWORD [ebp+8] + mov edx, [ecx] + in al, dx leave ret - -;~ void port8_init( port8_t *port, uint16_t number ) - - -; __asm__ volatile("inb %1, %0" : "=a" (result) : "Nd" (_port)); - -;~ 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)); - -;~ { - ;~ return 0; -;~ } diff --git a/src/serial.c b/src/serial.c new file mode 100644 index 0000000..3ef1a43 --- /dev/null +++ b/src/serial.c @@ -0,0 +1,44 @@ +#include "serial.h" +#include "string.h" + +void serial_init( serial_t *serial ) +{ + memset( serial, 0, sizeof( serial_t ) ); + + port8_init( &serial->port_3F8, 0x3F8 ); + port8_init( &serial->port_3FD, 0x3FD ); +} + +void serial_put_char( serial_t *serial, const char c ) +{ + uint8_t status; + do { + status = port8_read( &serial->port_3FD ); + } while( ( status & 0x20 ) == 0 ); + + port8_write( &serial->port_3F8, c ); +} + + //~ outb(0x3FB, 0x83); /* DLAB = 1 */ + //~ outb(0x3F8, 0x0C); /* 9600 Baud */ + //~ outb(0x3F9, 0x00); + //~ outb(0x3FB, 0x03); /* DLAB = 0 */ + //~ outb(0x3F9, 0x00); /* keine Interrupts auslösen */ + //~ outb(0x3FA, 0x00); /* FIFOs deaktiviert (8250, 16450) */ + //~ outb(0x3FC, 0x00); /* Loopback deaktivieren, Aux1 & Aux2 deaktivieren */ + + //~ outb(0xe9, c); + //~ outb(0x3f8, c); + //~ while ((inb(0x3fd) & 0x20) == 0) asm("nop"); + +//~ int is_transmit_empty() { + //~ return inb(PORT + 5) & 0x20; +//~ } + +//~ void write_serial(char a) { + //~ while (is_transmit_empty() == 0); + + + //~ outb(PORT,a); +//~ } + diff --git a/src/serial.h b/src/serial.h new file mode 100644 index 0000000..f302b93 --- /dev/null +++ b/src/serial.h @@ -0,0 +1,14 @@ +#ifndef SERIAL_H +#define SERIAL_H + +#include "port.h" + +typedef struct serial_t { + port8_t port_3F8; + port8_t port_3FD; +} serial_t; + +void serial_init( serial_t *serial ); +void serial_put_char( serial_t *serial, const char c ); + +#endif // SERIAL_H diff --git a/src/vga.c b/src/vga.c index fd67552..daad532 100644 --- a/src/vga.c +++ b/src/vga.c @@ -19,12 +19,14 @@ void vga_init( vga_t *vga ) vga->color = VGA_COLOR_DARK_GREY; vga->background_color = VGA_COLOR_BLACK; - // set up ports + port8_init( &vga->crtc_misc_port, 0x3d2 ); + port8_write( &vga->crtc_misc_port, 1 ); + + // set up VGA 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 ); + vga_set_cursor_from_hardware( vga ); }; void vga_clear_screen( vga_t *vga ) @@ -52,36 +54,30 @@ void vga_set_cursor( vga_t *vga, const int x, const int y ) } void vga_set_cursor_from_hardware( vga_t *vga ) -{ - // value of port we want to see later in assembly - uint16_t n = vga->crtc_index_port.number; - vga_put_hex( vga, n ); - vga_put_newline( vga ); +{ + vga->cursor_x = 0; + vga->cursor_y = 0; + + uint16_t hw_cursor_pos; - // the address of the vga structure - uintptr_t uip = (uintptr_t)( (void *)vga ); - vga_put_hex( vga, uip ); - vga_put_newline( vga ); - - // the address of the port structure inside the vga structure - uintptr_t uip2 = (uintptr_t)( (void *)&vga->crtc_index_port ); - vga_put_hex( vga, uip2 ); - vga_put_newline( vga ); - - // the address of the number membger in the port structure inside the vga structure - // must be the same as uip2 by C99 - uintptr_t uip3 = (uintptr_t)( (void *)&vga->crtc_index_port.number ); - vga_put_hex( vga, uip3 ); - vga_put_newline( vga ); + port8_write( &vga->crtc_index_port, 14 ); + uint8_t data = port8_read( &(vga->crtc_data_port ) ); + hw_cursor_pos = data << 8; + + port8_write( &vga->crtc_index_port, 15 ); + data = port8_read( &(vga->crtc_data_port ) ); + + hw_cursor_pos |= data; - uint8_t data = port8_read( &(vga->crtc_index_port ) ); - vga_put_hex( vga, data ); - vga_put_newline( vga ); -//~ unsigned short offset; - //~ out(0x3D4, 14); - //~ offset = in(0x3D5) << 8; - //~ out(0x3D4, 15); - //~ offset |= in(0x3D5); + vga->cursor_x = hw_cursor_pos % vga->res_x; + vga->cursor_y = hw_cursor_pos / vga->res_x; + + // reset to sane values if we get funny values from the VGA card + if( vga->cursor_x < 0 || vga->cursor_x > vga->res_x || + vga->cursor_y < 0 || vga->cursor_y > vga->res_y ) { + vga->cursor_x = 0; + vga->cursor_y = 0; + } } void vga_set_cursor_on_hardware( vga_t *vga ) @@ -89,9 +85,9 @@ 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_data_port, hw_cursor_pos & 0xff ); port8_write( &vga->crtc_index_port, 14 ); - port8_write( &vga->crtc_index_port, hw_cursor_pos >> 8 ); + port8_write( &vga->crtc_data_port, hw_cursor_pos >> 8 ); } int vga_get_cursor_x( vga_t *vga ) diff --git a/src/vga.h b/src/vga.h index aabffab..3a91154 100644 --- a/src/vga.h +++ b/src/vga.h @@ -34,6 +34,7 @@ typedef struct vga_t { int cursor_y; // current cursor position Y vga_color_t color; vga_color_t background_color; + port8_t crtc_misc_port; port8_t crtc_index_port; port8_t crtc_data_port; } vga_t; -- cgit v1.2.3-54-g00ecf