]>
code.delx.au - refind/blob - refind-mkdefault
325d38239f0eac4f4e6b00e61586a7091fcc317a
4 Set rEFInd as the default boot loader, using Linux's efibootmgr tool.
6 Copyright (c) 2016 Roderick W. Smith
9 Roderick W. Smith <rodsmith@rodsbooks.com>
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 3, or
13 (at your option) any later version, as published by the Free Software
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 from subprocess
import Popen
, PIPE
30 from argparse
import ArgumentParser
34 """Extract boot entry and boot order information.
37 boot_entries, boot_order
39 command
= "efibootmgr -v"
40 bootinfo_bytes
= (Popen(command
, stdout
=PIPE
, shell
=True)
42 bootinfo
= (bootinfo_bytes
.decode(encoding
="utf-8", errors
="ignore")
50 boot_order
= s
.split(":")[1].replace(" ", "").split(",")
54 # On Boot#### lines, #### is characters 4-8....
56 # ....and the description starts at character 10
59 # In normal efibootmgr output, only Boot#### entries
60 # have characters 4-8 that can be interpreted as
61 # hex values, so this will harmlessly error out on all
62 # but Boot#### entries....
64 boot_entries
[hex_value
] = name
67 return boot_entries
, boot_order
70 def add_unordered_entry(boot_entries
, boot_order
, label
):
71 """Find a rEFInd boot_entry and add it to the boot_order list.
73 Run if the boot_order list includes no rEFInd entry, in the
74 hopes of finding an existing rEFInd boot_entry that can be
77 Dictionary of boot entries, with string (hex-encoded number) as
78 key and description as value
80 List of boot numbers as strings, in boot order
82 String used to identify rEFInd entry in efibootmgr output
84 True if an entry was added, False otherwise
87 for boot_num
, description
in boot_entries
.items():
88 if label
.lower() in description
.lower():
89 print("Adding Boot{} from boot options list.".format(boot_num
))
90 boot_order
.insert(0, boot_num
)
95 def set_refind_first(boot_entries
, boot_order
, label
):
96 """Adjust boot_order so that rEFInd is first.
99 Dictionary of boot entries, with string (hex-encoded number) as
100 key and description as value
102 List of boot numbers as strings, in boot order
104 String used to identify rEFInd entry in efibootmgr output
106 True if order adjusted, False otherwise
108 first_refind_number
= i
= -1
109 changed_order
= False
110 found_first_refind
= ""
111 show_multiple_warning
= True
112 for entry
in boot_order
:
114 if label
.lower() in boot_entries
[entry
].lower():
115 if found_first_refind
:
116 if show_multiple_warning
:
117 print("Found multiple {} entries! The earliest in the boot order will be made".format(label
))
118 print("the default, but this may not be what you want. Manually checking with")
119 print("efibootmgr is advisable!\n")
120 show_multiple_warning
= False
122 found_first_refind
= entry
123 first_refind_number
= i
124 if first_refind_number
== -1:
125 if add_unordered_entry(boot_entries
, boot_order
, label
):
128 print("{} was not found in the boot options list!".format(label
))
129 print("You should create a {} entry with efibootmgr or by re-installing".format(label
))
130 print("(with refind-install, for example)")
131 elif first_refind_number
== 0:
132 print("{} is already the first entry".format(label
))
133 elif first_refind_number
> 0:
134 del boot_order
[first_refind_number
]
135 boot_order
.insert(0, found_first_refind
)
138 print("{} is not the first boot entry; adjusting....".format(label
))
142 def save_changes(boot_order
):
143 """Save an altered boot_order.
146 True if there were no problems, False otherwise
148 order_string
= ",".join(boot_order
)
149 command
= "efibootmgr -o {}".format(order_string
)
150 print("Setting a boot order of {}".format(order_string
))
152 Popen(command
, stdout
=PIPE
, shell
=True).communicate()[0]
154 print("An error occurred setting the new boot order!")
158 """Set rEFInd as the default boot option."""
159 description
= "Sets rEFInd as the default EFI boot option"
160 parser
= ArgumentParser(description
=description
)
161 parser
.add_argument("-L", "--label",
163 help=("The label used to identify rEFInd"))
164 args
= parser
.parse_args()
166 if sys
.platform
!= "linux":
167 print("This program is useful only under Linux; exiting!")
169 if shutil
.which("efibootmgr") is None:
170 print("The efibootmgr utility is not installed; exiting!")
172 if not os
.geteuid() == 0:
173 print("You must be root to run this program")
178 boot_entries
, boot_order
= discover_data()
179 if boot_entries
== {}:
181 print("No EFI boot entries available. This may indicate a firmware problem.")
184 print("The EFI BootOrder variable is not available. This may indicate a firmware")
186 if (boot_entries
!= {} and boot_order
!= [] and
187 set_refind_first(boot_entries
, boot_order
, args
.label
)):
188 save_changes(boot_order
)
192 print("No changes saved.")
195 if __name__
== '__main__':