]>
code.delx.au - refind/blob - refind-mkdefault
7f673db46edf25f8a275441935514908bb6117c4
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/>.
30 from subprocess
import Popen
, PIPE
31 from argparse
import ArgumentParser
35 """Extract boot entry and boot order information.
38 boot_entries, boot_order
40 command
= "efibootmgr -v"
41 bootinfo_bytes
= (Popen(shlex
.split(command
), stdout
=PIPE
)
43 bootinfo
= (bootinfo_bytes
.decode(encoding
="utf-8", errors
="ignore")
51 boot_order
= s
.split(":")[1].replace(" ", "").split(",")
55 # On Boot#### lines, #### is characters 4-8....
57 # ....and the description starts at character 10
60 # In normal efibootmgr output, only Boot#### entries
61 # have characters 4-8 that can be interpreted as
62 # hex values, so this will harmlessly error out on all
63 # but Boot#### entries....
65 boot_entries
[hex_value
] = name
68 return boot_entries
, boot_order
71 def add_unordered_entry(boot_entries
, boot_order
, label
):
72 """Find a rEFInd boot_entry and add it to the boot_order list.
74 Run if the boot_order list includes no rEFInd entry, in the
75 hopes of finding an existing rEFInd boot_entry that can be
78 Dictionary of boot entries, with string (hex-encoded number) as
79 key and description as value
81 List of boot numbers as strings, in boot order
83 String used to identify rEFInd entry in efibootmgr output
85 True if an entry was added, False otherwise
88 for boot_num
, description
in boot_entries
.items():
89 if label
.lower() in description
.lower():
90 print("Adding Boot{} from boot options list.".format(boot_num
))
91 boot_order
.insert(0, boot_num
)
96 def set_refind_first(boot_entries
, boot_order
, label
):
97 """Adjust boot_order so that rEFInd is first.
100 Dictionary of boot entries, with string (hex-encoded number) as
101 key and description as value
103 List of boot numbers as strings, in boot order
105 String used to identify rEFInd entry in efibootmgr output
107 True if order adjusted, False otherwise
109 first_refind_number
= i
= -1
110 changed_order
= False
111 found_first_refind
= ""
112 show_multiple_warning
= True
113 for entry
in boot_order
:
115 if label
.lower() in boot_entries
[entry
].lower():
116 if found_first_refind
:
117 if show_multiple_warning
:
118 print("Found multiple {} entries! The earliest in the boot order will be made".format(label
))
119 print("the default, but this may not be what you want. Manually checking with")
120 print("efibootmgr is advisable!\n")
121 show_multiple_warning
= False
123 found_first_refind
= entry
124 first_refind_number
= i
125 if first_refind_number
== -1:
126 if add_unordered_entry(boot_entries
, boot_order
, label
):
129 print("{} was not found in the boot options list!".format(label
))
130 print("You should create a {} entry with efibootmgr or by re-installing".format(label
))
131 print("(with refind-install, for example)")
132 elif first_refind_number
== 0:
133 print("{} is already the first entry".format(label
))
134 elif first_refind_number
> 0:
135 del boot_order
[first_refind_number
]
136 boot_order
.insert(0, found_first_refind
)
139 print("{} is not the first boot entry; adjusting....".format(label
))
143 def save_changes(boot_order
):
144 """Save an altered boot_order.
147 List of boot numbers as strings, in boot order
149 True if there were no problems, False otherwise
151 order_string
= ",".join(boot_order
)
152 command
= "efibootmgr -o {}".format(order_string
)
153 print("Setting a boot order of {}".format(order_string
))
155 Popen(shlex
.split(command
), stdout
=PIPE
).communicate()[0]
157 print("An error occurred setting the new boot order!")
161 """Set rEFInd as the default boot option."""
162 description
= "Sets rEFInd as the default EFI boot option"
163 parser
= ArgumentParser(description
=description
)
164 parser
.add_argument("-L", "--label",
166 help=("The label used to identify rEFInd (default=rEFInd)"))
167 args
= parser
.parse_args()
169 if sys
.platform
!= "linux":
170 print("This program is useful only under Linux; exiting!")
172 if shutil
.which("efibootmgr") is None:
173 print("The efibootmgr utility is not installed; exiting!")
175 if not os
.geteuid() == 0:
176 print("This program must be run as root (or via sudo); exiting!")
181 boot_entries
, boot_order
= discover_data()
182 if boot_entries
== {}:
184 print("No EFI boot entries are available. This may indicate a firmware problem.")
187 print("The EFI BootOrder variable is not available. This may indicate a firmware")
190 set_refind_first(boot_entries
, boot_order
, args
.label
)):
191 save_changes(boot_order
)
195 print("No changes saved.")
198 if __name__
== '__main__':