-
Notifications
You must be signed in to change notification settings - Fork 0
/
2019-12-25-how-to-fix-early-framebuffer-problems,-or-can-i-type-my-disk-password-yet.html
306 lines (272 loc) · 11.6 KB
/
2019-12-25-how-to-fix-early-framebuffer-problems,-or-can-i-type-my-disk-password-yet.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="alternate"
type="application/rss+xml"
href="https://blog.winny.tech/rss.xml"
title="RSS feed for https://blog.winny.tech/"/>
<title>How to fix early framebuffer problems, or "Can I type my disk password yet??"</title>
<link href="static/style.css?v=1.7" rel="stylesheet" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="preamble" class="status">
<nav>
<div class="flexcontainer">
<div class="smallitem">
blog.winny.tech
</div>
<div class="bigitem">
<ul class="inline-list">
<li><a href=".">Home</a></li>
<li><a href="archive.html">Archive</a></li>
<li><a href="tags.html">Tags</a></li>
<li><a href="rss.xml">RSS Feed</a></li>
</ul>
</div>
</div>
</nav>
<hr/>
</div>
<div id="content">
<div class="post-date">25 Dec 2019</div><h1 class="post-title"><a href="2019-12-25-how-to-fix-early-framebuffer-problems,-or-can-i-type-my-disk-password-yet.html">How to fix early framebuffer problems, or "Can I type my disk password yet??"</a></h1>
<p>
Most of my workstations & laptops require a passphrase typed in to
open the encrypted root filesystem. So my steps to booting are as
follows:
</p>
<ol class="org-ol">
<li>Power on machine</li>
<li>Wait for FDE passphrase prompt</li>
<li>Type in FDE passphrase</li>
<li>Wait for boot to complete and automatic XFCE session to start</li>
</ol>
<p>
Since I need to know when the computer is ready to accept the
passphrase, it is important the framebuffer is usable during the early
part of the boot. In the case of of HP Elitebook 820 G4, the EFI
framebuffer does not appear to work, and I rather not boot in BIOS
mode to get a functional VESA framebuffer. Making things more awkward,
a firmware is needed when the i915 driver is loaded, or the
framebuffer will not work either. (It’s not always clear if a firmware
is needed, so one should run <code>dmesg | grep -F firmware</code> and check if
firmware is being loaded.)
</p>
<p>
With this information, the problem is summarized to: <b>“How do I ensure
i915 is available at boot with the appropriate firmware?”</b>. This
question can be easily generalized to any framebuffer driver, as the
steps are more-or-less the same.
</p>
<div id="outline-container-org60590c1" class="outline-2">
<h2 id="org60590c1">Zeroth step: Do you need only a driver, or a driver with firmware?</h2>
<div class="outline-text-2" id="text-org60590c1">
<p>
IT is a good idea to verify if your kernel is missing a driver at
boot, or is missing firmware or both. Boot up a Live USB with good
hardware compatibility, such as <a href="http://grml.org/">GRML</a><sup><a id="fnr.1" class="footref" href="#fn.1">1</a></sup> or Ubuntu’s, and let’s see what
framebuffer driver our host is trying to use<sup><a id="fnr.2" class="footref" href="#fn.2">2</a></sup>:
</p>
<pre class="example">
$ dmesg | grep -i 'frame.*buffer'
[ 4.790570] efifb: framebuffer at 0xe0000000, using 8128k, total 8128k
[ 4.790611] fb0: EFI VGA frame buffer device
[ 4.820637] Console: switching to colour frame buffer device 240x67
[ 6.643895] i915 0000:00:02.0: fb1: i915drmfb frame buffer device
</pre>
<p>
Se we can see the efifb is initially used for a couple seconds, then
i915 is used for the rest of the computer’s uptime. Now let’s look
at if firmware is necessary, first checking if <code>modinfo(8)</code> knows of
any firmware:
</p>
<pre class="example">
$ modinfo i915 -F firmware
i915/bxt_dmc_ver1_07.bin
i915/skl_dmc_ver1_27.bin
i915/kbl_dmc_ver1_04.bin
... SNIP ...
i915/kbl_guc_33.0.0.bin
i915/icl_huc_ver8_4_3238.bin
i915/icl_guc_33.0.0.bin
</pre>
<p>
This indicates this driver will load firmware when available, and if
necessary for the particular mode of operation or hardware.
</p>
<p>
Now let’s look at dmesg to see if any firmware is loaded:
</p>
<pre class="example">
[ 0.222906] Spectre V2 : Enabling Restricted Speculation for firmware calls
[ 5.511731] [drm] Finished loading DMC firmware i915/kbl_dmc_ver1_04.bin (v1.4)
[ 25.579703] iwlwifi 0000:02:00.0: loaded firmware version 36.77d01142.0 op_mode iwlmvm
[ 25.612759] Bluetooth: hci0: Minimum firmware build 1 week 10 2014
[ 25.620251] Bluetooth: hci0: Found device firmware: intel/ibt-12-16.sfi
[ 25.712793] iwlwifi 0000:02:00.0: Allocated 0x00400000 bytes for firmware monitor.
[ 27.042080] Bluetooth: hci0: Waiting for firmware download to complete
</pre>
<p>
Aha! So it appears we need <code>i915/kbl_dmc_ver1_04.bin</code> for i915. In
the case case one doesn’t need firmware, it won’t show anything
related to <code>drm</code> or a line with your driver name in it.
</p>
<p>
By the way, it is a good idea to check dmesg for hints about missing
firmware, or alternative drivers, for example my trackpad is
supported by both i2c and synaptics based trackpad drivers, and the
kernel was kind enough to tell me.
</p>
</div>
</div>
<div id="outline-container-org47d680f" class="outline-2">
<h2 id="org47d680f">First step: Obtain the firmware</h2>
<div class="outline-text-2" id="text-org47d680f">
<p>
On Gentoo install
<code>sys-kernel/linux-firmware</code>. You will have to agree to some non-free
licenses; nothing too inane, but worth mentioning. Now just
run <code>emerge -av sys-kernel/linux-firmware</code>. (On other distros it
might be this easy, or more difficult; for example—in my experience
Debian does not ship every single firmware like Gentoo does, so
YMMV.)
</p>
</div>
</div>
<div id="outline-container-org2133291" class="outline-2">
<h2 id="org2133291">Second step, Option A: Compile firmware into your kernel</h2>
<div class="outline-text-2" id="text-org2133291">
<p>
Since most of my systems run Gentoo, it is business as usual to
deploy a kernel with most excess drivers disabled except for common
hot-swappable components such as USB network interfaces, audio
devices, and so on. For example, this laptop’s config was originally
derived from genkernel’ stock amd64 config with most extra drivers
disabled, then augmented with support for an Acer ES1-111M-C7DE,
and finally with support for this Elitebook.
</p>
<p>
I had compiled the kernel with i915 support built into the image, as
opposed to an additional kernel module. Unfortunately this meant the
kernel is unable to load firmware from filesystem, because it
appears only kernel modules can load firmware from filesystem. To
work around this without resorting to making i915 a kernel module,
we can include the drivers within the kernel image (<code>vmlinuz</code>).
Including firmware and drivers both in the vmlinuz has a couple
benefits. First it will always be available. There is no need to
figure out how to load the driver and firmware from initrd, let
alone getting the initrd generator one is using, to cooperate. A
downside is it makes the kernel very specific to the machine,
because perhaps a different Intel machine needs a different firmware
file compiled in.
</p>
<p>
To achieve including the firmware in kernel, I set the following
values in my kernel config (<code>.config</code> in your kernel source tree).
</p>
<pre class="example">
CONFIG_EXTRA_FIRMWARE="i915/kbl_dmc_ver1_04.bin"
CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"
</pre>
<p>
Note, if you’re using menuconfig, you can type <code>/EXTRA_FIRMWARE</code>
(slash for search, then the text) followed by keyboard return to
find where these settings exist in the menu system.
</p>
<p>
Then I verified i915 is indeed not a kernel module, but built into
the kernel image (it would be <code>m</code> if it’s a module):
</p>
<pre class="example">
CONFIG_DRM_I915=y
</pre>
<p>
After compiling & installing the kernel (and generating a dracut
initrd for cryptsetup/lvm), I was able to reboot and get an early
pre-mounted-root framebuffer on this device.
</p>
</div>
</div>
<div id="outline-container-orgccaf77f" class="outline-2">
<h2 id="orgccaf77f">Second step, Option B: A portable kernel approach (using <code>sys-kernel/vanilla-kernel</code>)</h2>
<div class="outline-text-2" id="text-orgccaf77f">
<p>
I discovered the Gentoo devs <a href="https://blogs.gentoo.org/mgorny/2019/12/19/a-distribution-kernel-for-gentoo/">have begun shipping an ebuild that
builds and installs a kernel with a portable, livecd friendly
config</a>. In addition this package will optionally generates an initrd
with dracut as a pkg<sub>postinst</sub> step, making it very suitable as a
replacement for users who just want a working kernel, and don’t mind
a excessive compatibility (at a cost to size and build time).
</p>
<p>
This presents a different challenge, because while this package does
allow the user to drop in their own .config, it is not very
multiple-machine-deployment friendly to hard-code each individual
firmware into the kernel. Instead we tell dracut to include our
framebuffer driver. As mentioned above I found this computer uses
the <code>i915</code> kernel driver for framebuffer. Let’s tell dracut to
include the driver:
</p>
<pre class="example">
cat > /etc/dracut.conf.d/i915.conf <<EOF
add_drivers+=" i915 "
EOF
</pre>
<p>
Dracut is smart enough to pick up the firmware the kernel module
needs, provided they are installed. To get an idea what firmware
dracut will include, run <code>modinfo i915 -F firmware</code> which will print
out a bunch of firmware relative paths.
</p>
<p>
After applying this fix, just regenerate your initrd using dracut; in
my case I let portage do the work:
<code>emerge -1av sys-kernel/vanilla-kernel</code>. Finally reboot.
</p>
</div>
</div>
<div id="outline-container-org89b02d2" class="outline-2">
<h2 id="org89b02d2">Conclusion</h2>
<div class="outline-text-2" id="text-org89b02d2">
<p>
Check dmesg. Always check dmesg. We found two ways to deploy
firmware, in-kernel and in-initrd. The in-kernel technique is best
for a device-specific kernel, the in-initrd is best for a portable
kernel. I am a big fan of the second technique because it scales
well to many machines.
</p>
<p>
I did not touch on the political side of using binary blobs. It
would be nice to not use any non-free software, but I rather have a
working system with a couple small non-free components, than a
non-working system. Which is more valuable, your freedom, or reduced
capacity of your tools?
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">
<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1">1</a></sup> <div class="footpara"><p class="footpara">
GRML is my favorite live media. It is simple, to the point, has
lots of little scripts to streamline tasks such as setting up a
wireless AP, a iPXE netboot environment, a router, installing debian,
and so on. And Remastering is relatively straight forward. It also has
a sane gui sutable for any machine (fluxbox).
</p></div></div>
<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2">2</a></sup> <div class="footpara"><p class="footpara">
Thanks to <a href="https://askubuntu.com/questions/727577/how-to-check-if-framebuffer-is-enabled">this post</a> on Ask Ubuntu
</p></div></div>
</div>
</div><div class="taglist"><a href="tags.html">Tags</a>: <a href="tag-gentoo.html">gentoo</a> <a href="tag-linux.html">linux</a> <a href="tag-computing.html">computing</a> </div></div>
<div id="postamble" class="status">
<hr/>
<ul class="inline-list interpunct">
<li>Powered by <a href="https://github.com/bastibe/org-static-blog">org-static-blog</a></li>
<li>Like what I do? <a href="https://www.buymeacoffee.com/winny">Buy me a Coffee</a></li>
</ul>
<p>© Winston Weinert (winny) — <a href="https://creativecommons.org/licenses/by-sa/4.0/legalcode">CC-BY-SA-4.0</a></p>
</div>
</body>
</html>