forked from hamishcoleman/thinkpad-ec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMakefile
463 lines (384 loc) · 14.2 KB
/
Makefile
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
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
#
# Infrastructure to manage patching thinkpad EC firmware
#
# Copyright (C) 2016-2019 Hamish Coleman
#
all: list_laptops
$(info See README file for additional details)
$(info )
.PHONY: all
QEMU_OPTIONS ?= -enable-kvm
# FIXME - the date should be the date of the last commit, unless the repo is
# dirty, in which case, it should be the date of the last change.
GITVERSION = $(shell git describe --dirty --abbrev=6 ) ($(shell date +%Y%m%d))
BUILDINFO = $(GITVERSION) $(MAKECMDGOALS)
LIST_PATCHED = $(basename $(shell grep ^patched Descriptions.txt |cut -d" " -f1))
list_laptops:
$(info )
$(info The following make targets are the supported usb images:)
$(info )
@for i in $(LIST_PATCHED); do \
echo "$$i.img\t- `scripts/describe $$i.iso`"; \
done
@echo
.PHONY: list_laptops
DEPSDIR := .d
$(shell mkdir -p $(DEPSDIR))
test: $(addsuffix .iso,$(LIST_PATCHED)) $(addsuffix .img,$(LIST_PATCHED))
ALL_IMG_ORIG := $(addsuffix .orig,$(shell grep rule:IMG Descriptions.txt |cut -d" " -f1))
test.img.orig: $(ALL_IMG_ORIG)
.PHONY: test.pgm
test.pgm: $(addsuffix .pgm,$(ALL_IMG_ORIG))
# Generate a useful report
test.report:
@echo
@echo Report summaries for generated images:
@echo
@for i in $(LIST_PATCHED); do \
echo "Report for $$i\t- `scripts/describe $$i.iso`"; \
cat $$i.iso.report; \
echo; \
echo; \
done
@echo Checksums for generated images:
@echo
@sha256sum *.iso *.img
# TODO
# - add tests for the non xx30 supported things
# Remove all the locally generated junk (including any patched firmware
# images) and any small downloads
clean:
rm -f $(CLEAN_FILES) \
patched.*.iso patched.*.img *.FL2 *.FL2.orig *.img.enc \
*.img.enc.orig *.img.orig *.bat *.report \
*.img \
*.txt.orig
rm -rf *.iso.extract *.iso.orig.extract
# Also remove the large iso images downloaded from remote servers.
really_clean: clean
rm -f *.iso.orig .config
# TODO - whilst this could be added to the "pretty named" list, I think
# that it is more useful to use the new generated rules framework to allow
# asking for the iso image by name - in this case "g1uj25us.iso"
#patched.t430.257.iso: g1uj25us.iso
# $(call patched_iso,$<,$@)
list_iso:
$(info )
$(info This list was a duplicate of the list_laptops list - please refer to that)
$(info )
@false
.PHONY: list_iso
# FIXME - need to automatically generate the iso image target list
list_images:
$(info The following make targets are available to produce firmware images:)
$(info )
$(info $(basename $(wildcard *.d)))
$(info )
$(info Check the Descriptions.txt for the names of the known FL2 files)
$(info )
@true
.PHONY: list_images
# All the bios update iso images I have checked have had a fat16 filesystem
# embedded in a dos mbr image as the el-torito ISO payload. Most of them
# had the same offset to this fat filesystem, so hardcode that offset here.
# FIXME:
# - checking the E330 image showed a different FAT_OFFSET, need to handle that
# The offset value is bytes in decimal.
FAT_OFFSET := 71680
# Some versions of mtools need this flag set to allow them to work with the
# dosfs images used by Lenovo - from my tests, it may be that Debian has
# applied some patch
export MTOOLS_SKIP_CHECK=1
# At least one distribution has set this value poorly for our scripts in their
# global /etc/mtools.conf file, so we set it back to the default value here.
export MTOOLS_LOWER_CASE=0
build-deps:
apt -y install git mtools libssl-dev build-essential xorriso
#
# Radare didnt seem to let me specify the directory to store the project file,
# so this target hacks around that
#
install.radare.projects:
mkdir -p ~/.config/radare2/projects/x220.8DHT34WW.d
cp -fs $(PWD)/radare/x220.8DHT34WW ~/.config/radare2/projects
mkdir -p ~/.config/radare2/projects/x230.G2HT35WW
cp -fs $(PWD)/radare/x230.G2HT35WW ~/.config/radare2/projects/x230.G2HT35WW/rc
mkdir -p ~/.config/radare2/projects/x260.R02HT29W.d/
cp -fs $(PWD)/radare/x260.R02HT29W ~/.config/radare2/projects
.config:
cp defconfig .config
include .config
PATCHES-$(CONFIG_KEYBOARD) += \
001_keysym.patch 002_dead_keys.patch 003_keysym_replacements.patch \
004_fn_keys.patch 005_fn_key_swap.patch
PATCHES-$(CONFIG_BATTERY) += \
006_battery_validate.patch
# To enable other misc patches:
# - add a new CONFIG_something value to the defconfig and .config
# - add a new PATCHES-$(CONFIG_something) line referencing the patch
# - optionally, add a patch_enable/patch_disable stanza
# - however, that will get messy quickly, so perhaps a real config target
#
# These enable and disable targets change which patches are configured to be
# applied.
# TODO - actually edit the .config, dont just keep appending new stuff to it
patch_enable_battery:
echo "CONFIG_BATTERY = y" >>.config
patch_disable_battery:
echo "CONFIG_BATTERY = n" >>.config
patch_enable_keyboard:
echo "CONFIG_KEYBOARD = y" >>.config
patch_disable_keyboard:
echo "CONFIG_KEYBOARD = n" >>.config
# TODO - the scripts/describe output depends on Descriptions.txt -
# could parse that file and create some deps
#
# Download any ISO image that we have a checksum for
# NOTE: makes an assumption about the Lenovo URL not changing
.PRECIOUS: %.iso.orig
%.iso.orig:
@echo -n "Downloading "
@scripts/describe $(basename $@)
@wget -nv -O $@ https://download.lenovo.com/pccbbs/mobiles/$(basename $@)
scripts/checksum --mv_on_fail $@ $(basename $@)
@touch $@
# Download any README text file released alongside to ISO images.
# Useful for looking up firmware versions and the changelog.
# Note that Lenovo produces two sets of release notes: *uc.txt and
# *.us.txt - the "us" ones contain instructions for using the .exe
# version of the bios update tool instead of the instructions for
# bootable cdrom image, but other than that they /should/ be identical
# NOTE: we download the one with the same name as the ISO, even if that is
# wrong (it removes a bunch of edge cases)
%.txt.orig:
@echo -n "Downloading release notes for "
@scripts/describe $(subst .txt.orig,.iso,$@)
wget -O $@ https://download.lenovo.com/pccbbs/mobiles/$(basename $@)
# keep intermediate files
.PRECIOUS: %.orig
.PRECIOUS: %.img
.PRECIOUS: %.img.orig
# Generate a working file with any known patches applied
%.img: %.img.orig
@cp --reflink=auto $< $@
./scripts/hexpatch.pl --rm_on_fail --fail_on_missing --report [email protected] $@ $(addprefix [email protected]/,$(PATCHES-y))
# using both __DIR and __FL2 is a hack to get around needing to quote the
# DOS path separator. It feels like there should be a better way if I put
# my mind to it..
#
%.iso.bat: %.iso.orig autoexec.bat.template
@sed -e "s%__DIR%`mdir -/ -b -i $<@@$(FAT_OFFSET) |grep FL2 |head -1|cut -d/ -f3`%; s%__FL2%`mdir -/ -b -i $<@@$(FAT_OFFSET) |grep FL2 |head -1|cut -d/ -f4`%" autoexec.bat.template >[email protected]
@mv [email protected] $@
# helper to write the ISO onto a cdrw
%.iso.blank_burn: %.iso
wodim -eject -v speed=40 -tao gracetime=0 blank=fast $<
# if you want to work on more patches, you probably want the pre-patched ver
%.img.prepatch: %.img.orig
cp --reflink=auto $< $(basename $<)
%.hex: %
hd -v $< >[email protected]
mv [email protected] $@
# Generate a patch report
%.diff: %.hex %.orig.hex
-diff -u $(basename $@).orig.hex $(basename $@).hex >[email protected]
mv [email protected] $@
cat $@
# If we ever want a copy of the dosflash.exe, just get it from the iso image
%.dosflash.exe.orig: %.iso.orig
mcopy -m -i $^@@$(FAT_OFFSET) ::FLASH/DOSFLASH.EXE $@
# Extract the "embedded" fat file system from a given iso.
%.iso.extract: %.iso
mcopy -n -s -i $^@@$(FAT_OFFSET) :: $@
%.iso.orig.extract: %.iso.orig
mcopy -n -s -i $^@@$(FAT_OFFSET) :: $@
## Use the system provided geteltorito script, if there is one
#GETELTORITO := $(shell if type geteltorito >/dev/null; then echo geteltorito; else echo ./geteltorito; fi)
# use the included geteltorito script always, since we know it does not have
# the hdd size bug
GETELTORITO := ./scripts/geteltorito
# extract the DOS boot image from an iso (and fix it up so qemu can boot it)
%.img: %.iso
$(GETELTORITO) -o [email protected] $<
./scripts/fix_mbr [email protected]
@mv [email protected] $@
$(call build_info,$<)
# $1 is the base name of the ISO file built
define build_info
@echo
@echo
@echo Your build has completed with the following details:
@echo
@echo "Built ISO: `sha1sum $1`"
@cat $1.report
endef
# Add information about the FL2 file to the current report
# $< is the IMG file
# $@ is the FL2 file being inserted into
define buildinfo_FL2
@echo "Buildinfo: $(BUILDINFO)" >[email protected]
@echo "Built FL2: `sha1sum $@`" >>[email protected]
@echo "" >>[email protected]
@cat $<.report >>[email protected]
endef
# Add information about the ISO file to the current report
# $< is the FL2 file
# $@ is the ISO file being inserted into
define buildinfo_ISO
@echo "Based on code from: `scripts/describe $@`" >[email protected]
@cat $<.report >>[email protected]
@echo "" >>[email protected]
endef
# simple testing of images in an emulator
%.iso.test: %.iso
qemu-system-x86_64 $(QEMU_OPTIONS) -cdrom $<
%.img.test: %.img
qemu-system-x86_64 $(QEMU_OPTIONS) -hda $<
mec-tools/Makefile:
@[ -e .git ] || (echo ERROR: This must be run on a git clone of the repository; false)
git submodule update --init --remote
mec-tools/mec_encrypt: mec-tools/Makefile
git submodule update
make -C mec-tools
# Simple Visualisation
%.pgm: %
(echo "P5 256 $$(($(shell stat -c %s $<)/265)) 255" ; cat $< ) > $@
# Extract the FL2 file from an ISO image
#
# Note that the integrity of the FL2 file is determined by two things:
# - The sha1sum for the ISO.orig file has been checked
# - The ./scripts/ISO_copyFL2 script is generating correct data
# We believe these two statements are correct, so there is no need to check
# the checksum for the extracted FL2.orig file
#
# $@ is the FL2 file to create
# $< is the ISO file
# $1 is the pattern to match FL2 file in ISO image
define rule_FL2_extract
./scripts/ISO_copyFL2 from_iso $< $@ $(1)
endef
rule_FL2_extract_DEPS = scripts/ISO_copyFL2
# Extract and decyrpt the IMG file from an FL2 file
#
# $@ is the decrypted IMG to create
# $< is the FL2
define rule_IMG_extract
./scripts/FL2_copyIMG from_fl2 $< $(subst .orig,.enc.tmp,$@)
mec-tools/mec_encrypt -d $(subst .orig,.enc.tmp,$@) [email protected]
mec-tools/mec_csum_flasher -c [email protected] >/dev/null
mec-tools/mec_csum_boot -c [email protected] >/dev/null
@rm $(subst .orig,.enc.tmp,$@)
@mv [email protected] $@
endef
rule_IMG_extract_DEPS = scripts/FL2_copyIMG mec-tools/mec_encrypt mec-tools/mec_csum_flasher mec-tools/mec_csum_boot
# Create a new ISO image with patches applied
#
# $@ is the ISO to create
# $< is the FL2
# $1 is the pattern to match FL2 file in ISO image
define rule_FL2_insert
$(call buildinfo_ISO)
@cp --reflink=auto [email protected] [email protected]
@cp --reflink=auto $< $<.tmp
@cp --reflink=auto [email protected] [email protected]
@cp --reflink=auto [email protected] [email protected]
@touch -d @1 $<.tmp [email protected] [email protected]
@# TODO - datestamp here could be the lastcommitdatestamp
./scripts/ISO_copyFL2 to_iso [email protected] $<.tmp $(1)
mcopy -t -m -o -i [email protected]@@$(FAT_OFFSET) [email protected] ::report.txt
mcopy -t -m -o -i [email protected]@@$(FAT_OFFSET) [email protected] ::AUTOEXEC.BAT
-mdel -i [email protected]@@$(FAT_OFFSET) ::EFI/Boot/BootX64.efi
-mattrib -i [email protected]@@$(FAT_OFFSET) -r ::FLASH/README.TXT
-mdel -i [email protected]@@$(FAT_OFFSET) ::FLASH/README.TXT
@rm $<.tmp [email protected] [email protected]
@mv [email protected] $@
endef
rule_FL2_insert_DEPS = scripts/ISO_copyFL2 # TODO - bat file
# TODO
# - maybe mdel any FL1 files, so the image can not accidentally be used to
# flash the BIOS?
# - only delete the UEFI updater if it exists in the original ISO
# - continue removing variables from the AUTOEXEC bat - perhaps calculate
# its contents here
# - provide a simple mechanism for selecting the flash command to run, to
# allow for autoexec bat files that do not use dosflash
# Insert the new firmware into the FL2 file
#
# $@ is the FL2 to create
# $< is the IMG
define rule_IMG_insert
./scripts/xx30.encrypt $< $<.enc.tmp
@cp --reflink=auto [email protected] [email protected]
./scripts/FL2_copyIMG to_fl2 [email protected] $<.enc.tmp
@rm $<.enc.tmp
@mv [email protected] $@
$(call buildinfo_FL2)
endef
rule_IMG_insert_DEPS = scripts/FL2_copyIMG scripts/xx30.encrypt
# Take a built ISO file with Lenovo's name and rename it to a nice name
#
# $< is the lenovo named iso
# $@ is the nicely named iso
define rule_niceISO_extract
cp $< $@
cp $<.report [email protected]
$(call build_info,$@)
endef
rule_niceISO_extract_DEPS = # no extra dependancies
# Additional macros for any special cases:
# Extract the IMG file from an FL2 file - special case, without decryption
#
# $@ is the IMG to create
# $< is the FL2
define rule_IMGnoenc_extract
./scripts/FL2_copyIMG from_fl2 $< $@
endef
rule_IMGnoenc_extract_DEPS = scripts/FL2_copyIMG
# Insert the new firmware into the FL2 file - special case, without encryption
#
# $@ is the FL2 to create
# $< is the IMG
define rule_IMGnoenc_insert
cp --reflink=auto [email protected] [email protected]
./scripts/FL2_copyIMG to_fl2 [email protected] $<
mv [email protected] $@
$(call buildinfo_FL2)
endef
rule_IMGnoenc_insert_DEPS = scripts/FL2_copyIMG
# Extract the FL2 file from an ISO image with two FL2 files
#
# $@ is the FL2 file to create
# $< is the ISO file
# $1 is the pattern to match FL2 file in ISO image
# $2 is the second FL2 files, but this is ignored
define rule_FL2multi2_extract
$(call rule_FL2_extract,$1)
endef
rule_FL2multi2_extract_DEPS = $(rule_FL2_extract_DEPS)
# Create a new ISO image with patches applied - for images with two FL2 files
# with different names but the same content
#
# $@ is the ISO to create
# $< is the FL2
# $1 is the first FL2 pattern
# $2 is the second FL2 pattern
define rule_FL2multi2_insert
$(call rule_FL2_insert,$1)
./scripts/ISO_copyFL2 to_iso $@ $< $(2)
endef
rule_FL2multi2_insert_DEPS = $(rule_FL2_insert_DEPS)
# Extract the FL2 file from an old style ISO image with no Hard disk image
#
# $@ is the FL2 file to create
# $< is the ISO file
# $1 is the pattern to match FL2 file in ISO image
define rule_oldISO_extract
xorriso -osirrox on -indev $< -extract $(shell xorriso -osirrox on -indev $< -ls '*$(1)*' 2>/dev/null) $@ 2>/dev/null
@chmod a-x,u+w $@
@touch $@
endef
# Generate and include the rules that use the above macros
-include $(DEPSDIR)/generated.deps
CLEAN_FILES += $(DEPSDIR)/generated.deps
$(DEPSDIR)/generated.deps: scripts/generate_deps
$(DEPSDIR)/generated.deps: Descriptions.txt
@./scripts/generate_deps $< >$@