Page 1 of 2
Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 4:37 am
by DeezRamChips
Sa, i successfully ploted a pixel on the screen with the right color !
But... I cant do this on all the screen, take a look:
and the code to plot a pixel:
Code: Select all
char* screen = 0xA0000;
void setPixel(int x,int y, int r, int g, int b) {
unsigned pos = x*3 + y*2400;
screen[pos] = b; // BLUE
screen[pos + 1] = g; // GREEN
screen[pos + 2] = r; // RED
}
here is the code to switch to the video mode:
Code: Select all
mov ax, 0x4F02
mov bx, 0x115
int 10h
On real hardware, teh computer simply crashes
Thank for your help
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 4:45 am
by BrightLight
You're not using a linear frame buffer; you're using bank switching. That is completely obsolete.
Try using mode 0x4115 instead of 0x0115, and also use function 0x4F01 with mode 0x0115 to get the linear frame buffer address.
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 4:55 am
by DeezRamChips
Well, I i just tried using mode 0x4115 but it didn't change anything
also, The probleme, is that i cant call int 10 in p_mode because i dont have a vm86 monitor setup :/
how could I pass the linear frame buffer address to the kernel from the bootloader ?
(Sorry for n00b questions
)
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 5:05 am
by BrightLight
Pass a structure to your kernel. For example, in your boot loader:
Code: Select all
boot_information:
; whatever information your kernel needs
.bios_memory_map dd 0 ; pointer to memory map
.vbe_framebuffer dd 0 ; VBE framebuffer
; anything else
Then, right before you call your kernel:
Code: Select all
mov eax, 0x12345678 ; you can make up any magic number to tell your kernel that it was booted with your loader
mov ebx, boot_information ; pass the boot information to the kernel
call 0x100000 ; if your kernel is loaded at 1 MB, for example
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 5:11 am
by DeezRamChips
Ok thank, I though it was reset when i jump to the kernel I'm so silly
and, now, how do I access it in the kernel ?
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 5:17 am
by BrightLight
Erm.. You're kidding right?
You already have a pointer to it. Access it from the pointer.
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 5:29 am
by DeezRamChips
Well I dont understand how pointers work in c and assembly: I just started OS developpement 3 weeks ago...
And my consol version works fine, but I want a better resolution so I would like to use VESA.
Could you show me an exemple of how i could get the info in the kernel and explain me how it works...
Sorry again for n00b question, i'm trying to get better
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 6:25 am
by Combuster
I dont understand how pointers work in c and assembly
Pointers is one of the fundamentals of C. If that's still magic to you, then possibly
Required Knowledge applies to you. There are many resources out on the internet that can help you learn the things involved.
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 6:53 am
by DeezRamChips
You didn't understand i think... I mean:
I understand pointers in C alone
But i dont understand how you can use them with Assembly
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 7:38 am
by DeezRamChips
So, i read a little more about pointer !
but, I only manage to pass a single variable, how could a pass a structure ?
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 8:21 am
by osdever
DeezRamChips wrote:So, i read a little more about pointer !
but, I only manage to pass a single variable, how could a pass a structure ?
Exactly as a variable - pass pointer to the structure.
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 8:48 am
by DeezRamChips
To pass a pointer to a structure, how do you do?
like this ? :
Code: Select all
int addr; //stores the address
asm("\t movl %%ebx,%0" : "=r"(addr)); //get the address from EBX
addr = addr + 1; // Add 1
unsigned char *boot_information = addr; //Initialize the pointer
struct boot_info
{
int a; //First info
int b; //Second info
};
boot_info = boot_information;
I tried this but it gives me an error
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 10:02 am
by osdever
DeezRamChips wrote:To pass a pointer to a structure, how do you do?
like this ? :
Code: Select all
int addr; //stores the address
asm("\t movl %%ebx,%0" : "=r"(addr)); //get the address from EBX
addr = addr + 1; // Add 1
unsigned char *boot_information = addr; //Initialize the pointer
struct boot_info
{
int a; //First info
int b; //Second info
};
boot_info = boot_information;
I tried this but it gives me an error
First read
Required Knowledge. You aren't declaring any copies of struct boot_info - instead you're trying to assign value to 1) invalid type in C (struct blablabla isn't creating new type in C), 2) type name in C++. Also, your assigning won't work even if you'll fix first your error - you need to swap boot_info and boot_information. You're assigning pointer to structure.
Some info: don't offend, I've been exactly like you when I started OSDev'ing.
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 10:21 am
by DeezRamChips
So, how could i fix the probleme ?
Re: Only portion of screen working in VESA
Posted: Sat Apr 09, 2016 10:57 am
by Schol-R-LEA
The use of
to increment the value here is troubling to me, for two reasons.
First, it implies that you don't know the increment operator (or just don't realize that it is a general operator rather than a part of the for() loop's control structure). The ++ operator is such a critical feature in C/C++ that not knowing it is a sign that you really don't understand the language as a whole as well as you think.
Second, I'm not sure just why you are incrementing that address in the first place. You already have the address of the boot map, why do you need to change it to map to a specific element in that map?
Third, since you are using an integer to hold the address rather than a pointer, incrementing the address gives it a value of address+1, but since you are working with a structure already (albeit one passed to you from the assembly code), you would only really need to increment it by address + sizeof(bootmap), if at all. By using a pointer, you could have the compiler do this part for you automatically.
If you had declared the boot_info structure
first, then declared boot_information as a pointer to that type and implicitly cast the address to that type by passing boot_information as the inline assembly parameter, you wouldn't need any of this.
Code: Select all
typedef struct boot_info
{
int a; //First info
int b; //Second info
} BOOT_INFO;
BOOT_INFO* boot_information;
asm("\t movl %%ebx,%0" : "=r"(boot_information)); //get the address from EBX