0

I am trying to write my own OS, I currently am trying to pass the video framebuffer address to my kernel so that I can start plotting pixels and etc. However, when I try and pass my arguments to my kernel entry the argument doesn't get passed.

I defined framebuffer like this:

framebuffer: dd 0

There might be a problem with the way I get the framebuffer or the way I store it so here is the way I got it:

First I get the first word of the address that is located in the 0x28th byte of the mode information structure and write it to [framebuffer]. Then I get the second word located in 0x2A. I know for a fact that the first word is 0x0000 and the second is 0xFD00 which makes sense because I am using qemu and qemu's framebuffer is located at 0xFD000000. So I write the first word to the second-word place of the framebuffer and the second word the first place in order to get 0xFD000000 in the framebuffer variable

mov bx, vbe_mode_structure+0x28                                ; vbe_mode_structure+0x28 is the framebuffer address
;push word [bx]                                                ;
;call print_hex_word                                           ;
;add sp, 2                                                     ;
mov ax, [bx]                                                   ;
mov word [framebuffer+1], ax                                   ;
mov bx, vbe_mode_structure+0x2A                                ; vbe_mode_structure+0x2A is the framebuffer address
;push word [bx]                                                ;
;call print_hex_word                                           ;
;add sp, 2                                                     ;
mov ax, [bx]                                                   ;
mov word [framebuffer], ax                                     ;

Then I pass it as an argument to my kernel which I loaded to 0x1000

mov eax, framebuffer
push eax
call 0x1000
add esp, 4

Finally in my kernel I do the following and try to plot a pixel

    push ebp    
    mov ebp, esp
    mov eax, [ ebp + 8 ]    

    mov  edi, [eax]   
    add  edi, 0    
    mov  al, 0xFF   
    stosb  
    
    
    pop ebp     ; minimal cleanup
    ret
    
    jmp $

The pixel however does not appear. If I write 0xFD000000 instead of [eax] I do get a blue pixel to appear in the top left corner of the screen.

The questions are:

  1. What is wrong with the code?

  2. Am I passing the parameters correctly

  3. Should I be passing framebuffer as a parameter to the kernel in the first place? Is there a get-around?

Finally here are the entire project files in github: https://github.com/Danyy427/OSDEV4.git

Edit: I changed the argument passing code to the following

;mov eax, [framebuffer]
push dword [vbe_mode_structure+0x28]
call 0x1000
add esp, 4

and changed the reciever like this:

mov  edi, [ebp+8]      ;
mov  al, 0xFF   
stosb  

I still don't get any pixel being plotted on top left corner.

Edit 2:

I mixed the low and high of the address the final code is:

    mov bx, vbe_mode_structure+0x28                                ; vbe_mode_structure+0x28 is the framebuffer address
    ;push word [bx]                                                ;
    ;call print_hex_word                                           ;
    ;add sp, 2                                                     ;
    mov ax, [bx]                                                   ;
    mov word [framebuffer], ax                                   ;
    mov bx, vbe_mode_structure+0x2A                                ; vbe_mode_structure+0x2A is the framebuffer address
    ;push word [bx]                                                ;
    ;call print_hex_word                                           ;
    ;add sp, 2                                                     ;
    mov ax, [bx]                                                   ;
    mov word [framebuffer+2], ax  

and for the receiving part

    mov ebp, esp
    mov eax, [ ebp +8 ]  
    
    mov  edi, eax       
    mov  al, 0xFF   
    stosb  
    
    pop ebp     ; minimal cleanup
    ret
    
    jmp $
  • 3
    `mov word [framebuffer+1], ax ` should be `+2`. Better yet, why not use `mov eax, [vbe_mode_structure+0x28]; mov [framebuffer], eax`. Also why pass the `framebuffer` by reference? Just do `push dword [vbe_mode_structure+0x28]` and `mov edi, [ebp + 8]`. – Jester Mar 23 '21 at 12:22
  • @Jester making those changes didn't change the result. I still am not getting any pixels plotted. I cannot do ```mov eax, [vbe_mode_structure+0x28]``` because I am in 16 bit, woudln't that cause trouble? – Özgür Güzeldereli Mar 23 '21 at 13:04
  • @MichaelPetch I push the argument from 32 bit. I store the framebuffer address to a variable before switching to 32 bit. – Özgür Güzeldereli Mar 23 '21 at 13:14
  • You can use 32-bit registers in 16-bit modes, given that you are running on a 386+ machine. This is accomplished with o32/a32 prefixes which your assembler will insert as needed automatically. – ecm Mar 23 '21 at 13:14
  • 1
    Oh also you got the low and high words reversed. – Jester Mar 23 '21 at 13:29
  • 2
    `0x28` is the low word so that should go to `[framebuffer]` and `0x2a` is the high word so that goes to `[framebuffer+2]` (if you keep the original code). This is the part you got wrong: _"So I write the first word to the second-word place of the framebuffer and the second word the first place in order to get 0xFD000000 in the framebuffer variable"_ – Jester Mar 23 '21 at 13:32
  • @Jester Yes, I just noticed that thank you! – Özgür Güzeldereli Mar 23 '21 at 13:35
  • @Jester Oh I found something. I was checking the value of ebp using qemu monitor and it seems that the value of ebp-4 is in fact 0xfd000000. But I still cannot use it? – Özgür Güzeldereli Mar 23 '21 at 13:36
  • Ok it finally worked with the comment @Jester made. It didn't work the moment I fixed it because I played so much on the code that everything was messed up. I cleaned everything and posting the final code as edit. – Özgür Güzeldereli Mar 23 '21 at 13:44

0 Answers0