Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Mar 2014 07:16:40 +0000 (UTC)
From:      Devin Teske <dteske@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r262701 - in stable/10/sys/boot: forth i386/loader
Message-ID:  <201403030716.s237Ge5I073823@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dteske
Date: Mon Mar  3 07:16:39 2014
New Revision: 262701
URL: http://svnweb.freebsd.org/changeset/base/262701

Log:
  MFC r257650:
  
  Defer loading of kernel and modules if the beastie menu is enabled. Add a
  kernel selection menu to the beastie menu. List of kernels is taken from
  `kernels' in loader.conf(5) as a space (or comma) separated list of names
  to display (up to 9). If not set, default value is "kernel kernel.old".
  Does not validate that kernels exist because the next enhancement will be
  to allow selection of the root device.
  
  Discussed on:	-current

Modified:
  stable/10/sys/boot/forth/beastie.4th
  stable/10/sys/boot/forth/loader.4th
  stable/10/sys/boot/forth/loader.4th.8
  stable/10/sys/boot/forth/loader.conf
  stable/10/sys/boot/forth/loader.conf.5
  stable/10/sys/boot/forth/loader.rc
  stable/10/sys/boot/forth/menu-commands.4th
  stable/10/sys/boot/forth/menu.4th
  stable/10/sys/boot/forth/menu.rc
  stable/10/sys/boot/forth/menusets.4th
  stable/10/sys/boot/i386/loader/loader.rc
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/boot/forth/beastie.4th
==============================================================================
--- stable/10/sys/boot/forth/beastie.4th	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/forth/beastie.4th	Mon Mar  3 07:16:39 2014	(r262701)
@@ -30,6 +30,8 @@ marker task-beastie.4th
 
 include /boot/delay.4th
 
+only forth definitions also support-functions
+
 variable logoX
 variable logoY
 
@@ -275,7 +277,11 @@ variable logoY
 	s" beastie_disable" getenv
 	dup -1 <> if
 		s" YES" compare-insensitive 0= if
-			exit
+			any_conf_read? if
+				load_kernel
+				load_modules
+			then
+			exit \ to autoboot (default)
 		then
 	else
 		drop
@@ -292,3 +298,5 @@ variable logoY
 		delay_execute
 	then
 ;
+
+only forth also

Modified: stable/10/sys/boot/forth/loader.4th
==============================================================================
--- stable/10/sys/boot/forth/loader.4th	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/forth/loader.4th	Mon Mar  3 07:16:39 2014	(r262701)
@@ -44,6 +44,14 @@ include /boot/color.4th
 
 only forth also support-functions also builtins definitions
 
+: bootmsg ( -- )
+  loader_color? if
+    ." Booting..." cr
+  else
+    ." Booting..." cr
+  then
+;
+
 : try-menu-unset
   \ menu-unset may not be present
   s" beastie_disable" getenv
@@ -71,12 +79,6 @@ only forth also support-functions also b
 : boot
   0= if ( interpreted ) get_arguments then
 
-  loader_color? if
-    ." Booting..." cr
-  else
-    ." Booting..." cr
-  then
-
   \ Unload only if a path was passed
   dup if
     >r over r> swap
@@ -85,25 +87,25 @@ only forth also support-functions also b
     else
       s" kernelname" getenv? if ( a kernel has been loaded )
         try-menu-unset
-        1 boot exit
+        bootmsg 1 boot exit
       then
       load_kernel_and_modules
       ?dup if exit then
       try-menu-unset
-      0 1 boot exit
+      bootmsg 0 1 boot exit
     then
   else
     s" kernelname" getenv? if ( a kernel has been loaded )
       try-menu-unset
-      1 boot exit
+      bootmsg 1 boot exit
     then
     load_kernel_and_modules
     ?dup if exit then
     try-menu-unset
-    0 1 boot exit
+    bootmsg 0 1 boot exit
   then
   load_kernel_and_modules
-  ?dup 0= if 0 1 boot then
+  ?dup 0= if bootmsg 0 1 boot then
 ;
 
 \ ***** boot-conf
@@ -129,8 +131,8 @@ include /boot/check-password.4th
 \ ***** start
 \
 \       Initializes support.4th global variables, sets loader_conf_files,
-\       process conf files, and, if any one such file was succesfully
-\       read to the end, load kernel and modules.
+\       processes conf files, and, if any one such file was succesfully
+\       read to the end, loads kernel and modules.
 
 : start  ( -- ) ( throws: abort & user-defined )
   s" /boot/defaults/loader.conf" initialize

Modified: stable/10/sys/boot/forth/loader.4th.8
==============================================================================
--- stable/10/sys/boot/forth/loader.4th.8	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/forth/loader.4th.8	Mon Mar  3 07:16:39 2014	(r262701)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 30, 2004
+.Dd October 17, 2013
 .Dt LOADER.4TH 8
 .Os
 .Sh NAME
@@ -94,31 +94,35 @@ Reads
 .Pa /boot/defaults/loader.conf ,
 all other
 .Xr loader.conf 5
-files specified in it, and then proceeds to boot as specified in them.
-This
+files specified in it, then loads the desired kernel and modules
+.Pq if not already loaded .
+After which you can use the
+.Ic boot
+or
+.Ic autoboot
+commmands or simply exit (provided
+.Va autoboot_delay
+is not set to NO) to boot the system.
+.Ic start
 is the command used in the default
 .Pa /boot/loader.rc
-file, and it uses the
-.Ic autoboot
-command (see
-.Xr loader 8 ) ,
-so it can be stopped for further interaction with
-.Xr loader 8 .
+file
+.Pq see Xr loader 8 .
 .Pp
 .It Ic initialize
-Initialize the supporting library so commands can be used without
-executing
+Initialize the support library so commands can be used without executing
 .Ic start
 first.
 Like
 .Ic start ,
-reads
+it reads
 .Pa /boot/defaults/loader.conf
 and all other
 .Xr loader.conf 5
-files specified in it.
+files specified in it
+.Pq but does not load kernel or modules .
 Returns a flag on the stack to indicate
-if any configuration file was successfully loaded.
+if any configuration files were successfully loaded.
 .Pp
 .It Ic read-conf Ar filename
 Reads and processes a

Modified: stable/10/sys/boot/forth/loader.conf
==============================================================================
--- stable/10/sys/boot/forth/loader.conf	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/forth/loader.conf	Mon Mar  3 07:16:39 2014	(r262701)
@@ -59,6 +59,7 @@ entropy_cache_type="/boot/entropy"	
 				# escape to the loader prompt, set to
 				# "NO" to disable autobooting
 #beastie_disable="NO"		# Turn the beastie boot menu on and off
+#kernels="kernel kernel.old"	# Kernels to display in the boot menu
 #loader_logo="orbbw"		# Desired logo: orbbw, orb, fbsdbw, beastiebw, beastie, none
 #comconsole_speed="9600"	# Set the current serial console speed
 #console="vidconsole"		# A comma separated list of console(s)

Modified: stable/10/sys/boot/forth/loader.conf.5
==============================================================================
--- stable/10/sys/boot/forth/loader.conf.5	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/forth/loader.conf.5	Mon Mar  3 07:16:39 2014	(r262701)
@@ -23,7 +23,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\" $FreeBSD$
-.Dd August 6, 2013
+.Dd October 18, 2013
 .Dt LOADER.CONF 5
 .Os
 .Sh NAME
@@ -209,6 +209,9 @@ replacing it with
 character (useful for embedded products and such).
 .It Va kernel
 .Pq Dq kernel
+.It Va kernels
+.Pq Dq kernel kernel.old
+Space or comma separated list of kernels to present in the boot menu.
 .It Va loader_conf_files
 .Pq Dq Pa /boot/loader.conf /boot/loader.conf.local
 .It Va splash_bmp_load

Modified: stable/10/sys/boot/forth/loader.rc
==============================================================================
--- stable/10/sys/boot/forth/loader.rc	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/forth/loader.rc	Mon Mar  3 07:16:39 2014	(r262701)
@@ -5,6 +5,7 @@
 include /boot/loader.4th
 
 \ Reads and processes loader.conf variables
+\ NOTE: Change to `initialize' if you enable the below boot menu
 start
 
 \ Tests for password -- executes autoboot first if a password was defined

