As I mentioned in comments, there is possibility to create dummy frame buffer using DRM.
Prepare your logo in proper resolution in *.h file.
It may be helpful: https://lvgl.io/tools/imageconverter
We need to write simple C program:
a) include logo from first step:
#include "logo.h"
b) we need this to invoke drm via ioctl:
#include <sys/ioctl.h>
#include <drm/drm.h>
#include <drm/drm_mode.h>
c) open proper device:
int dri_fd0 = open("/dev/dri/card0",O_RDWR | O_CLOEXEC);
d) retrieve info from drm:
struct drm_mode_modeinfo conn_mode_buf[20]={0};
uint64_t conn_prop_buf[20]={0},
conn_propval_buf[20]={0},
conn_enc_buf[20]={0};
struct drm_mode_get_connector conn={0};
conn.connector_id=res_conn_buf[i];
ioctl(dri_fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn);
conn.modes_ptr=(uint64_t)conn_mode_buf;
conn.props_ptr=(uint64_t)conn_prop_buf;
conn.prop_values_ptr=(uint64_t)conn_propval_buf;
conn.encoders_ptr=(uint64_t)conn_enc_buf;
ioctl(dri_fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn);
e) Init dummy buffer:
struct drm_mode_create_dumb create_dumb={0};
struct drm_mode_map_dumb map_dumb={0};
struct drm_mode_fb_cmd cmd_dumb={0};
create_dumb.width = width;
create_dumb.height = height;
create_dumb.bpp = 32;
create_dumb.flags = 0;
create_dumb.pitch = 0;
create_dumb.size = 0;
create_dumb.handle = 0;
ioctl(dri_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
cmd_dumb.width=create_dumb.width;
cmd_dumb.height=create_dumb.height;
cmd_dumb.bpp=create_dumb.bpp;
cmd_dumb.pitch=create_dumb.pitch;
cmd_dumb.depth=24;
cmd_dumb.handle=create_dumb.handle;
ioctl(dri_fd,DRM_IOCTL_MODE_ADDFB,&cmd_dumb);
map_dumb.handle=create_dumb.handle;
ioctl(dri_fd,DRM_IOCTL_MODE_MAP_DUMB,&map_dumb);
fb_base[i] = mmap(0, create_dumb.size, PROT_READ | PROT_WRITE, MAP_SHARED, dri_fd, map_dumb.offset);
struct drm_mode_get_encoder enc={0};
enc.encoder_id=conn.encoder_id;
ioctl(dri_fd, DRM_IOCTL_MODE_GETENCODER, &enc); //get encoder
struct drm_mode_crtc crtc={0};
crtc.crtc_id=enc.crtc_id;
ioctl(dri_fd, DRM_IOCTL_MODE_GETCRTC, &crtc);
crtc.fb_id=cmd_dumb.fb_id;
crtc.set_connectors_ptr=(uint64_t)&res_conn_buf[i];
crtc.count_connectors=1;
crtc.mode=conn_mode_buf[0];
crtc.mode_valid=1;
ioctl(dri_fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
f) copy data from c-array with your logo to video card shared buffer:
memcpy(fb_base[0], uint32_data, sizeof(uint32_t) * logo_width * logo_height);
We need to do this in loop because buffer is regularly auto-clearing.
Build application for dedicated platform and copy to /usr/bin/.
Add trigger in udev:
a) create new file in /usr/lib/udev/rules.d/11-framebuffer.rules
b) Inside file add trigger to invoke splash screen when video card will be ready:
KERNEL=="card0", RUN+="/usr/bin/splash-launch" in