Writing to video memory, is ignored.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
skeen
Member
Member
Posts: 59
Joined: Tue Sep 27, 2011 6:45 am
Location: Denmark

Writing to video memory, is ignored.

Post by skeen »

Hi everybody.

I just started playing around with OS development, however I can't seem to get the writing to video memory to work at all; currently I'm booting up in some asm (grub) and somewhat quickly turning control over to C; where I'm then trying to write to the video memory, alike:

Code: Select all

unsigned char *videoram = (unsigned char *) 0xb8000;
videoram[0] = 65; /* character 'A' */
videoram[1] = 0x07; /* light grey (7) on black (0). */
However nothing ever shows up on screen, I have confirmed that the C function is indeed called, and I am able to write to the screen from my assembly using;

Code: Select all

    MOV AL, 65
    MOV AH, 0x0e
    MOV BH, 0x00
    MOV BL, 0x07
    INT 0x10
I've been searching around the web, however with no luck really, I can't seem to figure why it wont work :s, also in 'Bran's Kernel Development tutorial' he makes use of;

Code: Select all

void outportb (unsigned short _port, unsigned char _data)
{
    __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
Is this the way to go, or should one prefer calling the '0x10' interrupt instead?

I'm compiling elf64 (x86-64) using nasm 2.10rc8 for asm, and gcc 4.6.1 cross-compiled for c.
I'm running the linked binary in VMWare's Player, booting from a floppy with my code in bootsector.

I've gotten the idea that the 64 bit code might be the source of the issue, no? - something about far pointers?
Also I do think I read something, about issues with laptops, about some interrupts? - and I'm currently developing on a laptop.

EDIT: Added the laptop thing.
// Skeen
// Developing a yet unnamed microkernel in C++14.
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: Writing to video memory, is ignored.

Post by NickJohnson »

So, which architecture are you compiling the C code for? If you still have BIOS access, that would imply you're in real mode; neither 32 nor 64 bit C code will work there. If you switch to protected mode (and not long mode) before calling the C code, you still need it to be 32 bit.

You also shouldn't need to use any I/O ports (i.e. need outportb() and friends to be accessible from C) to write to the VGA text console, although you will later for other stuff.
User avatar
skeen
Member
Member
Posts: 59
Joined: Tue Sep 27, 2011 6:45 am
Location: Denmark

Re: Writing to video memory, is ignored.

Post by skeen »

NickJohnson wrote:So, which architecture are you compiling the C code for?

Code: Select all

$ file main.o
main.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
The code is solely to be run on 64bit machines.
NickJohnson wrote:If you still have BIOS access, that would imply you're in real mode
I haven't looked into protected mode yet. - Wanted to be able to print to ease debugging/ect.
NickJohnson wrote:; neither 32 nor 64 bit C code will work there.
Just curious why not? - and will 16bit c code work?
NickJohnson wrote: If you switch to protected mode (and not long mode) before calling the C code, you still need it to be 32 bit.
What's long mode, and how is it different then protected mode? - Also why doesn't it support 64bit?
NickJohnson wrote: You also shouldn't need to use any I/O ports (i.e. need outportb() and friends to be accessible from C) to write to the VGA text console, although you will later for other stuff.
How would one write a VGA text console then? - and when will I need it then?

You can answer with links :) - if you got any.
Also how will I debug print in my kernel then?
// Skeen
// Developing a yet unnamed microkernel in C++14.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Writing to video memory, is ignored.

Post by Solar »

skeen wrote:
NickJohnson wrote:If you still have BIOS access, that would imply you're in real mode
I haven't looked into protected mode yet. - Wanted to be able to print to ease debugging/ect.
NickJohnson wrote:; neither 32 nor 64 bit C code will work there.
Just curious why not? - and will 16bit c code work?
NickJohnson wrote: If you switch to protected mode (and not long mode) before calling the C code, you still need it to be 32 bit.
What's long mode, and how is it different then protected mode? - Also why doesn't it support 64bit?
Please return to square one. Before you want debug output, you should know the very basics of the architecture you will be working on. The point to start is not a tutorial on "booting up in some asm (grub) and somewhat quickly turning control over to C", it's the Intel manuals. You will founder.

