My VGA driver prints garbage on screen
-
- Posts: 13
- Joined: Sun Jun 14, 2020 5:15 pm
- Libera.chat IRC: mrfrust
My VGA driver prints garbage on screen
Hello, i'm new at osdev forum, i am following a guide to make my own os, and i've reached the part where i need to write a vga driver, the driver that i've copied from the book displays this at bochs:
, someone could help me? Thanks in advance!
Re: My VGA driver prints garbage on screen
You've provided far too little information. Can you provide your code and the guide your following?
-
- Posts: 13
- Joined: Sun Jun 14, 2020 5:15 pm
- Libera.chat IRC: mrfrust
Re: My VGA driver prints garbage on screen
I'm using os-dev along with this github repository (the github repository is based on the book) https://github.com/cfenollosa/os-tutorial
EDIT: I realized that when i change the order of the files to link or change the "-Ttext 0x0" or it prints nothing, or it prints different garbage. "ld -o kernel\kernel.out -Ttext 0x0 kernel\kernel.o kernel\drivers\screen.o kernel\util.o kernel\drivers\ports.o"
Driver code:
kernel code:
EDIT: I realized that when i change the order of the files to link or change the "-Ttext 0x0" or it prints nothing, or it prints different garbage. "ld -o kernel\kernel.out -Ttext 0x0 kernel\kernel.o kernel\drivers\screen.o kernel\util.o kernel\drivers\ports.o"
Driver code:
Code: Select all
#include "screen.h"
#include "ports.h"
#include "util.h"
/* Declaration of private functions */
int get_cursor_offset();
void set_cursor_offset(int offset);
int print_char(char c, int col, int row, char attr);
int get_offset(int col, int row);
int get_offset_row(int offset);
int get_offset_col(int offset);
/**********************************************************
* Public Kernel API functions *
**********************************************************/
/**
* Print a message on the specified location
* If col, row, are negative, we will use the current offset
*/
void kprint_at(char *message, int col, int row) {
/* Set cursor if col/row are negative */
int offset;
if (col >= 0 && row >= 0)
offset = get_offset(col, row);
else {
offset = get_cursor_offset();
row = get_offset_row(offset);
col = get_offset_col(offset);
}
/* Loop through message and print it */
int i = 0;
while (message[i] != 0) {
offset = print_char(message[i++], col, row, WHITE_ON_BLACK);
/* Compute row/col for next iteration */
row = get_offset_row(offset);
col = get_offset_col(offset);
}
}
void kprint(char *message) {
kprint_at(message, -1, -1);
}
/**********************************************************
* Private kernel functions *
**********************************************************/
/**
* Innermost print function for our kernel, directly accesses the video memory
*
* If 'col' and 'row' are negative, we will print at current cursor location
* If 'attr' is zero it will use 'white on black' as default
* Returns the offset of the next character
* Sets the video cursor to the returned offset
*/
int print_char(char c, int col, int row, char attr) {
unsigned char *vidmem = (unsigned char*) VIDEO_ADDRESS;
if (!attr) attr = WHITE_ON_BLACK;
/* Error control: print a red 'E' if the coords aren't right */
if (col >= MAX_COLS || row >= MAX_ROWS) {
vidmem[2*(MAX_COLS)*(MAX_ROWS)-2] = 'E';
vidmem[2*(MAX_COLS)*(MAX_ROWS)-1] = RED_ON_WHITE;
return get_offset(col, row);
}
int offset;
if (col >= 0 && row >= 0) offset = get_offset(col, row);
else offset = get_cursor_offset();
if (c == '\n') {
row = get_offset_row(offset);
offset = get_offset(0, row+1);
} else {
vidmem[offset] = c;
vidmem[offset+1] = attr;
offset += 2;
}
/* Check if the offset is over screen size and scroll */
if (offset >= MAX_ROWS * MAX_COLS * 2) {
int i;
for (i = 1; i < MAX_ROWS; i++)
memory_copy(get_offset(0, i) + VIDEO_ADDRESS,
get_offset(0, i-1) + VIDEO_ADDRESS,
MAX_COLS * 2);
/* Blank last line */
char *last_line = get_offset(0, MAX_ROWS-1) + VIDEO_ADDRESS;
for (i = 0; i < MAX_COLS * 2; i++) last_line[i] = 0;
offset -= 2 * MAX_COLS;
}
set_cursor_offset(offset);
return offset;
}
int get_cursor_offset() {
/* Use the VGA ports to get the current cursor position
* 1. Ask for high byte of the cursor offset (data 14)
* 2. Ask for low byte (data 15)
*/
port_byte_out(REG_SCREEN_CTRL, 14);
int offset = port_byte_in(REG_SCREEN_DATA) << 8; /* High byte: << 8 */
port_byte_out(REG_SCREEN_CTRL, 15);
offset += port_byte_in(REG_SCREEN_DATA);
return offset * 2; /* Position * size of character cell */
}
void set_cursor_offset(int offset) {
/* Similar to get_cursor_offset, but instead of reading we write data */
offset /= 2;
port_byte_out(REG_SCREEN_CTRL, 14);
port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset >> 8));
port_byte_out(REG_SCREEN_CTRL, 15);
port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset & 0xff));
}
void clear_screen() {
int screen_size = MAX_COLS * MAX_ROWS;
int i;
char *screen = VIDEO_ADDRESS;
for (i = 0; i < screen_size; i++) {
screen[i*2] = ' ';
screen[i*2+1] = WHITE_ON_BLACK;
}
set_cursor_offset(get_offset(0, 0));
}
int get_offset(int col, int row) { return 2 * (row * MAX_COLS + col); }
int get_offset_row(int offset) { return offset / (2 * MAX_COLS); }
int get_offset_col(int offset) { return (offset - (get_offset_row(offset)*2*MAX_COLS))/2; }
Code: Select all
#include "drivers\screen.h"
#include "drivers\util.h"
void _main() {
clear_screen();
kprint_at("Tetsing", 5, 0);
}
-
- Member
- Posts: 5829
- Joined: Mon Mar 25, 2013 7:01 pm
Re: My VGA driver prints garbage on screen
Where is your kernel's entry point in the files you're linking together? Where is your kernel's entry point when it's loaded in memory by your bootloader?mrfrustrationman wrote:"ld -o kernel\kernel.out -Ttext 0x0 kernel\kernel.o kernel\drivers\screen.o kernel\util.o kernel\drivers\ports.o"
-
- Posts: 13
- Joined: Sun Jun 14, 2020 5:15 pm
- Libera.chat IRC: mrfrust
Re: My VGA driver prints garbage on screen
bootloader code:Octocontrabass wrote:Where is your kernel's entry point in the files you're linking together? Where is your kernel's entry point when it's loaded in memory by your bootloader?mrfrustrationman wrote:"ld -o kernel\kernel.out -Ttext 0x0 kernel\kernel.o kernel\drivers\screen.o kernel\util.o kernel\drivers\ports.o"
Code: Select all
[org 0x7c00]
KERNEL_OFFSET equ 0x1000
mov [BOOT_DRIVE], dl
mov bp, 0x9000
mov sp, bp
mov bx, MSG_REAL_MODE
call print
call print_nl
call load_kernel
call switch_to_pm
jmp $
%include "boot\print_string.asm"
%include "boot\print_string_hex.asm"
%include "boot\read_disk.asm"
%include "boot\gdt.asm"
%include "boot\32bit-print.asm"
%include "boot\32bit-switch.asm"
[bits 16]
load_kernel:
mov bx, MSG_LOAD_KERNEL
call print
call print_nl
mov bx, KERNEL_OFFSET
mov dh, 16
mov dl, [BOOT_DRIVE]
call disk_load
ret
[bits 32]
BEGIN_PM:
mov ebx, MSG_PROT_MODE
call print_string_pm
call KERNEL_OFFSET
jmp $
BOOT_DRIVE db 0
MSG_REAL_MODE db "Starting...", 0
MSG_PROT_MODE db "...", 0
MSG_LOAD_KERNEL db "Loading operating system...", 0
; padding
times 510 - ($-$$) db 0
dw 0xaa55
Code: Select all
[bits 32]
[extern __main] ; Define calling point. Must have same name as kernel.c 'main' function
call __main ; Calls the C function. The linker will know where it is placed in memory
jmp $
-
- Member
- Posts: 5829
- Joined: Mon Mar 25, 2013 7:01 pm
Re: My VGA driver prints garbage on screen
Where is your kernel entry point in the files you're linking together? You can't link source code!mrfrustrationman wrote:"ld -o kernel\kernel.out -Ttext 0x0 kernel\kernel.o kernel\drivers\screen.o kernel\util.o kernel\drivers\ports.o"
According to your bootloader code, your kernel's entry point in memory is 0x1000. How are you telling the linker about this?
-
- Posts: 13
- Joined: Sun Jun 14, 2020 5:15 pm
- Libera.chat IRC: mrfrust
Re: My VGA driver prints garbage on screen
what do you mean by tell the linker? like "-Ttext 0x1000"? Do you want to see my build.bat file?Octocontrabass wrote:Where is your kernel entry point in the files you're linking together? You can't link source code!mrfrustrationman wrote:"ld -o kernel\kernel.out -Ttext 0x0 kernel\kernel.o kernel\drivers\screen.o kernel\util.o kernel\drivers\ports.o"
According to your bootloader code, your kernel's entry point in memory is 0x1000. How are you telling the linker about this?
-
- Member
- Posts: 5829
- Joined: Mon Mar 25, 2013 7:01 pm
Re: My VGA driver prints garbage on screen
Yes. That tells the linker where your kernel will be loaded in memory.mrfrustrationman wrote:what do you mean by tell the linker? like "-Ttext 0x1000"?
-
- Posts: 13
- Joined: Sun Jun 14, 2020 5:15 pm
- Libera.chat IRC: mrfrust
Re: My VGA driver prints garbage on screen
My build.bat
Code: Select all
@echo off
cls
color a
echo Compiling...
gcc -ffreestanding -c kernel\kernel.c -o kernel\kernel.o
gcc -ffreestanding -c kernel\drivers\ports.c -o kernel\drivers\ports.o
gcc -ffreestanding -c kernel\drivers\screen.c -o kernel\drivers\screen.o
gcc -ffreestanding -c kernel\drivers\util.c -o kernel\util.o
timeout 2 >nul
echo Kernel dump:
objdump -d kernel\kernel.o
timeout 1 >nul
echo nasm:
nasm -f elf boot\kernel_entry.asm -o boot\kernel_entry.o
echo ld:
ld -o kernel\kernel.out -Ttext 0x0 kernel\kernel.o kernel\drivers\screen.o kernel\util.o kernel\drivers\ports.o
echo objcopy:
objcopy -O binary -j .text kernel\kernel.out kernel\kernel.bin
echo nasm:
nasm boot\bootloader.asm -f bin -o boot\bootloader.bin
echo cat:
cat boot\bootloader.bin kernel\kernel.bin > os-image.bin
pause >nul
::qemu-system-x86_64 os-image.bin
call run.bat
-
- Member
- Posts: 5829
- Joined: Mon Mar 25, 2013 7:01 pm
Re: My VGA driver prints garbage on screen
So your kernel entry point is located in kernel_entry.asm, which is assembled to kernel_entry.o and then... not linked? I'm surprised your kernel works at all without the entry point code, it's pretty important.
And in the batch file, you're still telling the linker that your kernel will be loaded at 0x0 when it really will be loaded at 0x1000.
And in the batch file, you're still telling the linker that your kernel will be loaded at 0x0 when it really will be loaded at 0x1000.
-
- Posts: 13
- Joined: Sun Jun 14, 2020 5:15 pm
- Libera.chat IRC: mrfrust
Re: My VGA driver prints garbage on screen
Omg, i didn't see it! I've already changed the arg, let me test it... Yeah, now it doesn't print anythingOctocontrabass wrote:So your kernel entry point is located in kernel_entry.asm, which is assembled to kernel_entry.o and then... not linked? I'm surprised your kernel works at all without the entry point code, it's pretty important.
And in the batch file, you're still telling the linker that your kernel will be loaded at 0x0 when it really will be loaded at 0x1000.
-
- Posts: 13
- Joined: Sun Jun 14, 2020 5:15 pm
- Libera.chat IRC: mrfrust
Re: My VGA driver prints garbage on screen
My updated build.bat:
Code: Select all
@echo off
cls
color a
echo Compiling...
gcc -ffreestanding -c kernel\kernel.c -o kernel\kernel.o
gcc -ffreestanding -c kernel\drivers\ports.c -o kernel\drivers\ports.o
gcc -ffreestanding -c kernel\drivers\screen.c -o kernel\drivers\screen.o
gcc -ffreestanding -c kernel\drivers\util.c -o kernel\util.o
timeout 2 >nul
echo Kernel dump:
objdump -d kernel\kernel.o
timeout 1 >nul
echo nasm:
nasm -f elf boot\kernel_entry.asm -o boot\kernel_entry.o
echo ld:
ld -o kernel\kernel.out -Ttext 0x1000 kernel\kernel.o boot\kernel_entry.o kernel\drivers\ports.o kernel\drivers\screen.o kernel\util.o
echo objcopy:
objcopy -O binary -j .text kernel\kernel.out kernel\kernel.bin
echo nasm:
nasm boot\bootloader.asm -f bin -o boot\bootloader.bin
echo cat:
cat boot\bootloader.bin kernel\kernel.bin > os-image.bin
pause >nul
::qemu-system-x86_64 os-image.bin
call run.bat
-
- Member
- Posts: 829
- Joined: Fri Aug 26, 2016 1:41 pm
- Libera.chat IRC: mpetch
Re: My VGA driver prints garbage on screen
As I mentioned in a comment on Stackoverflow you should put your own copy of the project with all your changes (batch files included). However the fact you are using `-Ttext 0x0` is a problem given that the tutorial you are using has a bootloader that loads the kernel to 0x1000. It should be `-Ttext 0x1000` . This could explain why strings print gibberish. Likely your code is reading the string from somewhere in the real mode IVT rather than where your kernel was actually loaded.
I will assume you are using powershell since you are using the `cat` command.
I will assume you are using powershell since you are using the `cat` command.
-
- Posts: 13
- Joined: Sun Jun 14, 2020 5:15 pm
- Libera.chat IRC: mrfrust
Re: My VGA driver prints garbage on screen
That's a interesting history, I've downloaded GnuWin and used it's cat commandMichaelPetch wrote:As I mentioned in a comment on Stackoverflow you should put your own copy of the project with all your changes (batch files included). However the fact you are using `-Ttext 0x0` is a problem given that the tutorial you are using has a bootloader that loads the kernel to 0x1000. It should be `-Ttext 0x1000` . This could explain why strings print gibberish. Likely your code is reading the string from somewhere in the real mode IVT rather than where your kernel was actually loaded.
I will assume you are using powershell since you are using the `cat` command.
-
- Member
- Posts: 5829
- Joined: Mon Mar 25, 2013 7:01 pm
Re: My VGA driver prints garbage on screen
Code: Select all
objcopy -O binary -j .text kernel\kernel.out kernel\kernel.bin