Page 1 of 1
Writing to video memory, is ignored.
Posted: Tue Sep 27, 2011 6:56 am
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.
Re: Writing to video memory, is ignored.
Posted: Tue Sep 27, 2011 7:23 am
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.
Re: Writing to video memory, is ignored.
Posted: Tue Sep 27, 2011 8:59 am
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?
Re: Writing to video memory, is ignored.
Posted: Tue Sep 27, 2011 9:11 am
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
Re: Writing to video memory, is ignored.
Posted: Tue Sep 27, 2011 9:22 am
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.
Re: Writing to video memory, is ignored.
Posted: Tue Sep 27, 2011 9:24 am
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!
Re: Writing to video memory, is ignored.
Posted: Tue Sep 27, 2011 9:46 am
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.
Re: Writing to video memory, is ignored.
Posted: Sat Nov 26, 2011 4:03 am
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.
Re: Writing to video memory, is ignored.
Posted: Sat Nov 26, 2011 3:19 pm
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.