This guide documents the complete setup process for running a full-screen Chromium kiosk on a 320x240 ILI9341 SPI display using Raspberry Pi OS in console mode (no desktop environment). Verified on Raspberry Pi OS Bookworm.
sudo systemctl set-default multi-user.targetsudo nano /boot/firmware/config.txtComment or remove this if present:
# dtoverlay=vc4-kms-v3dAdd this instead:
dtoverlay=vc4-fkms-v3ddtoverlay=fbtft,spi0-0,ili9341,bgr,reset_pin=27,dc_pin=22,rotate=270,speed=64000000sudo nano /boot/firmware/cmdline.txtAppend the following (keep everything on one line):
fbcon=map:1 fbcon=font:VGA8x8sudo rebootsudo apt install fbi
sudo fbi -T 1 -d /dev/fb0 -noverbose -a /path/to/image.jpgโ
If you see the image, framebuffer /dev/fb0 is working.
sudo apt install xserver-xorg xinit x11-xserver-utils xterm xserver-xorg-video-fbdev chromium-browsersudo mkdir -p /etc/X11/xorg.conf.d
sudo nano /etc/X11/xorg.conf.d/99-fbtft.confPaste this config:
Section "Device"
Identifier "FBDEV"
Driver "fbdev"
Option "fbdev" "/dev/fb0"
Option "ShadowFB" "false"
EndSection
Section "Screen"
Identifier "Screen0"
Device "FBDEV"
DefaultDepth 16
SubSection "Display"
Depth 16
Modes "320x240"
EndSubSection
EndSection
Section "Monitor"
Identifier "Monitor0"
EndSection
Section "ServerLayout"
Identifier "DefaultLayout"
Screen "Screen0"
EndSection#!/bin/sh
sudo -u pi bash <<EOF
source ~/.bashrc
export NVM_DIR="\$HOME/.nvm"
[ -s "\$NVM_DIR/nvm.sh" ] && \. "\$NVM_DIR/nvm.sh"
cd ~/<project-directory>
npm run start
exec chromium-browser \
--noerrdialogs \
--disable-infobars \
--disable-session-crashed-bubble \
--disable-gpu \
--disable-software-rasterizer \
--kiosk https://localhost:3000
EOFMake it executable:
chmod +x ~/.xinitrcPlace the following script at /usr/local/bin/kiosk-launch.sh:
sudo nano /usr/local/bin/kiosk-launch.shPaste:
#!/bin/bash
export GTK_THEME=Adwaita:dark
chmod +x ~/.xinitrc
chmod 666 /dev/fb0 /dev/tty0
# sudo xinit ~/.xinitrc -- vt1
# Show splash (requires framebuffer access)
echo "[kiosk] Launching splash screen"
fbi -T 1 -d /dev/fb0 -noverbose -a \
/home/pi/splash.jpg || true
sleep 1
# Run Chromium via xinit with VT access
echo "[kiosk] Starting Chromium via xinit"
xinit /home/pi/.xinitrc -- vt1Make it executable:
sudo chmod +x /usr/local/bin/kiosk-launch.shCreate the service file at /etc/systemd/system/chromium-kiosk.service:
sudo nano /etc/systemd/system/chromium-kiosk.servicePaste:
[Unit]
Description=Start Chromium Kiosk on
ILI9341 with Splash
After=network-online.target
Wants=network-online.target
[Service]
StandardOutput=journal
StandardError=journal
ExecStart=/usr/local/bin/kiosk-launch.sh
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetEnable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable chromium-kiosk.service
sudo systemctl start chromium-kiosk.serviceTests:
ls /dev/fb*
cat /sys/class/graphics/fb0/name
# Confirm framebuffer is bound to SPI
cat /sys/class/graphics/fb0/name
# Confirm screen resolution
cat /sys/class/graphics/fb0/virtual_size
# Confirm pixel depth
cat /sys/class/graphics/fb0/bits_per_pixel
# List framebuffer devices
ls -l /dev/fb*
# Confirm current TTY (helps with fbi and X)
tty
Fix after reboot:
chmod +x ~/.xinitrc
sudo systemctl set-default multi-user.target
sudo chmod 666 /dev/fb0 /dev/tty0
sudo reboot
sudo xinit ~/.xinitrc -- vt1