Page 1 of 2
Understanding Bare Bones
Posted: Fri Feb 27, 2009 9:12 pm
by gsingh2011
For those of you who were helping me set up GCC on windows recently, I just wanted to say thanks for the help, but I switched to linux. It was just pissing me way to much.. Anyway, now that I know how to boot a basic floppy image, I'm trying to understand the code. First of all, I know what's all of this about a multiboot header in the bare bones tutorial loader.s? What is a multiboot header? Then there's the code:
Code: Select all
unsigned char *videoram = (unsigned char *) 0xb8000;
videoram[0] = 65; /* character 'A' */
videoram[1] = 0x07; /* forground, background color. */
Why 0xb8000? Can I display longer strings? What else can I do with this?
And is the linker script written in a certain language? Where can I learn more about how this works?
Re: Understanding Bare Bones
Posted: Fri Feb 27, 2009 9:21 pm
by piranha
0xb8000 is the standard memory position to write text to the screen. Its just a standard.
To display longer strings, you need to go though the string and display each character.
Code: Select all
puts(char *s) {
while(*s) {
videoram[offset++] = *s; /* character 'A' */
videoram[offset++] = 0x07; /* forground, background color. */
s++;
}
}
Offset should be a number that shows where the current position on screen is. You can also find it by creating cursor_x and y variables that keeps track of the x, y position.
-JL
Re: Understanding Bare Bones
Posted: Fri Feb 27, 2009 11:26 pm
by Steve the Pirate
gsingh2011 - the Multiboot header is what gives Grub (the bootloader) the information it needs to boot your kernel executable.
piranha - That should be
, shouldn't it? GCC will complain if you try to call puts like
because implicitly converting a const char * to a char * is being depreciated.
Re: Understanding Bare Bones
Posted: Sat Feb 28, 2009 12:06 am
by piranha
Yeah, sure. But that wasn't supposed to be copied, that was just an example. Proper implementation should be done.
-JL
Re: Understanding Bare Bones
Posted: Sat Feb 28, 2009 12:31 am
by Troy Martin
piranha wrote:Yeah, sure. But that wasn't supposed to be copied, that was just an example. Proper implementation should be done.
OP: Adding on what piranha said, a slightly more proper implementation must have at least a newline handler (print \r\n when \n is encountered) a method of calculating the offset from 0xB8000 using the cursor position, and updating the cursor. I'd say a fully complete implementation of string printing is a working printf() function.
Re: Understanding Bare Bones
Posted: Sat Feb 28, 2009 11:02 am
by gsingh2011
Could you give me the code to display the text "Hi"? I think that would clear things up for me...
Re: Understanding Bare Bones
Posted: Sat Feb 28, 2009 11:11 am
by piranha
This code is very simple, with newline parsing. You can figure out backspaces, etc.
Code: Select all
int x=0, y=0;
void puts(const char *str) {
while(*str) {
if(*str == '\n')
{ //Handle newline
str++;
x=0;y++;
}
videoram[y*80+x] = *str; /* character */
videoram[y*80+x+1] = 0x07; /* forground, background color. */
x++;
if(x > 80)
{ //If we reached to edge of the screen
x=0;
y++;
}
str++;
}
}
int main() {
...
puts("Hi\n");
...
}
Note: You should also add code for scrolling, so when the code gets to the bottom of the screen it scrolls up one line. That can be done by copying all lines of memory back the length of one line.
-JL
Re: Understanding Bare Bones
Posted: Sat Feb 28, 2009 12:36 pm
by gsingh2011
Hmm.. My code looks like this now and nothing shows up when I boot it:
Code: Select all
unsigned char *videoram = (unsigned char *) 0xb8000;
int x=0, y=0;
void puts(const char *str) {
while(*str) {
if(*str == '\n')
{ //Handle newline
str++;
x=0;y++;
}
videoram[y*80+x] = *str; /* character */
videoram[y*80+x+1] = 0x07; /* forground, background color. */
x++;
if(x > 80)
{ //If we reached to edge of the screen
x=0;
y++;
}
str++;
}
}
void kmain( void* mbd, unsigned int magic )
{
puts("Hi\n");
}
What did I do wrong?
And about the multiboot header, is it's purpose so that you can boot different types of OS's from that one bootloader? What do the operations 1<<0 and 1<<1 do in assembly? I couldn't find them in any tutorials...
Re: Understanding Bare Bones
Posted: Sat Feb 28, 2009 12:40 pm
by piranha
OOO, ouch I fail.
the x++ should be x+=2.
-JL
Re: Understanding Bare Bones
Posted: Sat Feb 28, 2009 12:55 pm
by gsingh2011
Same thing, nothing shows up... Does that exact code I pasted work for you when you run it?
Re: Understanding Bare Bones
Posted: Sat Feb 28, 2009 1:14 pm
by piranha
Yes, that should show something. But I do fail again.
I don't have time to explain why you should not use the code that I posted, so I'm going to forward you to
http://jamesmolloy.co.uk/tutorial_html/ ... creen.html
-JL
Re: Understanding Bare Bones
Posted: Sat Feb 28, 2009 9:37 pm
by gsingh2011
Ok, I looked at the site and I tried the code but I get an error. Here's the code I have in the monitor.h:
Code: Select all
// monitor.h -- Defines the interface for monitor.h
// From JamesM's kernel development tutorials.
#ifndef MONITOR_H
#define MONITOR_H
#include "common.h"
int cursor_x, cursor_y = 0;
unsigned char *video_memory = (unsigned char *) 0xb8000;
// Scrolls the text on the screen up by one line.
static void scroll()
{
// Get a space character with the default colour attributes.
u8int attributeByte = (0 /*black*/ << 4) | (15 /*white*/ & 0x0F);
u16int blank = 0x20 /* space */ | (attributeByte << 8);
// Row 25 is the end, this means we need to scroll up
if(cursor_y >= 25)
{
// Move the current text chunk that makes up the screen
// back in the buffer by a line
int i;
for (i = 0*80; i < 24*80; i++)
{
video_memory[i] = video_memory[i+80];
}
// The last line should now be blank. Do this by writing
// 80 spaces to it.
for (i = 24*80; i < 25*80; i++)
{
video_memory[i] = blank;
}
// The cursor should now be on the last line.
cursor_y = 24;
}
// Updates the hardware cursor.
static void move_cursor()
{
// The screen is 80 characters wide...
u16int cursorLocation = cursor_y * 80 + cursor_x;
outb(0x3D4, 14); // Tell the VGA board we are setting the high cursor byte.
outb(0x3D5, cursorLocation >> 8); // Send the high cursor byte.
outb(0x3D4, 15); // Tell the VGA board we are setting the low cursor byte.
outb(0x3D5, cursorLocation); // Send the low cursor byte.
}
// Clears the screen, by copying lots of spaces to the framebuffer.
void monitor_clear()
{
// Make an attribute byte for the default colours
u8int attributeByte = (0 /*black*/ << 4) | (15 /*white*/ & 0x0F);
u16int blank = 0x20 /* space */ | (attributeByte << 8);
int i;
for (i = 0; i < 80*25; i++)
{
video_memory[i] = blank;
}
// Move the hardware cursor back to the start.
cursor_x = 0;
cursor_y = 0;
move_cursor();
}
// Writes a single character out to the screen.
void monitor_put(char c)
{
// The background colour is black (0), the foreground is white (15).
u8int backColour = 0;
u8int foreColour = 15;
// The attribute byte is made up of two nibbles - the lower being the
// foreground colour, and the upper the background colour.
u8int attributeByte = (backColour << 4) | (foreColour & 0x0F);
// The attribute byte is the top 8 bits of the word we have to send to the
// VGA board.
u16int attribute = attributeByte << 8;
u16int *location;
// Handle a backspace, by moving the cursor back one space
if (c == 0x08 && cursor_x)
{
cursor_x--;
}
// Handle a tab by increasing the cursor's X, but only to a point
// where it is divisible by 8.
else if (c == 0x09)
{
cursor_x = (cursor_x+8) & ~(8-1);
}
// Handle carriage return
else if (c == '\r')
{
cursor_x = 0;
}
// Handle newline by moving cursor back to left and increasing the row
else if (c == '\n')
{
cursor_x = 0;
cursor_y++;
}
// Handle any other printable character.
else if(c >= ' ')
{
location = video_memory + (cursor_y*80 + cursor_x);
*location = c | attribute;
cursor_x++;
}
// Check if we need to insert a new line because we have reached the end
// of the screen.
if (cursor_x >= 80)
{
cursor_x = 0;
cursor_y ++;
}
// Scroll the screen if needed.
scroll();
// Move the hardware cursor.
move_cursor();
}
// Outputs a null-terminated ASCII string to the monitor.
void monitor_write(char *c)
{
int i = 0;
while (c[i])
{
monitor_put(c[i++]);
}
}
#endif // MONITOR_H
I get the errors:
Code: Select all
In file included from Source Files/kernel.c:2:
/home/gulshan/Documents/OS/monitor.h: In function ‘scroll’:
/home/gulshan/Documents/OS/monitor.h:43: error: invalid storage class for function ‘move_cursor’
/home/gulshan/Documents/OS/monitor.h: In function ‘monitor_put’:
/home/gulshan/Documents/OS/monitor.h:114: warning: assignment from incompatible pointer type
Source Files/kernel.c: In function ‘scroll’:
Source Files/kernel.c:9: error: expected declaration or statement at end of input
Source Files/kernel.c: At top level:
Source Files/kernel.c:5: warning: unused parameter ‘mbd’
Source Files/kernel.c:5: warning: unused parameter ‘magic’
Re: Understanding Bare Bones
Posted: Sat Feb 28, 2009 9:54 pm
by Steve the Pirate
Code: Select all
// The cursor should now be on the last line.
cursor_y = 24;
}
} // <- You forgot to add this.
// Updates the hardware cursor.
static void move_cursor()
Apart from that, I wouldn't recommend having that code in a header (usually you just put prototypes of the functions you need to access from other source files)... But for now it will do, I suppose.
Stephen
Re: Understanding Bare Bones
Posted: Mon Mar 02, 2009 6:04 pm
by gsingh2011
I've been having a few problems. I'm getting the errors:
Code: Select all
Source Files/kernel.h:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘default_console’
Source Files/kernel.c:7: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘:’ token
Source Files/kernel.c:14: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘:’ token
For the respective lines:
Code: Select all
class default_console
void default_console::default_console()
void default_console::clear()
Did I declare the class wrong or something? If you need more code just ask.
Re: Understanding Bare Bones
Posted: Mon Mar 02, 2009 6:06 pm
by Troy Martin
Classes don't exist in C. You'll have to do without them.