Page 1 of 1
Confused about video memory
Posted: Sat Mar 13, 2010 10:34 pm
by GenHornet18
Alright so I decided to start writing the kernel of my OS and to start off I tried to simply output one character by writing to video memory, so I turned to your handy OSDev wiki and I got mixed results. If I call SetColor(...) and input 7 and 0 it prints the character correctly, but I wanted to have a default attribute (so I wouldn't have to call SetColor(...) so I just simply initialized it to 0x07 and this is where the problem occurs. The character doesn't show on screen so I'm assuming the initialization isn't working. I only modified the wiki example a bit which in my head seems to make sense and yet and it doesn't work. Can anyone help me understand why this doesn't work?
Code: Select all
unsigned int CSRX = 0;
unsigned int CSRY = 0;
unsigned short Attrib = 0x07;
void Put(unsigned char c)
{
volatile unsigned short *where;
where = (unsigned short *)0xB8000 + (CSRY * 80 + CSRX);
*where = c | (Attrib << 8);
}
void SetColor(unsigned char Fore, unsigned char Back)
{
Attrib = (Back << 4) | (Fore & 0x0F);
}
void main()
{
Put('R');
for(;;);
}
Re: Confused about video memory
Posted: Sun Mar 14, 2010 3:40 am
by bitshifter
character before attribute...
Code: Select all
*(unsigned char*)0xB8000 = 'R';
*(unsigned char*)0xB8001 = 0x07;
Re: Confused about video memory
Posted: Sun Mar 14, 2010 4:40 am
by Gigasoft
It should work, so this sounds like a linking or loading problem. The intial value of Attrib isn't stored where the program expects it to be.
Re: Confused about video memory
Posted: Sun Mar 14, 2010 10:46 am
by GenHornet18
Thanks I did have them mixed up, character does come before attribute.
Re: Confused about video memory
Posted: Mon Mar 15, 2010 7:38 am
by GenHornet18
Alright new problem,
Everything seems to print and is programmed correctly yet the StrLen function is reporting the null character too soon in the string (it only seems to print the first 7 characters of the string).
Code: Select all
unsigned int StrLen(unsigned const char *text)
{
unsigned int count = 0;
while(*text != '\0')
{
count++;
text++;
}
return count;
}
and this function is called from a separate source file which sends the address of the first character.
Code: Select all
void TextOut(unsigned const char *text)
{
int count;
for(count = 0; count <= StrLen(text); count++)
{
Put(*text);
text++;
}
}
and just in case the linker script
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x1000;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
*(.rodata*)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .;
}
I assumed gcc automatically puts in the terminating null character at the end of the string, yet my StrLen function reports it too soon. The programming seems right, am I missing something or is this another error related to linking/compiling etc. ?
Re: Confused about video memory
Posted: Mon Mar 15, 2010 8:11 am
by Gigasoft
That's because you're incrementing text. After you're halfways through the string, StrLen(text) will equal count.
Re: Confused about video memory
Posted: Mon Mar 15, 2010 8:52 am
by GenHornet18
Right on target, thanks I just switched up my IDE and picking out errors is harder.
-Hornet
Re: Confused about video memory
Posted: Mon Mar 15, 2010 6:34 pm
by bitshifter
You might want to consider a bit of pointer manipulation for such a task.
The compiler will generate much faster and smaller code with this method.
Code: Select all
unsigned int strlen(const char *str)
{
const char *ptr = str;
while(*ptr++)
{
// empty body...
}
return ptr - str - 1;
}
Or even like this...
Code: Select all
unsigned int strlen(const char *str)
{
const char *ptr = str;
while(*ptr)
{
ptr++;
}
return ptr - str;
}
Have fun
Re: Confused about video memory
Posted: Mon Mar 22, 2010 6:32 pm
by GenHornet18
Thanks for the help, but this error seems to have resurfaced (apparently I didn't fix it the first time). Everything seems to have gone well when I used my kernel at 1000h(physical) but since I decided to relocate to 10000h(physical) this error came back up. For some reason every time this code is compiled it refuses to initialize my 'Attrib' variable. My linker script seems to work fine (strings are in the right location, kernel is where it's supposed to be, etc.) but yet this code continues to be defiant. I'm using gcc with the following paremeters (-Wall -ffreestanding -finline-functions -nostdinc -I./include -c main.c -o main.o) would any of this cause the global variable 'Attrib' not to be initialized (directly after declaration)?
same code as before:
Code: Select all
unsigned int CSRX = 0;
unsigned int CSRY = 0;
unsigned short Attrib = 0x07;
void Put(unsigned char c)
{
volatile unsigned short *where;
where = (unsigned short *)0xB8000 + (CSRY * 80 + CSRX);
*where = c | (Attrib << 8);
}
void SetColor(unsigned char Fore, unsigned char Back)
{
Attrib = (Back << 4) | (Fore & 0x0F);
}
void main()
{
Put('R');
for(;;);
}
Thanks again, hopefully this error will stay down this time