Modified: stable/10/sys/boot/forth/menu-commands.4th
==============================================================================
--- stable/10/sys/boot/forth/menu-commands.4th	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/forth/menu-commands.4th	Mon Mar  3 07:16:39 2014	(r262701)
@@ -1,4 +1,4 @@
-\ Copyright (c) 2006-2012 Devin Teske <dteske@FreeBSD.org>
+\ Copyright (c) 2006-2013 Devin Teske <dteske@FreeBSD.org>
 \ All rights reserved.
 \ 
 \ Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,8 @@ include /boot/menusets.4th
 
 variable kernel_state
 variable root_state
+0 kernel_state !
+0 root_state !
 
 \ 
 \ Boot
@@ -279,21 +281,21 @@ variable root_state
 	init_cyclestate ( n k -- n )
 ;
 
-: cycle_kernel ( N -- N TRUE )
-	cycle_menuitem
-	menu-redraw
-
-	\ Now we're going to make the change effective
-
-	dup cycle_stateN @
-	dup kernel_state !       \ save a copy for re-initialization
-	48 +                     \ convert to ASCII numeral
+: activate_kernel ( N -- N )
+	dup cycle_stateN @	( n -- n n2 )
+	dup kernel_state !	( n n2 -- n n2 )  \ copy for re-initialization
+	48 +			( n n2 -- n n2' ) \ kernel_state to ASCII num
 
 	s" set kernel=${kernel_prefix}${kernel[N]}${kernel_suffix}"
-	36 +c!   \ replace 'N' with ASCII numeral
-	evaluate \ sets $kernel to full kernel-path
+	36 +c!		( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
+	evaluate	( n c-addr/u -- n ) \ sets $kernel to full kernel-path
+;
 
-	TRUE \ loop menu again
+: cycle_kernel ( N -- N TRUE )
+	cycle_menuitem	\ cycle cycle_stateN to next value
+	activate_kernel \ apply current cycle_stateN
+	menu-redraw	\ redraw menu
+	TRUE		\ loop menu again
 ;
 
 \ 
@@ -305,21 +307,21 @@ variable root_state
 	init_cyclestate ( n k -- n )
 ;
 
-: cycle_root ( N -- N TRUE )
-	cycle_menuitem
-	menu-redraw
-
-	\ Now we're going to make the change effective
-
-	dup cycle_stateN @
-	dup root_state !         \ save a copy for re-initialization
-	48 +                     \ convert to ASCII numeral
+: activate_root ( N -- N )
+	dup cycle_stateN @	( n -- n n2 )
+	dup root_state !	( n n2 -- n n2 )  \ copy for re-initialization
+	48 +			( n n2 -- n n2' ) \ root_state to ASCII num
 
 	s" set root=${root_prefix}${root[N]}${root_suffix}"
-	30 +c!   \ replace 'N' with ASCII numeral
-	evaluate \ sets $root to full root-path
+	30 +c!		( n n2 c-addr/u -- n c-addr/u ) \ 'N' to ASCII num
+	evaluate	( n c-addr/u -- n ) \ sets $root to full kernel-path
+;
 
-	TRUE \ loop menu again
+: cycle_root ( N -- N TRUE )
+	cycle_menuitem	\ cycle cycle_stateN to next value
+	activate_root	\ apply current cycle_stateN
+	menu-redraw	\ redraw menu
+	TRUE		\ loop menu again
 ;
 
 \ 

Modified: stable/10/sys/boot/forth/menu.4th
==============================================================================
--- stable/10/sys/boot/forth/menu.4th	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/forth/menu.4th	Mon Mar  3 07:16:39 2014	(r262701)
@@ -70,6 +70,12 @@ variable menureboot
 variable menurebootadded
 variable menuacpi
 variable menuoptions
+variable menukernel
+
+\ Parsing of kernels into menu-items
+variable kernidx
+variable kernlen
+variable kernmenuidx
 
 \ Menu timer [count-down] variables
 variable menu_timeout_enabled \ timeout state (internal use only)
@@ -109,14 +115,19 @@ variable cycle_state7
 variable cycle_state8
 
 \ Containers for storing the initial caption text
-create init_text1 255 allot
-create init_text2 255 allot
-create init_text3 255 allot
-create init_text4 255 allot
-create init_text5 255 allot
-create init_text6 255 allot
-create init_text7 255 allot
-create init_text8 255 allot
+create init_text1 64 allot
+create init_text2 64 allot
+create init_text3 64 allot
+create init_text4 64 allot
+create init_text5 64 allot
+create init_text6 64 allot
+create init_text7 64 allot
+create init_text8 64 allot
+
+\ Containers for parsing kernels into menu-items
+create kerncapbuf 64 allot
+create kerndefault 64 allot
+create kernelsbuf 256 allot
 
 : +c! ( N C-ADDR/U K -- C-ADDR/U )
 	3 pick 3 pick	( n c-addr/u k -- n c-addr/u k n c-addr )
@@ -124,45 +135,31 @@ create init_text8 255 allot
 	rot drop	( n c-addr/u -- c-addr/u )
 ;
 
+: delim? ( C -- BOOL )
+	dup  32 =		( c -- c bool )		\ [sp] space
+	over  9 = or		( c bool -- c bool )	\ [ht] horizontal tab
+	over 10 = or		( c bool -- c bool )	\ [nl] newline
+	over 13 = or		( c bool -- c bool )	\ [cr] carriage return
+	over [char] , =	or	( c bool -- c bool )	\ comma
+	swap drop		( c bool -- bool )	\ return boolean
+;
+
 : menukeyN      ( N -- ADDR )   s" menukeyN"       7 +c! evaluate ;
 : init_stateN   ( N -- ADDR )   s" init_stateN"   10 +c! evaluate ;
 : toggle_stateN ( N -- ADDR )   s" toggle_stateN" 12 +c! evaluate ;
 : cycle_stateN  ( N -- ADDR )   s" cycle_stateN"  11 +c! evaluate ;
 : init_textN    ( N -- C-ADDR ) s" init_textN"     9 +c! evaluate ;
 
-: str_loader_menu_frame       ( -- C-ADDR/U ) s" loader_menu_frame" ;
-: str_loader_menu_title       ( -- C-ADDR/U ) s" loader_menu_title" ;
-: str_loader_menu_title_align ( -- C-ADDR/U ) s" loader_menu_title_align" ;
-: str_loader_menu_x           ( -- C-ADDR/U ) s" loader_menu_x" ;
-: str_loader_menu_y           ( -- C-ADDR/U ) s" loader_menu_y" ;
-: str_loader_menu_timeout_x   ( -- C-ADDR/U ) s" loader_menu_timeout_x" ;
-: str_loader_menu_timeout_y   ( -- C-ADDR/U ) s" loader_menu_timeout_y" ;
-: str_menu_init               ( -- C-ADDR/U ) s" menu_init" ;
-: str_menu_timeout_command    ( -- C-ADDR/U ) s" menu_timeout_command" ;
-: str_menu_reboot             ( -- C-ADDR/U ) s" menu_reboot" ;
-: str_menu_acpi               ( -- C-ADDR/U ) s" menu_acpi" ;
-: str_menu_options            ( -- C-ADDR/U ) s" menu_options" ;
-: str_menu_optionstext        ( -- C-ADDR/U ) s" menu_optionstext" ;
-
-: str_menu_init[x]          ( -- C-ADDR/U ) s" menu_init[x]" ;
-: str_menu_command[x]       ( -- C-ADDR/U ) s" menu_command[x]" ;
-: str_menu_caption[x]       ( -- C-ADDR/U ) s" menu_caption[x]" ;
-: str_ansi_caption[x]       ( -- C-ADDR/U ) s" ansi_caption[x]" ;
-: str_menu_keycode[x]       ( -- C-ADDR/U ) s" menu_keycode[x]" ;
-: str_toggled_text[x]       ( -- C-ADDR/U ) s" toggled_text[x]" ;
-: str_toggled_ansi[x]       ( -- C-ADDR/U ) s" toggled_ansi[x]" ;
-: str_menu_caption[x][y]    ( -- C-ADDR/U ) s" menu_caption[x][y]" ;
-: str_ansi_caption[x][y]    ( -- C-ADDR/U ) s" ansi_caption[x][y]" ;
-
-: menu_init[x]       ( N -- C-ADDR/U )   str_menu_init[x]       10 +c! ;
-: menu_command[x]    ( N -- C-ADDR/U )   str_menu_command[x]    13 +c! ;
-: menu_caption[x]    ( N -- C-ADDR/U )   str_menu_caption[x]    13 +c! ;
-: ansi_caption[x]    ( N -- C-ADDR/U )   str_ansi_caption[x]    13 +c! ;
-: menu_keycode[x]    ( N -- C-ADDR/U )   str_menu_keycode[x]    13 +c! ;
-: toggled_text[x]    ( N -- C-ADDR/U )   str_toggled_text[x]    13 +c! ;
-: toggled_ansi[x]    ( N -- C-ADDR/U )   str_toggled_ansi[x]    13 +c! ;
-: menu_caption[x][y] ( N M -- C-ADDR/U ) str_menu_caption[x][y] 16 +c! 13 +c! ;
-: ansi_caption[x][y] ( N M -- C-ADDR/U ) str_ansi_caption[x][y] 16 +c! 13 +c! ;
+: kernel[x]          ( N -- C-ADDR/U )   s" kernel[x]"           7 +c! ;
+: menu_init[x]       ( N -- C-ADDR/U )   s" menu_init[x]"       10 +c! ;
+: menu_command[x]    ( N -- C-ADDR/U )   s" menu_command[x]"    13 +c! ;
+: menu_caption[x]    ( N -- C-ADDR/U )   s" menu_caption[x]"    13 +c! ;
+: ansi_caption[x]    ( N -- C-ADDR/U )   s" ansi_caption[x]"    13 +c! ;
+: menu_keycode[x]    ( N -- C-ADDR/U )   s" menu_keycode[x]"    13 +c! ;
+: toggled_text[x]    ( N -- C-ADDR/U )   s" toggled_text[x]"    13 +c! ;
+: toggled_ansi[x]    ( N -- C-ADDR/U )   s" toggled_ansi[x]"    13 +c! ;
+: menu_caption[x][y] ( N M -- C-ADDR/U ) s" menu_caption[x][y]" 16 +c! 13 +c! ;
+: ansi_caption[x][y] ( N M -- C-ADDR/U ) s" ansi_caption[x][y]" 16 +c! 13 +c! ;
 
 : arch-i386? ( -- BOOL ) \ Returns TRUE (-1) on i386, FALSE (0) otherwise.
 	s" arch-i386" environment? dup if
@@ -355,12 +352,9 @@ create init_text8 255 allot
 		then
 		( n addr 0 n 48 -- n addr 0 c-addr/u )
 		getenv dup -1 = if
-			\ This is highly unlikely to occur, but to make
-			\ sure that things move along smoothly, allocate
-			\ a temporary NULL string
-
-			drop ( n addr 0 -1 -- n addr 0 ) \ getenv cruft
-			s" " ( n addr 0 -- n addr 0 c-addr/u )
+			\ Highly unlikely to occur, but to ensure things move
+			\ along smoothly, allocate a temporary NULL string
+			drop ( cruft ) s" "
 		then
 	then
 
@@ -418,15 +412,15 @@ create init_text8 255 allot
 		acpipresent? if
 			acpienabled? if
 				loader_color? if
-					str_toggled_ansi[x]
+					s" toggled_ansi[x]"
 				else
-					str_toggled_text[x]
+					s" toggled_text[x]"
 				then
 			else
 				loader_color? if
-					str_ansi_caption[x]
+					s" ansi_caption[x]"
 				else
-					str_menu_caption[x]
+					s" menu_caption[x]"
 				then
 			then
 		else
@@ -438,17 +432,198 @@ create init_text8 255 allot
 	then
 ;
 
+\ This function parses $kernels into variables that are used by the menu to
+\ display wich kernel to boot when the [overloaded] `boot' word is interpreted.
+\ Used internally by menu-create, you need not (nor should you) call this
+\ directly.
+\ 
+: parse-kernels ( N -- ) \ kernidx
+	kernidx ! ( n -- )	\ store provided `x' value
+	[char] 0 kernmenuidx !	\ initialize `y' value for menu_caption[x][y]
+
+	\ Attempt to get a list of kernels, fall back to sensible default
+	s" kernels" getenv dup -1 = if
+		drop ( cruft )
+		s" kernel kernel.old"
+	then ( -- c-addr/u )
+
+	\ Check to see if the user has altered $kernel by comparing it against
+	\ $kernel[N] where N is kernel_state (the actively displayed kernel).
+	s" kernel_state" evaluate @ 48 + s" kernel[N]" 7 +c! getenv
+	dup -1 <> if
+		s" kernel" getenv dup -1 = if
+			drop ( cruft ) s" "
+		then
+		2swap 2over compare 0= if
+			2drop FALSE ( skip below conditional )
+		else \ User has changed $kernel
+			TRUE ( slurp in new value )
+		then
+	else \ We haven't yet parsed $kernels into $kernel[N]
+		drop ( getenv cruft )
+		s" kernel" getenv dup -1 = if
+			drop ( cruft ) s" "
+		then
+		TRUE ( slurp in initial value )
+	then ( c-addr/u -- c-addr/u c-addr/u,-1 | 0 )
+	if \ slurp new value into kerndefault
+		kerndefault 1+ 0 2swap strcat swap 1- c!
+	then
+
+	\ Clear out existing parsed-kernels
+	kernidx @ [char] 0
+	begin
+		dup kernel[x] unsetenv
+		2dup menu_caption[x][y] unsetenv
+		2dup ansi_caption[x][y] unsetenv
+		1+ dup [char] 8 >
+	until
+	2drop
+
+	\ Step through the string until we find the end
+	begin
+		0 kernlen ! \ initialize length of value
+
+		\ Skip leading whitespace and/or comma delimiters
+		begin
+			dup 0<> if
+				over c@ delim? ( c-addr/u -- c-addr/u bool )
+			else
+				false ( c-addr/u -- c-addr/u bool )
+			then
+		while
+			1- swap 1+ swap ( c-addr/u -- c-addr'/u' )
+		repeat
+		( c-addr/u -- c-addr'/u' )
+
+		dup 0= if \ end of string while eating whitespace
+			2drop ( c-addr/u -- )
+			kernmenuidx @ [char] 0 <> if \ found at least one
+				exit \ all done
+			then
+
+			\ No entries in $kernels; use $kernel instead
+			s" kernel" getenv dup -1 = if
+				drop ( cruft ) s" "
+			then ( -- c-addr/u )
+			dup kernlen ! \ store entire value length as kernlen
+		else
+			\ We're still within $kernels parsing toward the end;
+			\ find delimiter/end to determine kernlen
+			2dup ( c-addr/u -- c-addr/u c-addr/u )
+			begin dup 0<> while
+				over c@ delim? if
+					drop 0 ( break ) \ found delimiter
+				else
+					kernlen @ 1+ kernlen ! \ incrememnt
+					1- swap 1+ swap \ c-addr++ u--
+				then
+			repeat
+			2drop ( c-addr/u c-addr'/u' -- c-addr/u )
+
+			\ If this is the first entry, compare it to $kernel
+			\ If different, then insert $kernel beforehand
+			kernmenuidx @ [char] 0 = if
+				over kernlen @ kerndefault count compare if
+					kernelsbuf 0 kerndefault count strcat
+					s" ," strcat 2swap strcat
+					kerndefault count swap drop kernlen !
+				then
+			then
+		then
+		( c-addr/u -- c-addr'/u' )
+
+		\ At this point, we should have something on the stack to store
+		\ as the next kernel menu option; start assembling variables
+
+		over kernlen @ ( c-addr/u -- c-addr/u c-addr/u2 )
+
+		\ Assign first to kernel[x]
+		2dup kernmenuidx @ kernel[x] setenv
+
+		\ Assign second to menu_caption[x][y]
+		kerncapbuf 0 s" [K]ernel: " strcat
+		2over strcat
+		kernidx @ kernmenuidx @ menu_caption[x][y]
+		setenv
+
+		\ Assign third to ansi_caption[x][y]
+		kerncapbuf 0 s" Kernel: " strcat
+		kernmenuidx @ [char] 0 = if
+			s" default/"
+		else
+			s" "
+		then strcat
+		2over strcat
+		s" " strcat
+		kernidx @ kernmenuidx @ ansi_caption[x][y]
+		setenv
+
+		2drop ( c-addr/u c-addr/u2 -- c-addr/u )
+
+		kernmenuidx @ 1+ dup kernmenuidx ! [char] 8 > if
+			2drop ( c-addr/u -- ) exit
+		then
+
+		kernlen @ - swap kernlen @ + swap ( c-addr/u -- c-addr'/u' )
+	again
+;
+
+\ This function goes through the kernels that were discovered by the
+\ parse-kernels function [above], adding " (# of #)" text to the end of each
+\ caption.
+\ 
+: tag-kernels ( -- )
+	kernidx @ ( -- x ) dup 0= if exit then
+	[char] 0 s"  (Y of Z)" ( x -- x y c-addr/u )
+	kernmenuidx @ -rot 7 +c! \ Replace 'Z' with number of kernels parsed
+	begin
+		2 pick 1+ -rot 2 +c! \ Replace 'Y' with current ASCII num
+
+		2over menu_caption[x][y] getenv dup -1 <> if
+			2dup + 1- c@ [char] ) = if
+				2drop \ Already tagged
+			else
+				kerncapbuf 0 2swap strcat
+				2over strcat
+				5 pick 5 pick menu_caption[x][y] setenv
+			then
+		else
+			drop ( getenv cruft )
+		then
+
+		2over ansi_caption[x][y] getenv dup -1 <> if
+			2dup + 1- c@ [char] ) = if
+				2drop \ Already tagged
+			else
+				kerncapbuf 0 2swap strcat
+				2over strcat
+				5 pick 5 pick ansi_caption[x][y] setenv
+			then
+		else
+			drop ( getenv cruft )
+		then
+
+		rot 1+ dup [char] 8 > if
+			-rot 2drop TRUE ( break )
+		else
+			-rot FALSE
+		then
+	until
+	2drop ( x y -- )
+;
+
 \ This function creates the list of menu items. This function is called by the
 \ menu-display function. You need not be call it directly.
 \ 
 : menu-create ( -- )
 
 	\ Print the frame caption at (x,y)
-	str_loader_menu_title getenv dup -1 = if
+	s" loader_menu_title" getenv dup -1 = if
 		drop s" Welcome to FreeBSD"
 	then
 	TRUE ( use default alignment )
-	str_loader_menu_title_align getenv dup -1 <> if
+	s" loader_menu_title_align" getenv dup -1 <> if
 		2dup s" left" compare-insensitive 0= if ( 1 )
 			2drop ( c-addr/u ) drop ( bool )
 			menuX @ menuY @ 1-
@@ -470,7 +645,7 @@ create init_text8 255 allot
 	\ constructed dynamically -- as this function could conceivably set
 	\ the remaining environment variables to construct the menu entirely).
 	\ 
-	str_menu_init getenv dup -1 <> if
+	s" menu_init" getenv dup -1 <> if
 		evaluate
 	else
 		drop
@@ -495,7 +670,7 @@ create init_text8 255 allot
 	\ Initialize the ACPI option status.
 	\ 
 	0 menuacpi !
-	str_menu_acpi getenv -1 <> if
+	s" menu_acpi" getenv -1 <> if
 		c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
 			menuacpi !
 			arch-i386? if acpipresent? if
@@ -511,10 +686,51 @@ create init_text8 255 allot
 	then
 
 	\ 
+	\ Initialize kernel captions after parsing $kernels
+	\ 
+	0 menukernel !
+	s" menu_kernel" getenv -1 <> if
+		c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
+			dup menukernel !
+			dup parse-kernels tag-kernels
+
+			\ Get the current cycle state (entry to use)
+			s" kernel_state" evaluate @ 48 + ( n -- n y )
+
+			\ If state is invalid, reset
+			dup kernmenuidx @ 1- > if
+				drop [char] 0 ( n y -- n 48 )
+				0 s" kernel_state" evaluate !
+				over s" init_kernel" evaluate drop
+			then
+
+			\ Set the current non-ANSI caption
+			2dup swap dup ( n y -- n y y n n )
+			s" set menu_caption[x]=$menu_caption[x][y]"
+			17 +c! 34 +c! 37 +c! evaluate
+			( n y y n n c-addr/u -- n y  )
+
+			\ Set the current ANSI caption
+			2dup swap dup ( n y -- n y y n n )
+			s" set ansi_caption[x]=$ansi_caption[x][y]"
+			17 +c! 34 +c! 37 +c! evaluate
+			( n y y n n c-addr/u -- n y )
+
+			\ Initialize cycle state from stored value
+			48 - ( n y -- n k )
+			s" init_cyclestate" evaluate ( n k -- n )
+
+			\ Set $kernel to $kernel[y]
+			s" activate_kernel" evaluate ( n -- n )
+		then
+		drop
+	then
+
+	\ 
 	\ Initialize the menu_options visual separator.
 	\ 
 	0 menuoptions !
-	str_menu_options getenv -1 <> if
+	s" menu_options" getenv -1 <> if
 		c@ dup 48 > over 57 < and if ( '1' <= c1 <= '8' )
 			menuoptions !
 		else
@@ -534,7 +750,7 @@ create init_text8 255 allot
 		\ If the "Options:" separator, print it.
 		dup menuoptions @ = if
 			\ Optionally add a reboot option to the menu
-			str_menu_reboot getenv -1 <> if
+			s" menu_reboot" getenv -1 <> if
 				drop
 				s" Reboot" printmenuitem menureboot !
 				true menurebootadded !
@@ -544,7 +760,7 @@ create init_text8 255 allot
 			menurow @ 2 + menurow !
 			menurow @ menuY @ +
 			at-xy
-			str_menu_optionstext getenv dup -1 <> if
+			s" menu_optionstext" getenv dup -1 <> if
 				type
 			else
 				drop ." Options:"
@@ -603,7 +819,7 @@ create init_text8 255 allot
 
 	\ Optionally add a reboot option to the menu
 	menurebootadded @ true <> if
-		str_menu_reboot getenv -1 <> if
+		s" menu_reboot" getenv -1 <> if
 			drop       \ no need for the value
 			s" Reboot" \ menu caption (required by printmenuitem)
 
@@ -684,7 +900,7 @@ create init_text8 255 allot
 					\ (user did not cancel by pressing ANY
 					\ key)
 
-					str_menu_timeout_command getenv dup
+					s" menu_timeout_command"  getenv dup
 					-1 = if
 						drop \ clean-up
 					else
@@ -758,7 +974,7 @@ create init_text8 255 allot
 	0 menurow !     \ Initialize the starting position for the menu
 
 	\ Assign configuration values
-	str_loader_menu_y getenv dup -1 = if
+	s" loader_menu_y" getenv dup -1 = if
 		drop \ no custom row position
 		menu_default_y
 	else
@@ -768,7 +984,7 @@ create init_text8 255 allot
 		then
 	then
 	menuY !
-	str_loader_menu_x getenv dup -1 = if
+	s" loader_menu_x" getenv dup -1 = if
 		drop \ no custom column position
 		menu_default_x
 	else
@@ -781,7 +997,7 @@ create init_text8 255 allot
 
 	\ Interpret a custom frame type for the menu
 	TRUE ( draw a box? default yes, but might be altered below )
-	str_loader_menu_frame getenv dup -1 = if ( 1 )
+	s" loader_menu_frame" getenv dup -1 = if ( 1 )
 		drop \ no custom frame type
 	else ( 1 )  2dup s" single" compare-insensitive 0= if ( 2 )
 		f_single ( see frames.4th )
@@ -804,7 +1020,7 @@ create init_text8 255 allot
 	0 menu_timeout_enabled ! \ start with automatic timeout disabled
 
 	\ check indication that automatic execution after delay is requested
-	str_menu_timeout_command getenv -1 <> if ( Addr C -1 -- | Addr )
+	s" menu_timeout_command" getenv -1 <> if ( Addr C -1 -- | Addr )
 		drop ( just testing existence right now: Addr -- )
 
 		\ initialize state variables
@@ -840,7 +1056,7 @@ create init_text8 255 allot
 
 		menu_timeout_enabled @ 1 = if
 			\ read custom column position (if set)
-			str_loader_menu_timeout_x getenv dup -1 = if
+			s" loader_menu_timeout_x" getenv dup -1 = if
 				drop \ no custom column position
 				menu_timeout_default_x \ use default setting
 			else
@@ -852,7 +1068,7 @@ create init_text8 255 allot
 			menu_timeout_x ! ( store value on stack from above )
         
 			\ read custom row position (if set)
-			str_loader_menu_timeout_y getenv dup -1 = if
+			s" loader_menu_timeout_y" getenv dup -1 = if
 				drop \ no custom row position
 				menu_timeout_default_y \ use default setting
 			else
@@ -1005,12 +1221,13 @@ create init_text8 255 allot
 	until
 	drop \ iterator
 
-	str_menu_timeout_command unsetenv	\ menu timeout command
-	str_menu_reboot          unsetenv	\ Reboot menu option flag
-	str_menu_acpi            unsetenv	\ ACPI menu option flag
-	str_menu_options         unsetenv	\ Options separator flag
-	str_menu_optionstext     unsetenv	\ separator display text
-	str_menu_init            unsetenv	\ menu initializer
+	s" menu_timeout_command" unsetenv	\ menu timeout command
+	s" menu_reboot"          unsetenv	\ Reboot menu option flag
+	s" menu_acpi"            unsetenv	\ ACPI menu option flag
+	s" menu_kernel"          unsetenv	\ Kernel menu option flag
+	s" menu_options"         unsetenv	\ Options separator flag
+	s" menu_optionstext"     unsetenv	\ separator display text
+	s" menu_init"            unsetenv	\ menu initializer
 
 	0 menureboot !
 	0 menuacpi !

Modified: stable/10/sys/boot/forth/menu.rc
==============================================================================
--- stable/10/sys/boot/forth/menu.rc	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/forth/menu.rc	Mon Mar  3 07:16:39 2014	(r262701)
@@ -55,10 +55,14 @@ set mainmenu_reboot
 \ 
 set mainmenu_options=5
 
-set mainmenu_caption[5]="Configure Boot [O]ptions..."
-set mainmenu_command[5]="2 goto_menu"
-set mainmenu_keycode[5]=111
-set mainansi_caption[5]="Configure Boot Options..."
+set mainmenu_kernel=5
+set mainmenu_command[5]="cycle_kernel"
+set mainmenu_keycode[5]=107
+
+set mainmenu_caption[6]="Configure Boot [O]ptions..."
+set mainmenu_command[6]="2 goto_menu"
+set mainmenu_keycode[6]=111
+set mainansi_caption[6]="Configure Boot Options..."
 
 \ 
 \ BOOT OPTIONS MENU

Modified: stable/10/sys/boot/forth/menusets.4th
==============================================================================
--- stable/10/sys/boot/forth/menusets.4th	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/forth/menusets.4th	Mon Mar  3 07:16:39 2014	(r262701)
@@ -366,6 +366,7 @@ create menuset_y        1   allot
 	\ 	menuset1_command[x]		-> menu_command[x]
 	\ 	menuset1_init			-> ``evaluated''
 	\ 	menuset1_init[x]		-> menu_init[x]
+	\ 	menuset1_kernel			-> menu_kernel
 	\ 	menuset1_keycode[x]		-> menu_keycode[x]
 	\ 	menuset1_options		-> menu_options
 	\ 	menuset1_optionstext		-> menu_optionstext
@@ -382,6 +383,7 @@ create menuset_y        1   allot
 	\ 	{name}menu_command[x]		-> menu_command[x]
 	\ 	{name}menu_init			-> ``evaluated''
 	\ 	{name}menu_init[x]		-> menu_init[x]
+	\ 	{name}menu_kernel		-> menu_kernel
 	\ 	{name}menu_keycode[x]		-> menu_keycode[x]
 	\ 	{name}menu_options		-> menu_options
 	\ 	{name}menu_optionstext		-> menu_optionstext
@@ -520,6 +522,10 @@ create menuset_y        1   allot
 	s" set var=acpi" evaluate
 	menuset-loadmenuvar
 
+	\ ... menu_kernel ...
+	s" set var=kernel" evaluate
+	menuset-loadmenuvar
+
 	\ ... menu_options ...
 	s" set var=options" evaluate
 	menuset-loadmenuvar
@@ -597,6 +603,7 @@ create menuset_y        1   allot
 
 		s" set var=acpi"        evaluate menuset-unloadmenuvar
 		s" set var=init"        evaluate menuset-unloadmenuvar
+		s" set var=kernel"      evaluate menuset-unloadmenuvar
 		s" set var=options"     evaluate menuset-unloadmenuvar
 		s" set var=optionstext" evaluate menuset-unloadmenuvar
 		s" set var=reboot"      evaluate menuset-unloadmenuvar

Modified: stable/10/sys/boot/i386/loader/loader.rc
==============================================================================
--- stable/10/sys/boot/i386/loader/loader.rc	Mon Mar  3 00:27:51 2014	(r262700)
+++ stable/10/sys/boot/i386/loader/loader.rc	Mon Mar  3 07:16:39 2014	(r262701)
@@ -5,7 +5,7 @@
 include /boot/loader.4th
 
 \ Reads and processes loader.conf variables
-start
+initialize
 
 \ Tests for password -- executes autoboot first if a password was defined
 check-password



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201403030716.s237Ge5I073823>