Why can I not output a pixel to the Linear Framebuffer?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
itsaxg
Posts: 3
Joined: Tue Sep 30, 2025 11:51 am
Libera.chat IRC: alex

Why can I not output a pixel to the Linear Framebuffer?

Post by itsaxg »

Hello guys! I get the multiboot info, but I can not get a pixel going on the screen no matter what, can someone tell me what I am doing wrong? I am still learning OSDev, it's messy cause it's just an initial release where I am just testing stuff out

my linker.ld
```
ENTRY(start)

SECTIONS {
. = 1K;

.boot :
{
*(.multiboot)
}

.text :
{
*(.text)
}
}
```

```
// grub.cfg

set timeout=10
set default=0
set gfxpayload=keep

menuentry "zxOS" {
multiboot /boot/kernel.bin
}
```

```asm
; multiboot.asm
section .multiboot
align 4
dd 0x1BADB002
dd (1<<0)|(1<<1)|(1<<2)
dd -(0x1BADB002 + ((1<<0)|(1<<1)|(1<<2)))

dd 0
dd 0
dd 0
dd 0
dd 0

dd 0
dd 1024
dd 768
dd 32
```

```asm
; boot.asm
global start
extern kernel_main

section .text
bits 32
start:
push ebx
push eax
call kernel_main
end:
hlt
jmp end
```

```cpp
#ifndef IO_H
#define IO_H

#include "stdint.h"

static inline void outb(uint16_t port, uint8_t val) {
__asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
}

static inline uint8_t inb(uint16_t port) {
uint8_t ret;
__asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}

#endif
```

```cpp
#ifndef MULTIBOOT_INFO_H
#define MULTIBOOT_INFO_H

#include "stdint.h"

typedef struct __attribute__((packed)) multiboot_info {
uint32_t flags;

uint32_t mem_lower;
uint32_t mem_upper;

uint32_t boot_device;

uint32_t cmdline;

uint32_t mods_count;
uint32_t mods_addr;

uint32_t syms[4];

uint32_t mmap_length;
uint32_t mmap_addr;

uint32_t drives_length;
uint32_t drives_addr;

uint32_t config_table;

uint32_t boot_loader_name;

uint32_t apm_table;

uint32_t vbe_control_info;
uint32_t vbe_mode_info;
uint16_t vme_mode;
uint16_t vbe_interface_seg;
uint16_t vbe_interface_off;
uint16_t vbe_interface_len;

uint64_t framebuffer_addr;
uint32_t framebuffer_pitch;
uint32_t framebuffer_width;
uint32_t framebuffer_height;
uint8_t framebuffer_bpp;
uint8_t framebuffer_type;
uint8_t color_info[5];
} multiboot_info_t;

#endif
```

```cpp
// kernel.c
#include "multiboot_info.h"
#include "stdint.h"
#include "io.h"

void kernel_main(uint32_t magic, multiboot_info_t* mbi) {

if (magic != 0x2BADB002) {}

if (mbi->flags & (1 << 12)) {

uint8_t rp = mbi->color_info[0];
uint8_t gp = mbi->color_info[2];
uint8_t bp = mbi->color_info[4];

uint32_t red_pixel = (255 << rp); // full red
uint32_t green_pixel = (255 << gp); // full green
uint32_t blue_pixel = (255 << bp); // full blue

uint32_t* framebuffer = (uint32_t*)(uint32_t)mbi->framebuffer_addr;

framebuffer[mbi->framebuffer_pitch / 4] = red_pixel;

while (1) {}
}

while (inb(0x64) & 0x02) {}
// Pulse CPU reset
outb(0x64, 0xFE);
}
```

```
all:
nasm -f elf32 src/asm/multiboot.asm -o output/multiboot.o
nasm -f elf32 src/asm/boot.asm -o output/boot.o

gcc -m32 -ffreestanding -fno-builtin -fno-pie -fno-stack-protector -Iinclude -g -c src/c/kernel.c -o output/kernel.o

ld -m elf_i386 --nmagic --output=iso/boot/kernel.bin --script=linker.ld \
output/multiboot.o output/boot.o output/kernel.o

grub-mkrescue -o os.iso iso
```

I run with qemu-system-x86_64.exe os.iso

What could the issue be? Any help is appreciated!
User avatar
iansjack
Member
Member
Posts: 4936
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Why can I not output a pixel to the Linear Framebuffer?

Post by iansjack »

I haven’t checked your code, but are you sure you are not outputting the pixel? A single pixel is pretty small, and red is probably the least visible colour. You might want to try displaying a 10x10 block rather than a single pixel.
Octocontrabass
Member
Member
Posts: 6275
Joined: Mon Mar 25, 2013 7:01 pm

Re: Why can I not output a pixel to the Linear Framebuffer?

Post by Octocontrabass »

itsaxg wrote: ↑Tue Sep 30, 2025 11:56 amI get the multiboot info, but I can not get a pixel going on the screen no matter what, can someone tell me what I am doing wrong?
What does your debugger say about the multiboot info? Do the values look reasonable?
itsaxg wrote: ↑Tue Sep 30, 2025 11:56 am

Code: Select all

    . = 1K;
I'm not sure GRUB works properly if you tell it to load your kernel below 1M.
itsaxg
Posts: 3
Joined: Tue Sep 30, 2025 11:51 am
Libera.chat IRC: alex

Re: Why can I not output a pixel to the Linear Framebuffer?

Post by itsaxg »

Thank you so much for the reply!
Switching to 1M seems to have fixed the issue!
Now the pixel shows up!
Post Reply