splash: add shutdown splash

This commit adds a shutdown splash to the existing kernel startup splash(4)
screen feature. It can be customized by providing a PNG image to the
shutdown_splash directive loader.conf(5).

Sponsored by: 	Defenso
MFC after: 	2 weeks
Reviewed by:	vexeduxr, ziaee, manu
Differential Revision:	https://reviews.freebsd.org/D55140
This commit is contained in:
Quentin Thébault
2026-04-02 18:38:47 +02:00
committed by Ahmad Khalifa
parent b3d6829f49
commit 4b862c713a
8 changed files with 64 additions and 11 deletions
+11 -3
View File
@@ -24,14 +24,14 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd July 09, 2024
.Dd April 03, 2026
.Dt SPLASH 4
.Os
.Sh NAME
.Nm splash
.Nd splash screen / screen saver interface
.Sh SYNOPSIS
.Cd "device splash"
.Cd device splash
.Sh DESCRIPTION
The
.Nm
@@ -254,6 +254,12 @@ and include the following lines:
splash="/boot/images/freebsd-logo-rev.png"
boot_mute="YES"
.Ed
.Pp
A splash screen to be displayed at shutdown time can be specified with:
.Bd -literal -offset indent
shutdown_splash="/boot/images/freebsd-logo-rev.png"
boot_mute="YES"
.Ed
.\".Sh DIAGNOSTICS
.Sh SEE ALSO
.Xr vidcontrol 1 ,
@@ -308,7 +314,9 @@ modules were written by
png support for
.Xr vt 4
was written by
.An Emmanuel Vadot Aq Mt manu@FreeBSD.org .
.An Emmanuel Vadot Aq Mt manu@FreeBSD.org
and extended for shutdown by
.An Quentin Thébault Aq Mt quentin.thebault@defenso.fr .
.Sh CAVEATS
The screen saver works with
.Xr syscons 4
+3 -1
View File
@@ -282,7 +282,9 @@ int tslog_init(void);
int tslog_publish(void);
vm_offset_t build_font_module(vm_offset_t);
vm_offset_t build_splash_module(vm_offset_t);
#define SPLASH_STARTUP 1
#define SPLASH_SHUTDOWN 2
vm_offset_t build_splash_module(vm_offset_t, int);
/* MI module loaders */
#ifdef __elfN
+16 -4
View File
@@ -3098,7 +3098,7 @@ build_font_module(vm_offset_t addr)
}
vm_offset_t
build_splash_module(vm_offset_t addr)
build_splash_module(vm_offset_t addr, int type)
{
struct preloaded_file *fp;
struct splash_info si;
@@ -3118,7 +3118,11 @@ build_splash_module(vm_offset_t addr)
if (fp == NULL)
panic("can't find kernel file");
splash = getenv("splash");
if (type == SPLASH_STARTUP)
splash = getenv("splash");
if (type == SPLASH_SHUTDOWN)
splash = getenv("shutdown_splash");
if (splash == NULL)
return (addr);
@@ -3137,7 +3141,15 @@ build_splash_module(vm_offset_t addr)
/* Copy the bitmap. */
addr += archsw.arch_copyin(png.image, addr, png.png_datalen);
printf("Loading splash ok\n");
file_addmetadata(fp, MODINFOMD_SPLASH, sizeof(splashp), &splashp);
if (type == SPLASH_STARTUP) {
printf("Loading splash ok\n");
file_addmetadata(fp, MODINFOMD_SPLASH,
sizeof(splashp), &splashp);
}
if (type == SPLASH_SHUTDOWN) {
printf("Loading shutdown splash ok\n");
file_addmetadata(fp, MODINFOMD_SHTDWNSPLASH,
sizeof(splashp), &splashp);
}
return (addr);
}
+3 -1
View File
@@ -27,7 +27,9 @@ vesa_load="NO" # Set this to YES to load the vesa module
bitmap_load="NO" # Set this to YES if you want splash screen!
bitmap_name="splash.bmp" # Set this to the name of the file
bitmap_type="splash_image_data" # and place it on the module_path
splash="/boot/images/freebsd-logo-rev.png" # Set boot_mute=YES to load it
# Set boot_mute=YES to load these
splash="/boot/images/freebsd-logo-rev.png"
shutdown_splash="/boot/images/freebsd-logo-rev.png"
### Screen saver modules ###################################
# This is best done in rc.conf
+6 -1
View File
@@ -396,7 +396,12 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs)
/* Pad to a page boundary. */
addr = md_align(addr);
addr = build_splash_module(addr);
addr = build_splash_module(addr, SPLASH_STARTUP);
/* Pad to a page boundary. */
addr = md_align(addr);
addr = build_splash_module(addr, SPLASH_SHUTDOWN);
/* Pad to a page boundary. */
addr = md_align(addr);
+19 -1
View File
@@ -1684,8 +1684,13 @@ vtterm_splash(struct vt_device *vd)
uintptr_t image;
vt_axis_t top, left;
si = MD_FETCH(preload_kmdp, MODINFOMD_SPLASH, struct splash_info *);
if (!(vd->vd_flags & VDF_TEXTMODE) && (boothowto & RB_MUTE)) {
if (rebooting == 1) {
si = MD_FETCH(preload_kmdp, MODINFOMD_SHTDWNSPLASH, struct splash_info *);
vd->vd_driver->vd_blank(vd, TC_BLACK);
} else {
si = MD_FETCH(preload_kmdp, MODINFOMD_SPLASH, struct splash_info *);
}
if (si == NULL) {
top = (vd->vd_height - vt_logo_height) / 2;
left = (vd->vd_width - vt_logo_width) / 2;
@@ -1832,6 +1837,15 @@ vt_init_font_static(void)
vt_font_assigned = font;
}
#ifdef DEV_SPLASH
static int
vt_shutdown_splash(struct vt_window *vw)
{
vtterm_splash(vw->vw_device);
return (0);
}
#endif
static void
vtterm_cnprobe(struct terminal *tm, struct consdev *cp)
{
@@ -3177,6 +3191,10 @@ vt_upgrade(struct vt_device *vd)
/* For existing console window. */
EVENTHANDLER_REGISTER(shutdown_pre_sync,
vt_window_switch, vw, SHUTDOWN_PRI_DEFAULT);
#ifdef DEV_SPLASH
EVENTHANDLER_REGISTER(shutdown_pre_sync,
vt_shutdown_splash, vw, SHUTDOWN_PRI_DEFAULT);
#endif
}
}
}
+5
View File
@@ -307,6 +307,7 @@ preload_bootstrap_relocate(vm_offset_t offset)
case MODINFO_ADDR:
case MODINFO_METADATA|MODINFOMD_FONT:
case MODINFO_METADATA|MODINFOMD_SPLASH:
case MODINFO_METADATA|MODINFOMD_SHTDWNSPLASH:
case MODINFO_METADATA|MODINFOMD_SSYM:
case MODINFO_METADATA|MODINFOMD_ESYM:
ptr = (vm_offset_t *)(curp + (sizeof(uint32_t) * 2));
@@ -439,6 +440,9 @@ preload_modinfo_type(struct sbuf *sbp, int type)
case MODINFOMD_SPLASH:
sbuf_cat(sbp, "MODINFOMD_SPLASH");
break;
case MODINFOMD_SHTDWNSPLASH:
sbuf_cat(sbp, "MODINFOMD_SHTDWNSPLASH");
break;
#ifdef MODINFOMD_BOOT_HARTID
case MODINFOMD_BOOT_HARTID:
sbuf_cat(sbp, "MODINFOMD_BOOT_HARTID");
@@ -503,6 +507,7 @@ preload_modinfo_value(struct sbuf *sbp, uint32_t *bptr, int type, int len)
#endif
case MODINFO_METADATA | MODINFOMD_FONT:
case MODINFO_METADATA | MODINFOMD_SPLASH:
case MODINFO_METADATA | MODINFOMD_SHTDWNSPLASH:
sbuf_print_vmoffset(sbp, *(vm_offset_t *)bptr);
break;
case MODINFO_METADATA | MODINFOMD_HOWTO:
+1
View File
@@ -259,6 +259,7 @@ void linker_kldload_unbusy(int flags);
#define MODINFOMD_KEYBUF 0x000d /* Crypto key intake buffer */
#define MODINFOMD_FONT 0x000e /* Console font */
#define MODINFOMD_SPLASH 0x000f /* Console splash screen */
#define MODINFOMD_SHTDWNSPLASH 0x0010 /* Console shutdown splash screen */
#define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */
#define MODINFOMD_DEPLIST (0x4001 | MODINFOMD_NOCOPY) /* depends on */