]>
code.delx.au - refind/blob - refind-mkdefault
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 * -1 if order already OK
108 * 0 if order adjusted
109 * 3 if label was not found in available entries
111 first_refind_number
= i
= -1
113 found_first_refind
= ""
114 show_multiple_warning
= True
115 for entry
in boot_order
:
117 if label
.lower() in boot_entries
[entry
].lower():
118 if found_first_refind
:
119 if show_multiple_warning
:
120 print("Found multiple {} entries! The earliest in the boot order will be made".format(label
))
121 print("the default, but this may not be what you want. Manually checking with")
122 print("efibootmgr is advisable!\n")
123 show_multiple_warning
= False
125 found_first_refind
= entry
126 first_refind_number
= i
127 if first_refind_number
== -1:
128 if not 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)")
133 elif first_refind_number
== 0:
134 print("{} is already the first entry".format(label
))
136 elif first_refind_number
> 0:
137 del boot_order
[first_refind_number
]
138 boot_order
.insert(0, found_first_refind
)
140 print("{} is not the first boot entry; adjusting....".format(label
))
144 def save_changes(boot_order
):
145 """Save an altered boot_order.
148 List of boot numbers as strings, in boot order
150 0 if there were no problems, 1 otherwise
153 order_string
= ",".join(boot_order
)
154 command
= "efibootmgr -o {}".format(order_string
)
155 print("Setting a boot order of {}".format(order_string
))
157 Popen(shlex
.split(command
), stdout
=PIPE
).communicate()[0]
159 print("An error occurred setting the new boot order!")
165 """Set rEFInd as the default boot option."""
166 description
= "Sets rEFInd as the default EFI boot option"
167 parser
= ArgumentParser(description
=description
)
168 parser
.add_argument("-L", "--label",
170 help=("The label used to identify rEFInd (default=rEFInd)"))
171 args
= parser
.parse_args()
173 if sys
.platform
!= "linux":
174 print("This program is useful only under Linux; exiting!")
176 if shutil
.which("efibootmgr") is None:
177 print("The efibootmgr utility is not installed; exiting!")
179 if not os
.geteuid() == 0:
180 print("This program must be run as root (or via sudo); exiting!")
184 boot_entries
, boot_order
= discover_data()
185 if boot_entries
== {}:
186 print("No EFI boot entries are available. This may indicate a firmware problem.")
189 print("The EFI BootOrder variable is not available. This may indicate a firmware")
192 changed
= set_refind_first(boot_entries
, boot_order
, args
.label
)
194 retval
= save_changes(boot_order
)
196 print("No changes saved.")
200 print("No changes saved.")
203 if __name__
== '__main__':