diff --git a/share/man/man4/splash.4 b/share/man/man4/splash.4 --- a/share/man/man4/splash.4 +++ b/share/man/man4/splash.4 @@ -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 @@ 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 @@ 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 diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h --- a/stand/common/bootstrap.h +++ b/stand/common/bootstrap.h @@ -282,7 +282,9 @@ 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 diff --git a/stand/common/gfx_fb.c b/stand/common/gfx_fb.c --- a/stand/common/gfx_fb.c +++ b/stand/common/gfx_fb.c @@ -3098,7 +3098,7 @@ } 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 @@ 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 @@ /* 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); } diff --git a/stand/defaults/loader.conf b/stand/defaults/loader.conf --- a/stand/defaults/loader.conf +++ b/stand/defaults/loader.conf @@ -27,7 +27,9 @@ 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 diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c --- a/stand/efi/loader/bootinfo.c +++ b/stand/efi/loader/bootinfo.c @@ -396,7 +396,12 @@ /* 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); diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c --- a/sys/dev/vt/vt_core.c +++ b/sys/dev/vt/vt_core.c @@ -1684,8 +1684,13 @@ 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_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 @@ /* 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 } } } diff --git a/sys/kern/subr_module.c b/sys/kern/subr_module.c --- a/sys/kern/subr_module.c +++ b/sys/kern/subr_module.c @@ -307,6 +307,7 @@ 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 @@ 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 @@ #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: diff --git a/sys/sys/linker.h b/sys/sys/linker.h --- a/sys/sys/linker.h +++ b/sys/sys/linker.h @@ -259,6 +259,7 @@ #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 */