Real Mode

Protected Mode

Long Mode

But even before that:

Resources

and

Beginner Mistakes
Every good solution is obvious once you've found it.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Writing to video memory, is ignored.

Post by Combuster »

The modern processor has five(!) functionally distinct operating modes. Code written for one does not generally work in the other because of operand encoding and because of environment changes.

The BIOS can only be accessed from 16-bit real mode (or an emulation thereof). The fact that the int 0x10 does its job is because it is operating in real mode. 64-bit code has a different encoding than 16-bit code, and will therefore not execute as written when run in that way. The 0x000b8000 will for example get interpreted as 0x8000, the register names will change, and the resulting size differences will add new instructions. Whatever happens, a write will never happen to video ram.

In other words, you lack a lot of basic processor knowledge. Posting all the relevant links would take me more time finding them compared to you reading the entire CPU category of the wiki. And you won't be able to avoid getting a copy of the Intel software developer manuals and reading the first 8 chapters of volume 3. Since everything you should be aware of takes quite a few hours of reading, you might want to iterate through that and then come back with any questions you may still have pending afterwards.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
skeen
Member
Member
Posts: 59
Joined: Tue Sep 27, 2011 6:45 am
Location: Denmark

Re: Writing to video memory, is ignored.

Post by skeen »

Combuster wrote:You might want to iterate through that and then come back with any questions you may still have pending afterwards.
Roger that!
// Skeen
// Developing a yet unnamed microkernel in C++14.
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Re: Writing to video memory, is ignored.

Post by Ready4Dis »

If you're trying to access 0xb8000 in real mode, you need to use a segment offset pair:

Eg:

Code: Select all

mov ds, 0xb000
mov bx, 0x8000
mov [bx], 0x0e
mov [bx+1], 'a'
Don't forget to set DS back to whatever mode you need, or user another segment register (override the default)

Code: Select all

mov es:[bx], 0x0e
mov es:[bx+1], 'a'
In real mode, it takes the segment (ds) and shifts it left by 4.. then adds the offset to get your final address...
so, 0xb000 shifted by 4 = 0xb0000, adding bx (0x8000) results in 0xb8000. In protected mode, it's linear addressing (although, you can still use segmentation, but it's suggested that you don't), so you would setup your GDT, and just reference 0xb8000 directly.
3d7
Posts: 1
Joined: Sat Nov 26, 2011 3:58 am

Re: Writing to video memory, is ignored.

Post by 3d7 »

Code: Select all

mov ax,0xB000
mov ds,ax
mov byte[ds:0x8000],0x43
mov byte[ds:0x8001],0x1F
mov byte[ds:0x8002],0x42
mov byte[ds:0x8003],0x1F
mov byte[ds:0x8004],0x41
mov byte[ds:0x8005],0x1F
A "CBA" will appear on the top left corner of Bochs.
Tosi
Member
Member
Posts: 255
Joined: Tue Jun 15, 2010 9:27 am
Location: Flyover State, United States
Contact:

Re: Writing to video memory, is ignored.

Post by Tosi »

You are compiling for 64-bit code, but when your kernel is first loaded, it is in 32-bit protected mode. Add a 32-bit "stub" to the beginning of your kernel (create a special segment and use BITS 32 or a similar assembler directive to compile it) to set up long mode and then jump into the kernel proper from there. While I don't dabble in x86_64 much, I do know that you need to set up at least a GDT and paging, and maybe an IDT before entering long mode. If you want to make sure writing to video memory works, try writing to 0xB8000 while still in protected mode from a 32-bit segment.
Post Reply