0

Alright so I'm creating my own OS (not linux a completely original one) for raspberry pi 4 and when I try to build I get a bunch of the same errors but they all go along the lines of this example of one of them:

d:/superpios/build/gcc-arm-none-eabi-10-2020-q4-major-win32/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe: objects/mailbox.o:D:\SuperPiOS\build/../include/kernel/framebuffer.h:22: multiple definition of `fb_info'; objects/framebuffer.o:D:\SuperPiOS\build/../include/kernel/framebuffer.h:22: first defined here
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:49: build] Error 1

Anyways I was hoping if you could tell what the error is with this one is then I could fix the other ones using the same method. Oh, and here's where the errors should be to save you time I'll only show where it really matters: framebuffer.c:

int framebuffer_init(void) {
    property_message_tag_t tags[5];


    tags[0].proptag = FB_SET_PHYSICAL_DIMENSIONS;
    tags[0].value_buffer.fb_screen_size.width = 640;
    tags[0].value_buffer.fb_screen_size.height = 480;
    tags[1].proptag = FB_SET_VIRTUAL_DIMENSIONS;
    tags[1].value_buffer.fb_screen_size.width = 640;
    tags[1].value_buffer.fb_screen_size.height = 480;
    tags[2].proptag = FB_SET_BITS_PER_PIXEL;
    tags[2].value_buffer.fb_bits_per_pixel = COLORDEPTH;
    tags[3].proptag = NULL_TAG;


    // Send over the initialization
    if (send_messages(tags) != 0) {
        return -1;
    }

    fb_info.width = tags[0].value_buffer.fb_screen_size.width;
    fb_info.height = tags[0].value_buffer.fb_screen_size.height;
    fb_info.chars_width = fb_info.width / CHAR_WIDTH;
    fb_info.chars_height = fb_info.height / CHAR_HEIGHT;
    fb_info.chars_x = 0;
    fb_info.chars_y = 0;
    fb_info.pitch = fb_info.width*BYTES_PER_PIXEL;

    // request a framebuffer
    tags[0].proptag = FB_ALLOCATE_BUFFER;
    tags[0].value_buffer.fb_screen_size.width = 0;
    tags[0].value_buffer.fb_screen_size.height = 0;
    tags[0].value_buffer.fb_allocate_align = 16;
    tags[1].proptag = NULL_TAG;


    if (send_messages(tags) != 0) {
        return -1;
    }

    fb_info.buf = tags[0].value_buffer.fb_allocate_res.fb_addr;
    fb_info.buf_size = tags[0].value_buffer.fb_allocate_res.fb_size;

    return 0;
}

gpu.c:

void write_pixel(uint32_t x, uint32_t y, const pixel_t * pix) {
    uint8_t * location = fb_info.buf + y*fb_info.pitch + x*BYTES_PER_PIXEL;
    memcpy(location, pix, BYTES_PER_PIXEL);
}

void gpu_putc(char c) {
    static const pixel_t WHITE = {0xff, 0xff, 0xff};
    static const pixel_t BLACK = {0x00, 0x00, 0x00};
    uint8_t w,h;
    uint8_t mask;
    const uint8_t * bmp = fontf(c);
    uint32_t i, num_rows = fb_info.height/CHAR_HEIGHT;

    // shift everything up one row
    if (fb_info.chars_y >= num_rows) {
        // Copy a whole character row into the one above it
        for (i = 0; i < num_rows-1; i++)
            memcpy(fb_info.buf + fb_info.pitch*i*CHAR_HEIGHT, fb_info.buf + fb_info.pitch*(i+1)*CHAR_HEIGHT, fb_info.pitch * CHAR_HEIGHT);
        // zero out the last row
        bzero(fb_info.buf + fb_info.pitch*i*CHAR_HEIGHT,fb_info.pitch * CHAR_HEIGHT);
        fb_info.chars_y--;
    }

    if (c == '\n') {
        fb_info.chars_x = 0;
        fb_info.chars_y++;
        return;
    }

    for(w = 0; w < CHAR_WIDTH; w++) {
        for(h = 0; h < CHAR_HEIGHT; h++) {
            mask = 1 << (w);
            if (bmp[h] & mask)
                write_pixel(fb_info.chars_x*CHAR_WIDTH + w, fb_info.chars_y*CHAR_HEIGHT + h, &WHITE);
            else
                write_pixel(fb_info.chars_x*CHAR_WIDTH + w, fb_info.chars_y*CHAR_HEIGHT + h, &BLACK);
        }
    }

    fb_info.chars_x++;
    if (fb_info.chars_x > fb_info.chars_width) {
        fb_info.chars_x = 0;
        fb_info.chars_y++;
    }
}

void gpu_init(void) {
    static const pixel_t BLACK = {0x00, 0x00, 0x00};
    // Aparantly, this sometimes does not work, so try in a loop
    while(framebuffer_init());

    // clear screen
    for (uint32_t j = 0; j < fb_info.height; j++) {
        for (uint32_t i = 0; i < fb_info.width; i++) {
            write_pixel(i,j,&BLACK);
        }
    }
}

framebuffer.h:

#include <stdint.h>

#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H

#define COLORDEPTH 24
#define BYTES_PER_PIXEL COLORDEPTH/8

typedef struct framebuffer_info {
    uint32_t width;
    uint32_t height;
    uint32_t pitch;
    void * buf;
    uint32_t buf_size;
    uint32_t chars_width;
    uint32_t chars_height;
    uint32_t chars_x;
    uint32_t chars_y;
} framebuffer_info_t;


framebuffer_info_t fb_info;

int framebuffer_init(void);


#endif

Anyways, thanks in advance.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
Sammyueru
  • 23
  • 7
  • Did you miss to copy or acually missed to include `framebuffer.h` in `framebuffer.c`? – Sourav Ghosh Apr 25 '21 at 21:53
  • 3
    Also, that's why you do not define variable in header files. You define them in a source file, and declare them in header. – Sourav Ghosh Apr 25 '21 at 21:54
  • @SouravGhosh No framebuffer.c is really long so I only put the part that might have the error – Sammyueru Apr 25 '21 at 21:56
  • @SouravGhosh I'll try that – Sammyueru Apr 25 '21 at 21:57
  • Can't see why you put "assembly" in the list of tags. It's a typical C novice mistake: "framebuffer_info_t fb_info;" should be at the top of framebuffer.c, while framebuffer.h should have "extern framebuffer_info_t fb_info;" line. – tum_ Apr 25 '21 at 22:13

0 Answers0