jsandler18 / raspi-kernel

MIT License
297 stars 49 forks source link

The code doesn't run on real hardware raspi 2 B #17

Closed rgbstar closed 5 years ago

rgbstar commented 5 years ago

I downloaded and built the "master" branch code, or part 06 branch code. It runs smoothly on qemu-system-arm simulator,

but when I renamed the kernel.img to kernel7.img and copied to the raspbian SD card of the real raspi 2 hardware, it doesn't run at all, just blank black screen (I disabled the raspi colour splash test). I also tried to change the gpu.c BLACK colour to BLUE, it worked in simulator, but doesn't work on real hardware.

To double check, when I switch back the raspbian kernel7.img, the raspberry pi runs without issue. The hardware is raspberry pi 2 B model.

rgbstar commented 5 years ago

Just an update: after many trial-and-error, it starts to work on real pi 2 (v1.1) now. Few fix 1) when setting integer & fractional part of uart baud rate, the parameters based on 3MHz UART_CLOCK doesn't work, need to re-calculate the integer and frac part parameters based on 42MHz uart clock. it helps debugging tremendously.

2) The return address from mail box fbinfo.buf doesn't work (exceeded 1G address limit), it needs to be add by 0x40000000 (or do the bit wise AND 0x3FFFFFF) to translate to physical address.

3) color depth 24 doesn't work properly. Need to set to 16 (need to modify pixel accordingly). No matter how I change the frame buffer parameters, the return buffer size is always x96000, which is corresponding to 640x480x2 bytes, but the fbinfo.pitch seems changing with different parameters. The code returned from mail box message shows success. I wonder if it is caused by raspi config.txt file.

After these changes, it can print "hello world!" correctly on the screen. However, there are still other issue: ATAG returns 0 mem_size. I temporarily fix it by hard code the mem-size 128MB when debugging gpu code, need to go back to investigate frame buffer and ATAG issue.

By the way, I downloaded most recent raspbian and installed on pi 2 to create boot SD card and then replace the kernel7.img with this img. I don't know if it is because the new raspbian that caused the color depth and ATAG issue.

rgbstar commented 5 years ago

update: now I can set color depth to 24 or 32, also different screen size. I fixed the issue by merging the frame buffer initialization mail box message and the request frame buffer mail box message into one send_messages() call in the framebuffer_init(). For some reason, if send_messages() is being called twice or more, it results in strange behaviour, I suspect the heap kmalloc(bufsize) or kfree(msg) still have bugs.

Nevertheless, now I can successfully set and request the frame buffer on real hardware.

Here is the code

tags[0].proptag = FB_SET_PHYSICAL_DIMENSIONS;
tags[0].value_buffer.fb_screen_size.width = 800;
tags[0].value_buffer.fb_screen_size.height = 600;
tags[1].proptag = FB_SET_VIRTUAL_DIMENSIONS;
tags[1].value_buffer.fb_screen_size.width = 800;
tags[1].value_buffer.fb_screen_size.height = 600;
tags[2].proptag = FB_SET_BITS_PER_PIXEL;
tags[2].value_buffer.fb_bits_per_pixel = COLORDEPTH;
tags[3].proptag = FB_ALLOCATE_BUFFER;
tags[3].value_buffer.fb_screen_size.width = 0;
tags[3].value_buffer.fb_screen_size.height = 0;
tags[3].value_buffer.fb_allocate_align = 16;
tags[4].proptag = NULL_TAG;

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

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

fbinfo.buf = tags[3].value_buffer.fb_allocate_res.fb_addr;
fbinfo.buf += 0x40000000;

fbinfo.buf_size = tags[3].value_buffer.fb_allocate_res.fb_size;
rgbstar commented 5 years ago

After some help from Raspberry pi forum, I fixed the ATAG issue. Because I use new version Raspbian to create boot SD card, the new boot loader doesn't create ATAG by default. After I moved all device tree files into a different folder, boot loader creates the ATAGS, then everything runs correctly on PI2 now.

Here is the short recap of the fix: 1) UART fix in uart.c mmio_write(UART0_IBRD, 26); // New raspi uart clock is 48M Hz (not 3M Hz) mmio_write(UART0_FBRD, 3); 2) Fix the kfree() .... // try to coalesce segments to the right while(seg->next != NULL && !seg->next->is_allocated) { seg->segment_size += seg->next->segment_size; if(seg->next->next != NULL) seg->next->next->prev = seg; seg->next = seg->next->next; } ... 3) Merge the frame buffer initialization and buffer request into one message call.
4) Add the bfinfo.buff address by 0x40000000, the codes are in previous post. 5) For new raspbian, delete or move all the device tree related files:0 /boot/*dtb etc.