u32_t * rgb24to32(u8_t *buf24, PFBDEV pFbdev) { int w = fb_get_width(pFbdev); int h = fb_get_height(pFbdev); u32_t *buf32 = malloc(w * h * 4); if(NULL == buf) { printf("rgb24to32 malloc error\n"); return NULL; } int i; for(i = 0; i < w * h; ++i) { *((u8_t *)&buf32[i] + 2) = buf24[i * 3 + 0]; *((u8_t *)&buf32[i] + 1) = buf24[i * 3 + 1]; *((u8_t *)&buf32[i] + 0) = buf24[i * 3 + 2]; *((u8_t *)&buf32[i] + 3) = 0x30; } return (u32_t *)buf; }
u16_t * rgb24to16(u8_t *buf24, PFBDEV pFbdev) { u16_t *buf16 = NULL; u32_t r16,g16,b16; buf16 = malloc (fb_get_width(pFbdev)*fb_get_height(pFbdev)*2); if (buf16 == NULL) { printf("rgb24to16 malloc error\n"); return NULL; } int i; for (i = 0 ;i < jpeg_inf.w * jpeg_inf.h ; i++) { b16 = (buf24[i * 3 + 2] * 0x1f) / 0xff; g16 = (buf24[i * 3 + 1] * 0x3f) / 0xff; r16 = (buf24[i * 3 + 0] * 0x1f) / 0xff; buf16[i] = b16 | (g16 <<5) | (r16 <<11); } return buf16; }
void kernel_main(uint32_t boot_dev, uint32_t arm_m_type, uint32_t atags) { // Hack for newer firmware - assume if atags not specified then they are at 0x100 // We also check the zero address in case this is true - see later if(atags == 0x0) atags = 0x100; atag_cmd_line = (void *)0; _atags = atags; _arm_m_type = arm_m_type; UNUSED(boot_dev); // First use the serial console stdout_putc = split_putc; stderr_putc = split_putc; stream_putc = def_stream_putc; output_init(); output_enable_uart(); // dump arguments to main #ifdef DEBUG printf("MAIN: boot_dev: %x, arm_m_type: %i, atags: %x\n", boot_dev, arm_m_type, atags); #endif // try and interpret device tree/atags if(fdt_check_header((const void *)atags) == 0) conf_source = 3; else if(fdt_check_header((const void *)0) == 0) conf_source = 4; else if(check_atags((const void *)atags) == 0) conf_source = 1; else if(check_atags((const void *)0) == 0) conf_source = 2; switch(conf_source) { case 1: case 2: // If using ATAGs, need to set up base adjust // manually if(arm_m_type == 0xc42) base_adjust = BASE_ADJUST_V1; else if(arm_m_type == 0xc43) base_adjust = BASE_ADJUST_V2; uart_init(); #ifdef DEBUG printf("ATAGS: detected\n"); #endif // Fall through case 3: case 4: parse_atag_or_dtb(mem_cb); break; default: printf("MAIN: ERROR no device tree or ATAGS found\n"); return; } #ifdef ENABLE_FRAMEBUFFER int result = fb_init(); if(result == 0) { puts("Successfully set up frame buffer"); #ifdef DEBUG2 printf("FB: width: %i, height: %i, bpp: %i\n", fb_get_width(), fb_get_height(), fb_get_bpp()); #endif } else { puts("Error setting up framebuffer:"); puthex(result); } #endif // Switch to the framebuffer for output output_enable_fb(); // Allocate a log in memory #ifdef ENABLE_CONSOLE_LOGFILE register_log_file(NULL, 0x1000); output_enable_log(); #endif printf("Welcome to Rpi bootloader\n"); printf("Compiled on %s at %s\n", __DATE__, __TIME__); printf("ARM system type is %x\n", arm_m_type); if(atag_cmd_line != (void *)0) printf("Command line: %s\n", atag_cmd_line); // Register the various file systems libfs_init(); // List devices printf("MAIN: device list: "); vfs_list_devices(); printf("\n"); // Look for a boot configuration file, starting with the default device, // then iterating through all devices FILE *f = (void*)0; // Default device char **fname = boot_cfg_names; char *found_cfg; while(*fname) { f = fopen(*fname, "r"); if(f) { found_cfg = *fname; break; } fname++; } if(!f) { // Try other devices char **dev = vfs_get_device_list(); while(*dev) { int dev_len = strlen(*dev); fname = boot_cfg_names; while(*fname) { int fname_len = strlen(*fname); char *new_str = (char *)malloc(dev_len + fname_len + 3); new_str[0] = 0; strcat(new_str, "("); strcat(new_str, *dev); strcat(new_str, ")"); strcat(new_str, *fname); f = fopen(new_str, "r"); if(f) { found_cfg = new_str; break; } free(new_str); fname++; } if(f) break; dev++; } } if(!f) { printf("MAIN: No bootloader configuration file found\n"); } else { long flen = fsize(f); printf("MAIN: Found bootloader configuration: %s\n", found_cfg); char *buf = (char *)malloc(flen+1); buf[flen] = 0; // null terminate fread(buf, 1, flen, f); fclose(f); cfg_parse(buf); } }
void draw_vline(int x, color c) { for( int y = 0; y < fb_get_height(); y++ ) draw_pixel(x, y, c); }