mirror of
http://cgit.git.savannah.gnu.org/git/grub.git
synced 2026-04-28 14:33:34 +00:00
Compare commits
181 Commits
phcoder/ar
...
phcoder/ve
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2cdd6159d7 | ||
|
|
ba5401b197 | ||
|
|
4f280d955e | ||
|
|
09bd17faaa | ||
|
|
aa93127ed8 | ||
|
|
c4b8bec5fe | ||
|
|
70b555a52a | ||
|
|
c6eaa982d1 | ||
|
|
5c3fd1b135 | ||
|
|
b0b1b81a11 | ||
|
|
c4313c812d | ||
|
|
4f8471532d | ||
|
|
d11ced1e1f | ||
|
|
058df7b5a9 | ||
|
|
265292f2b0 | ||
|
|
656c3b0d7f | ||
|
|
3edabad8fe | ||
|
|
848bed9d92 | ||
|
|
216950a4ee | ||
|
|
ac6b41b89f | ||
|
|
5a865b3786 | ||
|
|
fcbb723d4b | ||
|
|
24e37a8852 | ||
|
|
9808c3ef95 | ||
|
|
1daa716c70 | ||
|
|
461bfab7b7 | ||
|
|
d08c968514 | ||
|
|
a35ac85430 | ||
|
|
d9f7de0ae3 | ||
|
|
dc6e1b5af8 | ||
|
|
ede6c96893 | ||
|
|
a827807a13 | ||
|
|
1073ddb120 | ||
|
|
4341f82af0 | ||
|
|
c2ea443446 | ||
|
|
608bec5112 | ||
|
|
6dec3a26b3 | ||
|
|
b43b8cacc8 | ||
|
|
37865c2c4a | ||
|
|
5a0c548ba3 | ||
|
|
b0bad6fd94 | ||
|
|
e54c99aaff | ||
|
|
d454509bb8 | ||
|
|
007f0b407f | ||
|
|
4bd4a88725 | ||
|
|
6cef7f6079 | ||
|
|
ec4af117c6 | ||
|
|
8014b7b337 | ||
|
|
fcea891e17 | ||
|
|
c42cb97f08 | ||
|
|
bcf3c55531 | ||
|
|
fb93c75bdd | ||
|
|
641bb15fa4 | ||
|
|
f34ed1f53c | ||
|
|
892dfbe113 | ||
|
|
951306c509 | ||
|
|
512bb31cbc | ||
|
|
2fb8cd26a9 | ||
|
|
529818738f | ||
|
|
8a96fc4093 | ||
|
|
f3df8f961f | ||
|
|
ec4aca088a | ||
|
|
fcb1528d93 | ||
|
|
c36c0e05f1 | ||
|
|
c96cfac167 | ||
|
|
bf94ef7fbd | ||
|
|
5412028d19 | ||
|
|
c65d35b08b | ||
|
|
a5bd52990e | ||
|
|
1d4e3db907 | ||
|
|
4e5414b2a1 | ||
|
|
1402cdd96a | ||
|
|
31932a267c | ||
|
|
393cc59195 | ||
|
|
dac87d6032 | ||
|
|
42e24b6006 | ||
|
|
08438d783f | ||
|
|
34fe0b5901 | ||
|
|
377c121170 | ||
|
|
43b444e593 | ||
|
|
ea20dd2b22 | ||
|
|
3d173955f0 | ||
|
|
68c6cec061 | ||
|
|
0704e83a1b | ||
|
|
f14c77f501 | ||
|
|
0fd9fa565b | ||
|
|
6f5aa28bc2 | ||
|
|
a134ef1ab9 | ||
|
|
255b9e0bea | ||
|
|
b53f595b3e | ||
|
|
6371e9c104 | ||
|
|
d15f17b2a0 | ||
|
|
a0413e2677 | ||
|
|
43dbf83aa2 | ||
|
|
bec592aa87 | ||
|
|
79fc008935 | ||
|
|
bf9c561670 | ||
|
|
afa9dda37e | ||
|
|
cde63a3bb0 | ||
|
|
bf0e59cebf | ||
|
|
a2932fbe8a | ||
|
|
972765fe82 | ||
|
|
07662af7ae | ||
|
|
562c406763 | ||
|
|
ce95549cc5 | ||
|
|
a3e9da054d | ||
|
|
130234bc78 | ||
|
|
7b4c54c4ad | ||
|
|
0d2345774d | ||
|
|
c9a8d037a8 | ||
|
|
f8c3af3b61 | ||
|
|
0af7539bd2 | ||
|
|
0d663b50b9 | ||
|
|
28511b0da9 | ||
|
|
e1b099fb69 | ||
|
|
fbca374105 | ||
|
|
5f311e86d2 | ||
|
|
0de3eeb623 | ||
|
|
b67a95ecad | ||
|
|
5500cefccd | ||
|
|
d73976fdff | ||
|
|
1fbb2b4b39 | ||
|
|
c221ea06b5 | ||
|
|
72c28509fa | ||
|
|
7e5fcb0b34 | ||
|
|
6ae55ce103 | ||
|
|
c69d1858f1 | ||
|
|
4231927e44 | ||
|
|
a620876e3b | ||
|
|
f2b6c20a25 | ||
|
|
ba89c19f49 | ||
|
|
9862b24121 | ||
|
|
e563928ba4 | ||
|
|
a0bf403f66 | ||
|
|
4e0f8f66e3 | ||
|
|
c831d2073b | ||
|
|
52408aa946 | ||
|
|
58590cb2ef | ||
|
|
b524fa27f5 | ||
|
|
e045af148a | ||
|
|
13f7ead3a1 | ||
|
|
7a5b301e3a | ||
|
|
abf9beb7d6 | ||
|
|
f4d35d49e3 | ||
|
|
6714d7ecff | ||
|
|
5b8ddf6e03 | ||
|
|
76eac44af3 | ||
|
|
ee83919e93 | ||
|
|
3c3e96d044 | ||
|
|
15aee573d2 | ||
|
|
7f2a856fae | ||
|
|
9545a8fd04 | ||
|
|
082bc9f77b | ||
|
|
d017ea8ede | ||
|
|
8207874e5d | ||
|
|
102e435d81 | ||
|
|
51f375d688 | ||
|
|
ca028db3d4 | ||
|
|
0f076d75d0 | ||
|
|
86ef66d977 | ||
|
|
5bcb7d394c | ||
|
|
df21fff504 | ||
|
|
73a9c742fe | ||
|
|
dd3969e7ec | ||
|
|
36212460d3 | ||
|
|
2ebef43cf6 | ||
|
|
8c26dace6f | ||
|
|
070e190305 | ||
|
|
109189ce01 | ||
|
|
b00e4c2bd9 | ||
|
|
06a3b0b214 | ||
|
|
5486a4e12b | ||
|
|
eb9f401fc1 | ||
|
|
94c56a4c65 | ||
|
|
1b782e902e | ||
|
|
15dfea842c | ||
|
|
054d1325e9 | ||
|
|
0678b5d629 | ||
|
|
be4e9d20a5 | ||
|
|
bc220962e3 | ||
|
|
625934ec0f |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -246,3 +246,4 @@ build-aux/test-driver
|
||||
/garbage-gen
|
||||
/garbage-gen.exe
|
||||
/grub-fs-tester
|
||||
grub-core/build-grub-module-verifier
|
||||
|
||||
7
INSTALL
7
INSTALL
@@ -15,15 +15,14 @@ configuring the GRUB.
|
||||
Note: older versions may work but support is limited
|
||||
|
||||
Experimental support for clang 3.3 or later (results in much bigger binaries)
|
||||
for i386, x86_64, arm (except thumb), arm64, mips(el), powerpc, sparc64
|
||||
for i386, x86_64, arm (including thumb), arm64, mips(el), powerpc, sparc64
|
||||
Note: clang 3.2 or later works for i386 and x86_64 targets but results in
|
||||
much bigger binaries.
|
||||
earlier versions not tested
|
||||
Note: clang 3.2 or later works for arm
|
||||
None of tested clang versions generated usable thumb code
|
||||
earlier versions not tested
|
||||
Note: clang 3.3 or later works for arm64
|
||||
earlier versions have no arm64 support
|
||||
Note: clang on arm64 is not supported due to
|
||||
https://llvm.org/bugs/show_bug.cgi?id=26030
|
||||
Note: clang 3.3 or later works for mips(el)
|
||||
earlier versions fail to generate .reginfo and hence gprel relocations
|
||||
fail.
|
||||
|
||||
67
Makefile.am
67
Makefile.am
@@ -145,109 +145,116 @@ if COND_real_platform
|
||||
|
||||
if COND_i386_coreboot
|
||||
QEMU32=qemu-system-i386
|
||||
MINIMUM_CPU_LINUX=pentium2
|
||||
endif
|
||||
|
||||
if COND_i386_multiboot
|
||||
QEMU32=qemu-system-i386
|
||||
MINIMUM_CPU_LINUX=pentium2
|
||||
endif
|
||||
|
||||
if COND_i386_ieee1275
|
||||
QEMU32=qemu-system-i386
|
||||
MINIMUM_CPU_LINUX=pentium2
|
||||
endif
|
||||
|
||||
if COND_i386_qemu
|
||||
QEMU32=qemu-system-i386
|
||||
MINIMUM_CPU_LINUX=pentium2
|
||||
endif
|
||||
|
||||
if COND_i386_pc
|
||||
QEMU32=qemu-system-i386
|
||||
MINIMUM_CPU_LINUX=pentium2
|
||||
endif
|
||||
|
||||
if COND_i386_efi
|
||||
QEMU32=qemu-system-i386
|
||||
MINIMUM_CPU_LINUX=pentium2
|
||||
endif
|
||||
|
||||
if COND_x86_64_efi
|
||||
QEMU32=qemu-system-x86_64
|
||||
MINIMUM_CPU_LINUX=core2duo
|
||||
endif
|
||||
|
||||
linux.init.x86_64: $(srcdir)/grub-core/tests/boot/linux.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
$(TARGET_CC) -o $@ $< -static -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux.init.i386: $(srcdir)/grub-core/tests/boot/linux.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
$(TARGET_CC) -o $@ $< -static -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux.init.mips: $(srcdir)/grub-core/tests/boot/linux.init-mips.S
|
||||
$(TARGET_CC) -o $@ $< -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
$(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux.init.ppc: $(srcdir)/grub-core/tests/boot/linux.init-ppc.S
|
||||
$(TARGET_CC) -o $@ $< -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
$(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux.init.mipsel: $(srcdir)/grub-core/tests/boot/linux.init-mips.S
|
||||
$(TARGET_CC) -o $@ $< -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
$(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux.init.loongson: $(srcdir)/grub-core/tests/boot/linux.init-mips.S
|
||||
$(TARGET_CC) -o $@ $< -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -DREBOOT=1
|
||||
$(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -DREBOOT=1
|
||||
|
||||
multiboot.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -DTARGET_MULTIBOOT=1 -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include
|
||||
$(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -static -ffreestanding -nostdlib -nostdinc -DTARGET_MULTIBOOT=1 -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include
|
||||
|
||||
kfreebsd.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include
|
||||
$(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -static -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include
|
||||
|
||||
kfreebsd.aout: kfreebsd.elf
|
||||
$(TARGET_OBJCOPY) -O a.out-i386-linux $< $@ -R .note.gnu.build-id -R .note.gnu.gold-version
|
||||
$(TARGET_OBJCOPY) -O a.out-i386-linux $< $@ -j .text
|
||||
|
||||
pc-chainloader.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -DTARGET_CHAINLOADER=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x7c00 -m32
|
||||
$(TARGET_CC) -o $@ $< -static -DTARGET_CHAINLOADER=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x7c00 -m32
|
||||
|
||||
pc-chainloader.bin: pc-chainloader.elf
|
||||
$(TARGET_OBJCOPY) -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@;
|
||||
|
||||
ntldr.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -DTARGET_NTLDR=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0 -m32
|
||||
$(TARGET_CC) -o $@ $< -DTARGET_NTLDR=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -static -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0 -m32
|
||||
|
||||
ntldr.bin: ntldr.elf
|
||||
$(TARGET_OBJCOPY) -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@;
|
||||
$(TARGET_OBJCOPY) -O binary --strip-unneeded -j .text $< $@;
|
||||
|
||||
multiboot2.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include -DTARGET_MULTIBOOT2=1
|
||||
$(TARGET_CC) -static -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include -DTARGET_MULTIBOOT2=1
|
||||
|
||||
kfreebsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kfreebsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@
|
||||
$(TARGET_CC) -o $@ $< -m64 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@
|
||||
|
||||
kfreebsd.init.i386: $(srcdir)/grub-core/tests/boot/kfreebsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@
|
||||
$(TARGET_CC) -o $@ $< -m32 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@
|
||||
|
||||
knetbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DTARGET_NETBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
$(TARGET_CC) -o $@ $< -m32 -static -nostdlib -nostdinc -DTARGET_NETBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
kopenbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DTARGET_OPENBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
$(TARGET_CC) -o $@ $< -m32 -static -nostdlib -nostdinc -DTARGET_OPENBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
knetbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m64 -DTARGET_NETBSD=1 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
$(TARGET_CC) -o $@ $< -m64 -DTARGET_NETBSD=1 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
kopenbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m64 -DTARGET_OPENBSD=1 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
$(TARGET_CC) -o $@ $< -m64 -DTARGET_OPENBSD=1 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux-initramfs.mips: linux.init.mips Makefile
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
|
||||
linux-initramfs.ppc: linux.init.ppc Makefile
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
|
||||
linux-initramfs.mipsel: linux.init.mipsel Makefile
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
|
||||
linux-initramfs.loongson: linux.init.loongson Makefile
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
|
||||
linux-initramfs.i386: linux.init.i386 Makefile
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
|
||||
linux-initramfs.x86_64: linux.init.x86_64 Makefile
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR
|
||||
|
||||
kfreebsd-mfsroot.i386.img: kfreebsd.init.i386 Makefile
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR
|
||||
@@ -306,7 +313,7 @@ bootcheck-knetbsd-x86_64: knetbsd.miniroot-image.x86_64.gz $(GRUB_PAYLOADS_DIR)/
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/miniroot.gz=knetbsd.miniroot-image.x86_64.gz --files=/knetbsd=$(GRUB_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/grub-core/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-linux-i386: linux-initramfs.i386 $(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg --qemu-opts="-cpu $(MINIMUM_CPU_LINUX)" | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-linux-x86_64: linux-initramfs.x86_64 $(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
@@ -369,6 +376,12 @@ if COND_i386_coreboot
|
||||
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386
|
||||
endif
|
||||
|
||||
if COND_i386_ieee1275
|
||||
# *BSD requires ACPI
|
||||
#legacy protocol (linux16) makes early BIOS calls.
|
||||
BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64
|
||||
endif
|
||||
|
||||
if COND_i386_pc
|
||||
#pc chainloader by definition is only for i386-pc
|
||||
#ntldr and bootmgr require BIOS.
|
||||
@@ -410,7 +423,7 @@ bootcheck: $(BOOTCHECKS)
|
||||
|
||||
if COND_i386_coreboot
|
||||
default_payload.elf: grub-mkstandalone grub-mkimage FORCE
|
||||
rm $@
|
||||
test -f $@ && rm $@ || true
|
||||
pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(shell cat grub-core/fs.lst) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
|
||||
endif
|
||||
|
||||
|
||||
@@ -416,7 +416,7 @@ program = {
|
||||
ldadd = libgrubgcry.a;
|
||||
ldadd = libgrubkern.a;
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
||||
};
|
||||
|
||||
data = {
|
||||
|
||||
14
NEWS
14
NEWS
@@ -18,6 +18,7 @@ New in 2.02:
|
||||
* ZFS features support.
|
||||
* ZFS LZ4 support.
|
||||
* XFS V5 format support.
|
||||
* LVM RAID1 support.
|
||||
|
||||
* New/improved terminal and video support:
|
||||
* Monochrome text (matching `hercules' in GRUB Legacy).
|
||||
@@ -49,6 +50,9 @@ New in 2.02:
|
||||
* Improve TFTP robustness.
|
||||
* Parse `nd' disk names in GRUB Legacy configuration files.
|
||||
* Issue separate DNS queries for IPv4 and IPv6.
|
||||
* Support IPv6 Router Advertisement to configure default router.
|
||||
* New variable net_<interface>_next_server containing next server
|
||||
from BOOTP reply.
|
||||
|
||||
* Coreboot improvements:
|
||||
* CBFS support both in on-disk images (loopback) and flash.
|
||||
@@ -96,6 +100,8 @@ New in 2.02:
|
||||
EFI Stall. If everything fails, use hardcoded frequency 800MHz.
|
||||
* Support Hyper-V Gen2 platforms which lack PIT for TSC calibration.
|
||||
* Map UEFI Persistent Memory to E820 persistent memory.
|
||||
* New Xen loader on ARM64.
|
||||
* Respect alignment requirement for block device IO buffers on EFI.
|
||||
|
||||
* Security:
|
||||
* Add optional facility to enforce that all files read by the core image
|
||||
@@ -134,6 +140,11 @@ New in 2.02:
|
||||
menu entry immediately.
|
||||
* New `file' command and grub-file utility to check file types.
|
||||
* New syslinux configuration file parser.
|
||||
* Set menu entry class to primary OS name returned by os-prober to display
|
||||
OS specific icon.
|
||||
* On Linux x86 detect EFI word size in grub-install and automatically select
|
||||
correct platform (x86_64-efi or i386-efi) to install. Requires Linux kernel
|
||||
4.0 or higher.
|
||||
|
||||
* Build system:
|
||||
* Remove all uses of nested functions; GRUB no longer requires an
|
||||
@@ -160,6 +171,9 @@ New in 2.02:
|
||||
* emu libusb support removed (was broken and unmaintained).
|
||||
* powerpc64le compile support.
|
||||
* Use fixed timestamp when generating GRUB image for reproducible builds.
|
||||
* Verify at build time that modules contain only supported relocations and their
|
||||
structure matches what boot-time module loader expects.
|
||||
* Do not require fonts on powerpc-ieee1275.
|
||||
|
||||
* Revision control moved to git.
|
||||
|
||||
|
||||
52
acinclude.m4
52
acinclude.m4
@@ -390,6 +390,58 @@ else
|
||||
[fi]
|
||||
])
|
||||
|
||||
AC_DEFUN([grub_CHECK_LINK_PIE],[
|
||||
[# Position independent executable.
|
||||
link_nopie_needed=no]
|
||||
AC_MSG_CHECKING([whether linker needs disabling of PIE to work])
|
||||
AC_LANG_CONFTEST([AC_LANG_SOURCE([[]])])
|
||||
|
||||
[if eval "$ac_compile -Wl,-r,-d -nostdlib -Werror -o conftest.o" 2> /dev/null; then]
|
||||
AC_MSG_RESULT([no])
|
||||
[# Should we clear up other files as well, having called `AC_LANG_CONFTEST'?
|
||||
rm -f conftest.o
|
||||
else
|
||||
link_nopie_needed=yes]
|
||||
AC_MSG_RESULT([yes])
|
||||
[fi]
|
||||
])
|
||||
|
||||
|
||||
dnl Check if the Linker supports `-no-pie'.
|
||||
AC_DEFUN([grub_CHECK_NO_PIE],
|
||||
[AC_MSG_CHECKING([whether linker accepts -no-pie])
|
||||
AC_CACHE_VAL(grub_cv_cc_ld_no_pie,
|
||||
[save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -no-pie -nostdlib -Werror"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[grub_cv_cc_ld_no_pie=yes],
|
||||
[grub_cv_cc_ld_no_pie=no])
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
])
|
||||
AC_MSG_RESULT([$grub_cv_cc_ld_no_pie])
|
||||
nopie_possible=no
|
||||
if test "x$grub_cv_cc_ld_no_pie" = xyes ; then
|
||||
nopie_possible=yes
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([grub_CHECK_NO_PIE_ONEWORD],
|
||||
[AC_MSG_CHECKING([whether linker accepts -nopie])
|
||||
AC_CACHE_VAL(grub_cv_cc_ld_no_pie_oneword,
|
||||
[save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -nopie -nostdlib -Werror"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[grub_cv_cc_ld_no_pie_oneword=yes],
|
||||
[grub_cv_cc_ld_no_pie_oneword=no])
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
])
|
||||
AC_MSG_RESULT([$grub_cv_cc_ld_no_pie_oneword])
|
||||
nopie_oneword_possible=no
|
||||
if test "x$grub_cv_cc_ld_no_pie_oneword" = xyes ; then
|
||||
nopie_oneword_possible=yes
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Check if the C compiler supports `-fPIC'.
|
||||
AC_DEFUN([grub_CHECK_PIC],[
|
||||
[# Position independent executable.
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
/* on x86 old clang doesn't support .code16
|
||||
newer clang supports it but creates 6-byte jumps instead of 3-byte ones
|
||||
which makes us go over boot sector size. */
|
||||
which makes us go over boot sector size.
|
||||
Starting with 3.9 clang emits 3-byte jumps but still creates 8-bytes movl
|
||||
instead of 5-bytes, so code overflows into data. */
|
||||
|
||||
.code16
|
||||
jmp far
|
||||
.org 4
|
||||
jmp nearer
|
||||
.org 6
|
||||
movl nearer, %ebx
|
||||
.org 11
|
||||
.space 100
|
||||
nearer:
|
||||
.space 200
|
||||
|
||||
84
configure.ac
84
configure.ac
@@ -31,7 +31,7 @@ dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables
|
||||
dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are
|
||||
dnl used for the target type. See INSTALL for full list of variables.
|
||||
|
||||
AC_INIT([GRUB],[2.02~beta2],[bug-grub@gnu.org])
|
||||
AC_INIT([GRUB],[2.03],[bug-grub@gnu.org])
|
||||
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
@@ -374,7 +374,10 @@ case "$host_os" in
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_SIZEOF(off_t)
|
||||
test x"$ac_cv_sizeof_off_t" = x8 || AC_MSG_ERROR([Large file support is required]);;
|
||||
if test x"$ac_cv_sizeof_off_t" != x8 ; then
|
||||
AC_CHECK_SIZEOF(off64_t)
|
||||
test x"$ac_cv_sizeof_off64_t" = x8 || AC_MSG_ERROR([Large file support is required])
|
||||
fi;;
|
||||
esac
|
||||
|
||||
if test x$USE_NLS = xno; then
|
||||
@@ -389,7 +392,15 @@ fi
|
||||
|
||||
# Check for functions and headers.
|
||||
AC_CHECK_FUNCS(posix_memalign memalign getextmntent)
|
||||
AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h sys/mkdev.h limits.h)
|
||||
AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h)
|
||||
|
||||
# glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits deprecation
|
||||
# warning which causes compilation failure later with -Werror. So use -Werror here
|
||||
# as well to force proper sys/sysmacros.h detection.
|
||||
SAVED_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$HOST_CFLAGS -Werror"
|
||||
AC_HEADER_MAJOR
|
||||
CFLAGS="$SAVED_CFLAGS"
|
||||
|
||||
AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$ac_includes_default
|
||||
#include <sys/param.h>
|
||||
@@ -449,6 +460,16 @@ case "$build_os" in
|
||||
esac
|
||||
AC_SUBST(BUILD_EXEEXT)
|
||||
|
||||
# In some build environments like termux /bin/sh is not a valid
|
||||
# shebang. Use $SHELL instead if it's executable and /bin/sh isn't
|
||||
BUILD_SHEBANG=/bin/sh
|
||||
for she in /bin/sh "$SHELL"; do
|
||||
if test -x "$she" ; then
|
||||
BUILD_SHEBANG="$she"
|
||||
fi
|
||||
done
|
||||
AC_SUBST(BUILD_SHEBANG)
|
||||
|
||||
# For gnulib.
|
||||
gl_INIT
|
||||
|
||||
@@ -1145,14 +1166,23 @@ if test "$target_cpu"-"$platform" = x86_64-efi; then
|
||||
fi
|
||||
|
||||
if test "x$target_cpu" = xarm; then
|
||||
AC_CACHE_CHECK([whether option -mlong-calls works], grub_cv_cc_mlong_calls, [
|
||||
CFLAGS="$TARGET_CFLAGS -mlong-calls -Werror"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[grub_cv_cc_mlong_calls=yes],
|
||||
[grub_cv_cc_mlong_calls=no])
|
||||
AC_CACHE_CHECK([for options to disable movt and movw], grub_cv_target_cc_mno_movt, [
|
||||
grub_cv_target_cc_mno_movt=no
|
||||
for cand in "-mno-movt" \
|
||||
"-mllvm -arm-use-movt=0"; do
|
||||
if test x"$grub_cv_target_cc_mno_movt" != xno ; then
|
||||
break
|
||||
fi
|
||||
CFLAGS="$TARGET_CFLAGS $cand -Werror"
|
||||
CPPFLAGS="$TARGET_CPPFLAGS"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[grub_cv_target_cc_mno_movt="$cand"], [])
|
||||
done
|
||||
])
|
||||
if test "x$grub_cv_cc_mlong_calls" = xyes; then
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS -mlong-calls"
|
||||
|
||||
if test x"$grub_cv_target_cc_mno_movt" != xno ; then
|
||||
# A trick so that clang doesn't see it on link stage
|
||||
TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_movt"
|
||||
fi
|
||||
AC_CACHE_CHECK([whether option -mthumb-interwork works], grub_cv_cc_mthumb_interwork, [
|
||||
CFLAGS="$TARGET_CFLAGS -mthumb-interwork -Werror"
|
||||
@@ -1185,13 +1215,26 @@ CFLAGS="$TARGET_CFLAGS"
|
||||
|
||||
# Position independent executable.
|
||||
grub_CHECK_PIE
|
||||
grub_CHECK_NO_PIE
|
||||
grub_CHECK_NO_PIE_ONEWORD
|
||||
grub_CHECK_LINK_PIE
|
||||
[# Need that, because some distributions ship compilers that include
|
||||
# `-fPIE' in the default specs.
|
||||
# `-fPIE' or '-fpie' and '-pie' in the default specs.
|
||||
if [ x"$pie_possible" = xyes ]; then
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE"
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie"
|
||||
fi
|
||||
|
||||
if [ x"$link_nopie_needed" = xyes ] || [ x"$pie_possible" = xyes ]; then
|
||||
if [ x"$nopie_possible" = xyes ]; then
|
||||
TARGET_LDFLAGS="$TARGET_LDFLAGS -no-pie"
|
||||
fi
|
||||
if [ x"$nopie_oneword_possible" = xyes ]; then
|
||||
TARGET_LDFLAGS="$TARGET_LDFLAGS -nopie"
|
||||
fi
|
||||
fi]
|
||||
|
||||
CFLAGS="$TARGET_CFLAGS"
|
||||
LDFLAGS="$TARGET_LDFLAGS"
|
||||
|
||||
# Position independent executable.
|
||||
grub_CHECK_PIC
|
||||
@@ -1200,9 +1243,12 @@ grub_CHECK_PIC
|
||||
# and reload $gp in every function.
|
||||
# GCC implements it using symbol __gnu_local_gp in non-PIC as well.
|
||||
# However with clang we need PIC for this reloading to happen.
|
||||
# With arm64 we need relocations that are in some way representable in
|
||||
# PE as we need to support arm64-efi. Without -fPIC clang generates
|
||||
# movk's which aren't representable.
|
||||
# Since default varies across dictributions use either -fPIC or -fno-PIC
|
||||
# explicitly.
|
||||
if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel ) && test "x$grub_cv_cc_target_clang" = xyes ; then
|
||||
if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel || test x$target_cpu = xarm64 ) && test "x$grub_cv_cc_target_clang" = xyes ; then
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS -fPIC"
|
||||
elif [ x"$pic_possible" = xyes ]; then
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC"
|
||||
@@ -1555,11 +1601,11 @@ if test x"$grub_build_mkfont_excuse" = x ; then
|
||||
else
|
||||
enable_build_grub_mkfont=no
|
||||
fi
|
||||
if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then
|
||||
if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then
|
||||
if test x"$grub_build_mkfont_excuse" = x ; then
|
||||
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports needs build-time grub-mkfont])
|
||||
AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont])
|
||||
else
|
||||
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports needs build-time grub-mkfont ($grub_build_mkfont_excuse)])
|
||||
AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont ($grub_build_mkfont_excuse)])
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1629,11 +1675,11 @@ if test x"$enable_build_grub_mkfont" = xno ; then
|
||||
FONT_SOURCE=
|
||||
fi
|
||||
|
||||
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then
|
||||
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then
|
||||
if test x"$grub_build_mkfont_excuse" = x ; then
|
||||
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports need unifont])
|
||||
AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont])
|
||||
else
|
||||
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)])
|
||||
AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)])
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ This edition documents version @value{VERSION}.
|
||||
* Video Subsystem::
|
||||
* PFF2 Font File Format::
|
||||
* Graphical Menu Software Design::
|
||||
* Verifiers framework::
|
||||
* Copying This Manual:: Copying This Manual
|
||||
* Index::
|
||||
@end menu
|
||||
@@ -1949,6 +1950,58 @@ the graphics mode that was in use before @code{grub_video_setup()} was called
|
||||
might fix some of the problems.
|
||||
|
||||
|
||||
@node Verifiers framework
|
||||
@chapter Verifiers framework
|
||||
|
||||
To register your own verifier call @samp{grub_verifier_register} with a
|
||||
structure pointing to your functions.
|
||||
|
||||
The interface is inspired by hash interface with @samp{init}/@samp{write}/@samp{fini}.
|
||||
|
||||
There are eesntially 2 ways of using it: hashing and whole-file verification:
|
||||
|
||||
With hashing approach:
|
||||
During @samp{init} you decide whether you want to check given file and init context.
|
||||
In @samp{write} you update you hashing state.
|
||||
In @samp{fini} you check that hash matches the expected value/passes some check/...
|
||||
|
||||
With whole-file verification:
|
||||
During @samp{init} you decide whether you want to check given file and init context.
|
||||
In @samp{write} you verify file and return error if it fails.
|
||||
You don't have @samp{fini}.
|
||||
|
||||
Additional @samp{verify_string} receives various strings like kernel parameters to
|
||||
verify. Returning no error means successful verification and an error stops the current
|
||||
action.
|
||||
|
||||
Detailed description of API:
|
||||
|
||||
Every time a file is opened your @samp{init} function is called with file descriptor
|
||||
and file type. Your function can have following outcomes:
|
||||
|
||||
@itemize
|
||||
|
||||
@item returning no error and setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_SKIP_VERIFICATION}.
|
||||
In this case your verifier will not be called anymore and your verifier is considered
|
||||
to have skipped verification
|
||||
|
||||
@item returning error. Then opening of the fail will fail due to failed verification.
|
||||
|
||||
@item returning no error and not setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_SKIP_VERIFICATION}
|
||||
In this case verification is done as described in following section
|
||||
|
||||
@end itemize
|
||||
|
||||
In the third case your @samp{write} will be called with chunks of file. If you need the whole file in a single
|
||||
chunk then during @samp{init} set bit @samp{GRUB_VERIFY_FLAGS_SINGLE_CHUNK} in @samp{*flags}.
|
||||
During @samp{init} you may set @samp{*context} if you need additional context. At every iteration you may return
|
||||
an error and the the file will be considered as having failed the verification. If you return no error then
|
||||
verification continues.
|
||||
|
||||
Optionally at the end of the file @samp{fini} if it exists is called with just the context. If you return
|
||||
no error during any of @samp{init}, @samp{write} and @samp{fini} then the file is considered as having
|
||||
succeded verification.
|
||||
|
||||
@node Copying This Manual
|
||||
@appendix Copying This Manual
|
||||
|
||||
|
||||
@@ -2446,6 +2446,10 @@ The boot file name provided by DHCP. Read-only.
|
||||
The name of the DHCP server responsible for these boot parameters.
|
||||
Read-only.
|
||||
|
||||
@item net_@var{<interface>}_next_server
|
||||
The IP address of the next (usually, TFTP) server provided by DHCP.
|
||||
Read-only.
|
||||
|
||||
@item net_default_interface
|
||||
Initially set to name of network interface that was used to load grub.
|
||||
Read-write, although setting it affects only interpretation of
|
||||
@@ -3062,6 +3066,7 @@ These variables have special meaning to GRUB.
|
||||
* net_@var{<interface>}_hostname::
|
||||
* net_@var{<interface>}_ip::
|
||||
* net_@var{<interface>}_mac::
|
||||
* net_@var{<interface>}_next_server::
|
||||
* net_@var{<interface>}_rootpath::
|
||||
* net_default_interface::
|
||||
* net_default_ip::
|
||||
@@ -3213,9 +3218,10 @@ source for more details.
|
||||
@node default
|
||||
@subsection default
|
||||
|
||||
If this variable is set, it identifies a menu entry that should be selected
|
||||
by default, possibly after a timeout (@pxref{timeout}). The entry may be
|
||||
identified by number or by id.
|
||||
If this variable is set, it identifies a menu entry that should be
|
||||
selected by default, possibly after a timeout (@pxref{timeout}). The
|
||||
entry may be identified by number (starting from 0 at each level of
|
||||
the hierarchy), by title, or by id.
|
||||
|
||||
For example, if you have:
|
||||
|
||||
@@ -3231,24 +3237,26 @@ then you can make this the default using:
|
||||
default=example-gnu-linux
|
||||
@end example
|
||||
|
||||
If the entry is in a submenu, then it must be identified using the titles of
|
||||
each of the submenus starting from the top level followed by the number or
|
||||
title of the menu entry itself, separated by @samp{>}. For example, take
|
||||
the following menu structure:
|
||||
If the entry is in a submenu, then it must be identified using the
|
||||
number, title, or id of each of the submenus starting from the top
|
||||
level, followed by the number, title, or id of the menu entry itself,
|
||||
with each element separated by @samp{>}. For example, take the
|
||||
following menu structure:
|
||||
|
||||
@example
|
||||
Submenu 1
|
||||
Menu Entry 1
|
||||
Menu Entry 2
|
||||
Submenu 2
|
||||
Submenu 3
|
||||
Menu Entry 3
|
||||
Menu Entry 4
|
||||
Menu Entry 5
|
||||
GNU/Hurd --id gnu-hurd
|
||||
Standard Boot --id=gnu-hurd-std
|
||||
Rescue shell --id=gnu-hurd-rescue
|
||||
Other platforms --id=other
|
||||
Minix --id=minix
|
||||
Version 3.4.0 --id=minix-3.4.0
|
||||
Version 3.3.0 --id=minix-3.3.0
|
||||
GRUB Invaders --id=grub-invaders
|
||||
@end example
|
||||
|
||||
``Menu Entry 3'' would then be identified as
|
||||
@samp{Submenu 2>Submenu 3>Menu Entry 3}.
|
||||
The more recent release of Minix would then be identified as
|
||||
@samp{Other platforms>Minix>Version 3.4.0}, or as @samp{1>0>0}, or as
|
||||
@samp{other>minix>minix-3.4.0}.
|
||||
|
||||
This variable is often set by @samp{GRUB_DEFAULT} (@pxref{Simple
|
||||
configuration}), @command{grub-set-default}, or @command{grub-reboot}.
|
||||
@@ -3422,6 +3430,12 @@ The default is the value of @samp{color_normal} (@pxref{color_normal}).
|
||||
@xref{Network}.
|
||||
|
||||
|
||||
@node net_@var{<interface>}_next_server
|
||||
@subsection net_@var{<interface>}_next_server
|
||||
|
||||
@xref{Network}.
|
||||
|
||||
|
||||
@node net_@var{<interface>}_rootpath
|
||||
@subsection net_@var{<interface>}_rootpath
|
||||
|
||||
|
||||
@@ -292,7 +292,7 @@ BUILT_SOURCES += symlist.h
|
||||
|
||||
symlist.c: symlist.h gensymlist.sh
|
||||
$(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) -DGRUB_SYMBOL_GENERATOR=1 symlist.h > symlist.p || (rm -f symlist.p; exit 1)
|
||||
cat symlist.p | /bin/sh $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1)
|
||||
cat symlist.p | $(SHELL) $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1)
|
||||
rm -f symlist.p
|
||||
CLEANFILES += symlist.c
|
||||
BUILT_SOURCES += symlist.c
|
||||
|
||||
@@ -164,6 +164,7 @@ kernel = {
|
||||
arm_coreboot = term/arm/pl050.c;
|
||||
arm_coreboot = term/arm/cros.c;
|
||||
arm_coreboot = term/arm/cros_ec.c;
|
||||
arm_coreboot = bus/spi/rk3288_spi.c;
|
||||
arm_coreboot = commands/keylayouts.c;
|
||||
arm_coreboot = kern/arm/coreboot/dma.c;
|
||||
|
||||
@@ -229,8 +230,10 @@ kernel = {
|
||||
|
||||
arm_efi = kern/arm/efi/init.c;
|
||||
arm_efi = kern/arm/efi/misc.c;
|
||||
arm_efi = kern/efi/fdt.c;
|
||||
|
||||
arm64_efi = kern/arm64/efi/init.c;
|
||||
arm64_efi = kern/efi/fdt.c;
|
||||
|
||||
i386_pc = kern/i386/pc/init.c;
|
||||
i386_pc = kern/i386/pc/mmap.c;
|
||||
@@ -242,6 +245,7 @@ kernel = {
|
||||
|
||||
coreboot = kern/coreboot/mmap.c;
|
||||
i386_coreboot = kern/i386/coreboot/cbtable.c;
|
||||
coreboot = kern/coreboot/cbtable.c;
|
||||
arm_coreboot = kern/arm/coreboot/cbtable.c;
|
||||
|
||||
i386_multiboot = kern/i386/multiboot_mmap.c;
|
||||
@@ -598,13 +602,6 @@ module = {
|
||||
enable = arm_coreboot;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = dwc2;
|
||||
common = bus/usb/dwc2.c;
|
||||
arm_coreboot = bus/usb/dwc2-fdt.c;
|
||||
enable = arm_coreboot;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = pci;
|
||||
common = bus/pci.c;
|
||||
@@ -669,6 +666,7 @@ module = {
|
||||
module = {
|
||||
name = cbtable;
|
||||
common = kern/i386/coreboot/cbtable.c;
|
||||
common = kern/coreboot/cbtable.c;
|
||||
enable = i386_pc;
|
||||
enable = i386_efi;
|
||||
enable = i386_qemu;
|
||||
@@ -850,7 +848,7 @@ module = {
|
||||
common = commands/gptsync.c;
|
||||
};
|
||||
|
||||
/*module = {
|
||||
module = {
|
||||
name = halt;
|
||||
nopc = commands/halt.c;
|
||||
i386_pc = commands/i386/pc/halt.c;
|
||||
@@ -866,7 +864,8 @@ module = {
|
||||
efi = lib/efi/halt.c;
|
||||
ieee1275 = lib/ieee1275/halt.c;
|
||||
emu = lib/emu/halt.c;
|
||||
uboot = lib/uboot/halt.c;
|
||||
uboot = lib/dummy/halt.c;
|
||||
arm_coreboot = lib/dummy/halt.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
@@ -884,8 +883,9 @@ module = {
|
||||
mips_qemu_mips = lib/mips/qemu_mips/reboot.c;
|
||||
xen = lib/xen/reboot.c;
|
||||
uboot = lib/uboot/reboot.c;
|
||||
arm_coreboot = lib/dummy/reboot.c;
|
||||
common = commands/reboot.c;
|
||||
};*/
|
||||
};
|
||||
|
||||
module = {
|
||||
name = hashsum;
|
||||
@@ -899,6 +899,11 @@ module = {
|
||||
cppflags = '-I$(srcdir)/lib/posix_wrap';
|
||||
};
|
||||
|
||||
module = {
|
||||
name = verify_helper;
|
||||
common = commands/verify_helper.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = hdparm;
|
||||
common = commands/hdparm.c;
|
||||
@@ -1562,6 +1567,7 @@ module = {
|
||||
i386_xen = lib/i386/xen/relocator.S;
|
||||
x86_64_xen = lib/x86_64/xen/relocator.S;
|
||||
xen = lib/i386/relocator_common_c.c;
|
||||
x86_64_efi = lib/x86_64/efi/relocator.c;
|
||||
|
||||
extra_dist = lib/i386/relocator_common.S;
|
||||
extra_dist = kern/powerpc/cache_flush.S;
|
||||
@@ -1576,8 +1582,8 @@ module = {
|
||||
name = datetime;
|
||||
cmos = lib/cmos_datetime.c;
|
||||
efi = lib/efi/datetime.c;
|
||||
uboot = lib/uboot/datetime.c;
|
||||
arm_coreboot = lib/uboot/datetime.c;
|
||||
uboot = lib/dummy/datetime.c;
|
||||
arm_coreboot = lib/dummy/datetime.c;
|
||||
sparc64_ieee1275 = lib/ieee1275/datetime.c;
|
||||
powerpc_ieee1275 = lib/ieee1275/datetime.c;
|
||||
sparc64_ieee1275 = lib/ieee1275/cmos.c;
|
||||
@@ -1991,6 +1997,11 @@ module = {
|
||||
common = tests/example_functional_test.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = strtoull_test;
|
||||
common = tests/strtoull_test.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = setjmp_test;
|
||||
common = tests/setjmp_test.c;
|
||||
|
||||
@@ -25,28 +25,22 @@ static grub_size_t root_address_cells, root_size_cells;
|
||||
/* Pointer to this symbol signals invalid mapping. */
|
||||
char grub_fdtbus_invalid_mapping[1];
|
||||
|
||||
struct grub_fdtbus_dev
|
||||
{
|
||||
struct grub_fdtbus_dev *next;
|
||||
struct grub_fdtbus_dev *parent;
|
||||
int node;
|
||||
struct grub_fdtbus_driver *driver;
|
||||
};
|
||||
|
||||
struct grub_fdtbus_dev *devs;
|
||||
struct grub_fdtbus_driver *drivers;
|
||||
|
||||
static int
|
||||
is_compatible (struct grub_fdtbus_driver *driver,
|
||||
int node)
|
||||
int
|
||||
grub_fdtbus_is_compatible (const char *compat_string,
|
||||
const struct grub_fdtbus_dev *dev)
|
||||
{
|
||||
grub_size_t compatible_size;
|
||||
const char *compatible = grub_fdt_get_prop (dtb, node, "compatible",
|
||||
const char *compatible = grub_fdt_get_prop (dtb, dev->node, "compatible",
|
||||
&compatible_size);
|
||||
if (!compatible)
|
||||
return 0;
|
||||
const char *compatible_end = compatible + compatible_size;
|
||||
while (compatible < compatible_end)
|
||||
{
|
||||
if (grub_strcmp (driver->compatible, compatible) == 0)
|
||||
if (grub_strcmp (compat_string, compatible) == 0)
|
||||
return 1;
|
||||
compatible += grub_strlen (compatible) + 1;
|
||||
}
|
||||
@@ -73,10 +67,12 @@ fdtbus_scan (struct grub_fdtbus_dev *parent)
|
||||
dev->parent = parent;
|
||||
devs = dev;
|
||||
FOR_LIST_ELEMENTS(driver, drivers)
|
||||
if (!dev->driver && is_compatible (driver, node))
|
||||
if (!dev->driver && grub_fdtbus_is_compatible (driver->compatible, dev))
|
||||
{
|
||||
if (driver->attach(dev) == GRUB_ERR_NONE)
|
||||
grub_dprintf ("fdtbus", "Attaching %s\n", driver->compatible);
|
||||
if (driver->attach (dev) == GRUB_ERR_NONE)
|
||||
{
|
||||
grub_dprintf ("fdtbus", "Attached %s\n", driver->compatible);
|
||||
dev->driver = driver;
|
||||
break;
|
||||
}
|
||||
@@ -90,13 +86,18 @@ void
|
||||
grub_fdtbus_register (struct grub_fdtbus_driver *driver)
|
||||
{
|
||||
struct grub_fdtbus_dev *dev;
|
||||
grub_dprintf ("fdtbus", "Registering %s\n", driver->compatible);
|
||||
grub_list_push (GRUB_AS_LIST_P (&drivers),
|
||||
GRUB_AS_LIST (driver));
|
||||
for (dev = devs; dev; dev = dev->next)
|
||||
if (!dev->driver && is_compatible (driver, dev->node))
|
||||
if (!dev->driver && grub_fdtbus_is_compatible (driver->compatible, dev))
|
||||
{
|
||||
if (driver->attach(dev) == GRUB_ERR_NONE)
|
||||
dev->driver = driver;
|
||||
grub_dprintf ("fdtbus", "Attaching %s (%p)\n", driver->compatible, dev);
|
||||
if (driver->attach (dev) == GRUB_ERR_NONE)
|
||||
{
|
||||
grub_dprintf ("fdtbus", "Attached %s\n", driver->compatible);
|
||||
dev->driver = driver;
|
||||
}
|
||||
grub_print_error ();
|
||||
}
|
||||
}
|
||||
|
||||
103
grub-core/bus/spi/rk3288_spi.c
Normal file
103
grub-core/bus/spi/rk3288_spi.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
*
|
||||
* Copyright (C) 2012 Google Inc.
|
||||
* Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
*
|
||||
* This is based on depthcharge code.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/mm.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/fdtbus.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
|
||||
static grub_err_t
|
||||
spi_send (const struct grub_fdtbus_dev *dev, const void *data, grub_size_t sz)
|
||||
{
|
||||
const grub_uint8_t *ptr = data, *end = ptr + sz;
|
||||
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
|
||||
spi[2] = 0;
|
||||
spi[1] = sz - 1;
|
||||
spi[0] = ((1 << 18) | spi[0]) & ~(1 << 19);
|
||||
spi[2] = 1;
|
||||
while (ptr < end)
|
||||
{
|
||||
while (spi[9] & 2);
|
||||
spi[256] = *ptr++;
|
||||
}
|
||||
while (spi[9] & 1);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
spi_receive (const struct grub_fdtbus_dev *dev, void *data, grub_size_t sz)
|
||||
{
|
||||
grub_uint8_t *ptr = data, *end = ptr + sz;
|
||||
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
|
||||
spi[2] = 0;
|
||||
spi[1] = sz - 1;
|
||||
spi[0] = ((1 << 19) | spi[0]) & ~(1 << 18);
|
||||
spi[2] = 1;
|
||||
while (ptr < end)
|
||||
{
|
||||
while (spi[9] & 8);
|
||||
*ptr++ = spi[512];
|
||||
}
|
||||
while (spi[9] & 1);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
spi_start (const struct grub_fdtbus_dev *dev)
|
||||
{
|
||||
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
|
||||
spi[3] = 1;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
spi_stop (const struct grub_fdtbus_dev *dev)
|
||||
{
|
||||
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
|
||||
spi[3] = 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
spi_attach(const struct grub_fdtbus_dev *dev)
|
||||
{
|
||||
if (!grub_fdtbus_is_mapping_valid (grub_fdtbus_map_reg (dev, 0, 0)))
|
||||
return GRUB_ERR_IO;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static struct grub_fdtbus_driver spi =
|
||||
{
|
||||
.compatible = "rockchip,rk3288-spi",
|
||||
.attach = spi_attach,
|
||||
.send = spi_send,
|
||||
.receive = spi_receive,
|
||||
.start = spi_start,
|
||||
.stop = spi_stop,
|
||||
};
|
||||
|
||||
void
|
||||
grub_rk3288_spi_init (void)
|
||||
{
|
||||
grub_fdtbus_register (&spi);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1579,8 +1579,8 @@ grub_ehci_hubports (grub_usb_controller_t dev)
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_ehci_reset_port (grub_usb_controller_t dev,
|
||||
unsigned int port)
|
||||
grub_ehci_portstatus (grub_usb_controller_t dev,
|
||||
unsigned int port, unsigned int enable)
|
||||
{
|
||||
struct grub_ehci *e = (struct grub_ehci *) dev->data;
|
||||
grub_uint64_t endtime;
|
||||
@@ -1602,6 +1602,14 @@ grub_ehci_reset_port (grub_usb_controller_t dev,
|
||||
if (grub_get_time_ms () > endtime)
|
||||
return GRUB_USB_ERR_TIMEOUT;
|
||||
|
||||
if (!enable) /* We don't need reset port */
|
||||
{
|
||||
grub_dprintf ("ehci", "portstatus: Disabled.\n");
|
||||
grub_dprintf ("ehci", "portstatus: end, status=0x%02x\n",
|
||||
grub_ehci_port_read (e, port));
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_dprintf ("ehci", "portstatus: enable\n");
|
||||
|
||||
grub_boot_time ("Resetting port %d", port);
|
||||
@@ -1802,7 +1810,7 @@ static struct grub_usb_controller_dev usb_controller = {
|
||||
.check_transfer = grub_ehci_check_transfer,
|
||||
.cancel_transfer = grub_ehci_cancel_transfer,
|
||||
.hubports = grub_ehci_hubports,
|
||||
.reset_port = grub_ehci_reset_port,
|
||||
.portstatus = grub_ehci_portstatus,
|
||||
.detect_dev = grub_ehci_detect_dev,
|
||||
/* estimated max. count of TDs for one bulk transfer */
|
||||
.max_bulk_tds = GRUB_EHCI_N_TD * 3 / 4
|
||||
|
||||
@@ -1224,8 +1224,8 @@ grub_ohci_cancel_transfer (grub_usb_controller_t dev,
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_ohci_rest_port (grub_usb_controller_t dev,
|
||||
unsigned int port)
|
||||
grub_ohci_portstatus (grub_usb_controller_t dev,
|
||||
unsigned int port, unsigned int enable)
|
||||
{
|
||||
struct grub_ohci *o = (struct grub_ohci *) dev->data;
|
||||
grub_uint64_t endtime;
|
||||
@@ -1233,6 +1233,22 @@ grub_ohci_rest_port (grub_usb_controller_t dev,
|
||||
|
||||
grub_dprintf ("ohci", "begin of portstatus=0x%02x\n",
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port));
|
||||
|
||||
if (!enable) /* We don't need reset port */
|
||||
{
|
||||
/* Disable the port and wait for it. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_CLEAR_PORT_ENABLE);
|
||||
endtime = grub_get_time_ms () + 1000;
|
||||
while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)
|
||||
& (1 << 1)))
|
||||
if (grub_get_time_ms () > endtime)
|
||||
return GRUB_USB_ERR_TIMEOUT;
|
||||
|
||||
grub_dprintf ("ohci", "end of portstatus=0x%02x\n",
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port));
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* OHCI does one reset signal 10ms long but USB spec.
|
||||
* requests 50ms for root hub (no need to be continuous).
|
||||
@@ -1422,7 +1438,7 @@ static struct grub_usb_controller_dev usb_controller =
|
||||
.check_transfer = grub_ohci_check_transfer,
|
||||
.cancel_transfer = grub_ohci_cancel_transfer,
|
||||
.hubports = grub_ohci_hubports,
|
||||
.reset_port = grub_ohci_reset_port,
|
||||
.portstatus = grub_ohci_portstatus,
|
||||
.detect_dev = grub_ohci_detect_dev,
|
||||
/* estimated max. count of TDs for one bulk transfer */
|
||||
.max_bulk_tds = GRUB_OHCI_TDS * 3 / 4
|
||||
|
||||
@@ -710,8 +710,8 @@ grub_uhci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data)
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_uhci_reset_port (grub_usb_controller_t dev,
|
||||
unsigned int port)
|
||||
grub_uhci_portstatus (grub_usb_controller_t dev,
|
||||
unsigned int port, unsigned int enable)
|
||||
{
|
||||
struct grub_uhci *u = (struct grub_uhci *) dev->data;
|
||||
int reg;
|
||||
@@ -731,6 +731,21 @@ grub_uhci_reset_port (grub_usb_controller_t dev,
|
||||
|
||||
status = grub_uhci_readreg16 (u, reg);
|
||||
grub_dprintf ("uhci", "detect=0x%02x\n", status);
|
||||
|
||||
if (!enable) /* We don't need reset port */
|
||||
{
|
||||
/* Disable the port. */
|
||||
grub_uhci_writereg16 (u, reg, 0 << 2);
|
||||
grub_dprintf ("uhci", "waiting for the port to be disabled\n");
|
||||
endtime = grub_get_time_ms () + 1000;
|
||||
while ((grub_uhci_readreg16 (u, reg) & (1 << 2)))
|
||||
if (grub_get_time_ms () > endtime)
|
||||
return GRUB_USB_ERR_TIMEOUT;
|
||||
|
||||
status = grub_uhci_readreg16 (u, reg);
|
||||
grub_dprintf ("uhci", ">3detect=0x%02x\n", status);
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Reset the port. */
|
||||
status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC;
|
||||
@@ -828,7 +843,7 @@ static struct grub_usb_controller_dev usb_controller =
|
||||
.check_transfer = grub_uhci_check_transfer,
|
||||
.cancel_transfer = grub_uhci_cancel_transfer,
|
||||
.hubports = grub_uhci_hubports,
|
||||
.reset_port = grub_uhci_reset_port,
|
||||
.portstatus = grub_uhci_portstatus,
|
||||
.detect_dev = grub_uhci_detect_dev,
|
||||
/* estimated max. count of TDs for one bulk transfer */
|
||||
.max_bulk_tds = N_TD * 3 / 4
|
||||
|
||||
@@ -207,8 +207,8 @@ attach_root_port (struct grub_usb_hub *hub, int portno,
|
||||
|
||||
grub_boot_time ("After detect_dev");
|
||||
|
||||
/* Reset port. */
|
||||
err = hub->controller->dev->reset_port (hub->controller, portno);
|
||||
/* Enable the port. */
|
||||
err = hub->controller->dev->portstatus (hub->controller, portno, 1);
|
||||
if (err)
|
||||
return;
|
||||
hub->controller->dev->pending_reset = grub_get_time_ms () + 5000;
|
||||
|
||||
@@ -635,7 +635,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||
grub_size_t size;
|
||||
char *buf;
|
||||
|
||||
file = grub_file_open (args[i]);
|
||||
file = grub_file_open (args[i], GRUB_FILE_TYPE_ACPI_TABLE);
|
||||
if (! file)
|
||||
{
|
||||
free_tables ();
|
||||
@@ -761,10 +761,10 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||
struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
|
||||
struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
|
||||
|
||||
grub_efi_system_table->boot_services->install_configuration_table
|
||||
(&acpi20, grub_acpi_get_rsdpv2 ());
|
||||
grub_efi_system_table->boot_services->install_configuration_table
|
||||
(&acpi, grub_acpi_get_rsdpv1 ());
|
||||
efi_call_2 (grub_efi_system_table->boot_services->install_configuration_table,
|
||||
&acpi20, grub_acpi_get_rsdpv2 ());
|
||||
efi_call_2 (grub_efi_system_table->boot_services->install_configuration_table,
|
||||
&acpi, grub_acpi_get_rsdpv1 ());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -121,8 +121,8 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
|
||||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (args[0]);
|
||||
file = grub_file_open (args[0], GRUB_FILE_TYPE_PRINT_BLOCKLIST
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
file = grub_file_open (args[0]);
|
||||
file = grub_file_open (args[0], GRUB_FILE_TYPE_CAT);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
@@ -140,10 +140,13 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
|
||||
}
|
||||
|
||||
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
|
||||
for (j = 0; j < utcount; j++)
|
||||
grub_printf ("<%x>", (unsigned int) utbuf[j]);
|
||||
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
|
||||
if (utcount)
|
||||
{
|
||||
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
|
||||
for (j = 0; j < utcount; j++)
|
||||
grub_printf ("<%x>", (unsigned int) utbuf[j]);
|
||||
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
|
||||
}
|
||||
|
||||
grub_xputs ("\n");
|
||||
grub_refresh ();
|
||||
|
||||
@@ -45,8 +45,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_printf_ (N_("Compare file `%s' with `%s':\n"), args[0],
|
||||
args[1]);
|
||||
|
||||
file1 = grub_file_open (args[0]);
|
||||
file2 = grub_file_open (args[1]);
|
||||
file1 = grub_file_open (args[0], GRUB_FILE_TYPE_CMP);
|
||||
file2 = grub_file_open (args[1], GRUB_FILE_TYPE_CMP);
|
||||
if (! file1 || ! file2)
|
||||
goto cleanup;
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
file = grub_file_open (argv[1]);
|
||||
file = grub_file_open (argv[1], GRUB_FILE_TYPE_VBE_DUMP);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
@@ -183,7 +183,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)),
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
file = grub_file_open (argv[0]);
|
||||
file = grub_file_open (argv[0], GRUB_FILE_TYPE_VBE_DUMP);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (type == -1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no type specified");
|
||||
|
||||
file = grub_file_open (args[0]);
|
||||
file = grub_file_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL);
|
||||
if (!file)
|
||||
return grub_errno;
|
||||
switch (type)
|
||||
@@ -546,7 +546,8 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
case IS_XNU64:
|
||||
case IS_XNU32:
|
||||
{
|
||||
macho = grub_macho_open (args[0], (type == IS_XNU64));
|
||||
macho = grub_macho_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL,
|
||||
(type == IS_XNU64));
|
||||
if (!macho)
|
||||
break;
|
||||
/* FIXME: more checks? */
|
||||
|
||||
@@ -113,7 +113,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
||||
if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
|
||||
return grub_error (GRUB_ERR_BUG, "mdlen is too long");
|
||||
|
||||
hashlist = grub_file_open (hashfilename);
|
||||
hashlist = grub_file_open (hashfilename, GRUB_FILE_TYPE_HASHLIST);
|
||||
if (!hashlist)
|
||||
return grub_errno;
|
||||
|
||||
@@ -141,17 +141,15 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
||||
filename = grub_xasprintf ("%s/%s", prefix, p);
|
||||
if (!filename)
|
||||
return grub_errno;
|
||||
if (!uncompress)
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (filename);
|
||||
file = grub_file_open (filename, GRUB_FILE_TYPE_TO_HASH
|
||||
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||
: 0));
|
||||
grub_free (filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!uncompress)
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (p);
|
||||
}
|
||||
file = grub_file_open (p, GRUB_FILE_TYPE_TO_HASH
|
||||
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||
: 0));
|
||||
if (!file)
|
||||
{
|
||||
grub_file_close (hashlist);
|
||||
@@ -242,9 +240,9 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt,
|
||||
grub_file_t file;
|
||||
grub_err_t err;
|
||||
unsigned j;
|
||||
if (!uncompress)
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (args[i]);
|
||||
file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH
|
||||
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||
: 0));
|
||||
if (!file)
|
||||
{
|
||||
if (!keep)
|
||||
|
||||
@@ -328,6 +328,7 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
ata = ((struct grub_scsi *) disk->data)->data;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
grub_disk_close (disk);
|
||||
return grub_error (GRUB_ERR_IO, "not an ATA device");
|
||||
|
||||
@@ -90,7 +90,7 @@ grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
grub_file_t file;
|
||||
|
||||
file = grub_file_open (args[0]);
|
||||
file = grub_file_open (args[0], GRUB_FILE_TYPE_HEXCAT);
|
||||
if (! file)
|
||||
return 0;
|
||||
|
||||
|
||||
79
grub-core/commands/i386/nthibr.c
Normal file
79
grub-core/commands/i386/nthibr.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/* nthibr.c - tests whether an MS Windows system partition is hibernated */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2013 Peter Lustig
|
||||
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_nthibr (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
grub_uint8_t hibr_file_magic[4];
|
||||
grub_file_t hibr_file = 0;
|
||||
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
|
||||
hibr_file = grub_file_open (args[0], GRUB_FILE_TYPE_FILE_ID);
|
||||
if (!hibr_file)
|
||||
return grub_errno;
|
||||
|
||||
/* Try to read magic number of 'hiberfil.sys' */
|
||||
if (grub_file_read (hibr_file, hibr_file_magic,
|
||||
sizeof (hibr_file_magic))
|
||||
!= (grub_ssize_t) sizeof (hibr_file_magic))
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_TEST_FAILURE, "false");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!(grub_memcmp ("hibr", hibr_file_magic, sizeof (hibr_file_magic)) == 0
|
||||
|| grub_memcmp ("HIBR", hibr_file_magic, sizeof (hibr_file_magic)) == 0))
|
||||
grub_error (GRUB_ERR_TEST_FAILURE, "false");
|
||||
|
||||
exit:
|
||||
grub_file_close (hibr_file);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT (check_nt_hiberfil)
|
||||
{
|
||||
cmd = grub_register_command ("check_nt_hiberfil", grub_cmd_nthibr,
|
||||
N_("FILE"),
|
||||
N_("Test whether a hiberfil.sys is "
|
||||
"in hibernated state."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (check_nt_hiberfil)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
||||
@@ -93,7 +93,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_uint32_t tempo;
|
||||
grub_file_t file;
|
||||
|
||||
file = grub_file_open (args[0]);
|
||||
file = grub_file_open (args[0], GRUB_FILE_TYPE_AUDIO);
|
||||
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
@@ -220,7 +220,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)),
|
||||
else
|
||||
filename = argv[0];
|
||||
|
||||
file = grub_file_open (filename);
|
||||
file = grub_file_open (filename, GRUB_FILE_TYPE_KEYBOARD_LAYOUT);
|
||||
if (! file)
|
||||
goto fail;
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ legacy_file (const char *filename)
|
||||
if (!suffix)
|
||||
return grub_errno;
|
||||
|
||||
file = grub_file_open (filename);
|
||||
file = grub_file_open (filename, GRUB_FILE_TYPE_CONFIG);
|
||||
if (! file)
|
||||
{
|
||||
grub_free (suffix);
|
||||
@@ -517,7 +517,7 @@ grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
#endif
|
||||
);
|
||||
|
||||
return cmd->func (cmd, argc, args);
|
||||
return cmd->func (cmd, argc ? 1 : 0, args);
|
||||
}
|
||||
if (kernel_type == MULTIBOOT)
|
||||
{
|
||||
|
||||
@@ -44,7 +44,8 @@ static const struct grub_arg_option options[] =
|
||||
PUBKEY filter (that insists upon properly signed files) as well. PUBKEY
|
||||
filter is restored before the function returns. */
|
||||
static grub_file_t
|
||||
open_envblk_file (char *filename, int untrusted)
|
||||
open_envblk_file (char *filename,
|
||||
enum grub_file_type type)
|
||||
{
|
||||
grub_file_t file;
|
||||
char *buf = 0;
|
||||
@@ -72,13 +73,7 @@ open_envblk_file (char *filename, int untrusted)
|
||||
grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
|
||||
}
|
||||
|
||||
/* The filters that are disabled will be re-enabled by the call to
|
||||
grub_file_open() after this particular file is opened. */
|
||||
grub_file_filter_disable_compression ();
|
||||
if (untrusted)
|
||||
grub_file_filter_disable_pubkey ();
|
||||
|
||||
file = grub_file_open (filename);
|
||||
file = grub_file_open (filename, type);
|
||||
|
||||
grub_free (buf);
|
||||
return file;
|
||||
@@ -171,7 +166,10 @@ grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
whitelist.list = args;
|
||||
|
||||
/* state[0] is the -f flag; state[1] is the --skip-sig flag */
|
||||
file = open_envblk_file ((state[0].set) ? state[0].arg : 0, state[1].set);
|
||||
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
|
||||
GRUB_FILE_TYPE_LOADENV
|
||||
| (state[1].set
|
||||
? GRUB_FILE_TYPE_SKIP_SIGNATURE : 0));
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
@@ -206,7 +204,10 @@ grub_cmd_list_env (grub_extcmd_context_t ctxt,
|
||||
grub_file_t file;
|
||||
grub_envblk_t envblk;
|
||||
|
||||
file = open_envblk_file ((state[0].set) ? state[0].arg : 0, 0);
|
||||
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
|
||||
GRUB_FILE_TYPE_LOADENV
|
||||
| (state[1].set
|
||||
? GRUB_FILE_TYPE_SKIP_SIGNATURE : 0));
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
@@ -390,7 +391,8 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified");
|
||||
|
||||
file = open_envblk_file ((state[0].set) ? state[0].arg : 0,
|
||||
1 /* allow untrusted */);
|
||||
GRUB_FILE_TYPE_SAVEENV
|
||||
| GRUB_FILE_TYPE_SKIP_SIGNATURE);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
|
||||
@@ -129,8 +129,8 @@ print_files_long (const char *filename, const struct grub_dirhook_info *info,
|
||||
|
||||
/* XXX: For ext2fs symlinks are detected as files while they
|
||||
should be reported as directories. */
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (pathname);
|
||||
file = grub_file_open (pathname, GRUB_FILE_TYPE_GET_SIZE
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
if (! file)
|
||||
{
|
||||
grub_errno = 0;
|
||||
@@ -225,8 +225,8 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
|
||||
struct grub_dirhook_info info;
|
||||
grub_errno = 0;
|
||||
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (dirname);
|
||||
file = grub_file_open (dirname, GRUB_FILE_TYPE_GET_SIZE
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
if (! file)
|
||||
goto fail;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
|
||||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
file = grub_file_open (argv[0]);
|
||||
file = grub_file_open (argv[0], GRUB_FILE_TYPE_CAT);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ get_uuid (const char *name, char **uuid, int getnative)
|
||||
case GRUB_DISK_DEVICE_XEN:
|
||||
if (getnative)
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
/* Virtual disks. */
|
||||
/* GRUB dynamically generated files. */
|
||||
@@ -241,7 +242,8 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
|
||||
if (! filename)
|
||||
goto fail;
|
||||
|
||||
file = grub_file_open (filename);
|
||||
file = grub_file_open (filename,
|
||||
GRUB_FILE_TYPE_GRUB_MODULE);
|
||||
grub_free (filename);
|
||||
if (! file)
|
||||
goto fail;
|
||||
|
||||
@@ -193,7 +193,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
|
||||
{
|
||||
grub_file_t file;
|
||||
|
||||
file = grub_file_open (filename);
|
||||
file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE_LIST);
|
||||
if (file)
|
||||
{
|
||||
char *buf = 0;
|
||||
|
||||
@@ -64,7 +64,7 @@ iterate_device (const char *name, void *data)
|
||||
/* Skip floppy drives when requested. */
|
||||
if (ctx->no_floppy &&
|
||||
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
#ifdef DO_SEARCH_FS_UUID
|
||||
#define compare_fn grub_strcasecmp
|
||||
@@ -81,8 +81,8 @@ iterate_device (const char *name, void *data)
|
||||
if (! buf)
|
||||
return 1;
|
||||
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (buf);
|
||||
file = grub_file_open (buf, GRUB_FILE_TYPE_FS_SEARCH
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
if (file)
|
||||
{
|
||||
found = 1;
|
||||
|
||||
@@ -355,8 +355,8 @@ test_parse (char **args, int *argn, int argc)
|
||||
if (grub_strcmp (args[*argn], "-s") == 0)
|
||||
{
|
||||
grub_file_t file;
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (args[*argn + 1]);
|
||||
file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
update_val (file && (grub_file_size (file) != 0), &ctx);
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
|
||||
@@ -57,7 +57,7 @@ grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)),
|
||||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
file = grub_file_open (argv[0]);
|
||||
file = grub_file_open (argv[0], GRUB_FILE_TYPE_TESTLOAD);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ grub_cmd_testspeed (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (buffer == NULL)
|
||||
return grub_errno;
|
||||
|
||||
file = grub_file_open (args[0]);
|
||||
file = grub_file_open (args[0], GRUB_FILE_TYPE_TESTLOAD);
|
||||
if (file == NULL)
|
||||
goto quit;
|
||||
|
||||
|
||||
@@ -30,16 +30,10 @@
|
||||
#include <grub/env.h>
|
||||
#include <grub/kernel.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/verify.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
struct grub_verified
|
||||
{
|
||||
grub_file_t file;
|
||||
void *buf;
|
||||
};
|
||||
typedef struct grub_verified *grub_verified_t;
|
||||
|
||||
enum
|
||||
{
|
||||
OPTION_SKIP_SIG = 0
|
||||
@@ -445,22 +439,26 @@ rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct grub_pubkey_context
|
||||
{
|
||||
grub_file_t sig;
|
||||
struct signature_v4_header v4;
|
||||
grub_uint8_t v;
|
||||
const gcry_md_spec_t *hash;
|
||||
void *hash_context;
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_verify_signature_real (char *buf, grub_size_t size,
|
||||
grub_file_t f, grub_file_t sig,
|
||||
struct grub_public_key *pkey)
|
||||
grub_verify_signature_init (struct grub_pubkey_context *ctxt, grub_file_t sig)
|
||||
{
|
||||
grub_size_t len;
|
||||
grub_uint8_t v;
|
||||
grub_uint8_t h;
|
||||
grub_uint8_t t;
|
||||
grub_uint8_t pk;
|
||||
const gcry_md_spec_t *hash;
|
||||
struct signature_v4_header v4;
|
||||
grub_err_t err;
|
||||
grub_size_t i;
|
||||
gcry_mpi_t mpis[10];
|
||||
grub_uint8_t type = 0;
|
||||
grub_uint8_t pk;
|
||||
|
||||
grub_memset (ctxt, 0, sizeof (*ctxt));
|
||||
|
||||
err = read_packet_header (sig, &type, &len);
|
||||
if (err)
|
||||
@@ -469,18 +467,18 @@ grub_verify_signature_real (char *buf, grub_size_t size,
|
||||
if (type != 0x2)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
|
||||
if (grub_file_read (sig, &v, sizeof (v)) != sizeof (v))
|
||||
if (grub_file_read (sig, &ctxt->v, sizeof (ctxt->v)) != sizeof (ctxt->v))
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
|
||||
if (v != 4)
|
||||
if (ctxt->v != 4)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
|
||||
if (grub_file_read (sig, &v4, sizeof (v4)) != sizeof (v4))
|
||||
if (grub_file_read (sig, &ctxt->v4, sizeof (ctxt->v4)) != sizeof (ctxt->v4))
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
|
||||
h = v4.hash;
|
||||
t = v4.type;
|
||||
pk = v4.pkeyalgo;
|
||||
h = ctxt->v4.hash;
|
||||
t = ctxt->v4.type;
|
||||
pk = ctxt->v4.pkeyalgo;
|
||||
|
||||
if (t != 0)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
@@ -491,183 +489,232 @@ grub_verify_signature_real (char *buf, grub_size_t size,
|
||||
if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
|
||||
hash = grub_crypto_lookup_md_by_name (hashes[h]);
|
||||
if (!hash)
|
||||
ctxt->hash = grub_crypto_lookup_md_by_name (hashes[h]);
|
||||
if (!ctxt->hash)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, "hash `%s' not loaded", hashes[h]);
|
||||
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
|
||||
{
|
||||
void *context = NULL;
|
||||
unsigned char *hval;
|
||||
grub_ssize_t rem = grub_be_to_cpu16 (v4.hashed_sub);
|
||||
grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6);
|
||||
grub_uint8_t s;
|
||||
grub_uint16_t unhashed_sub;
|
||||
grub_ssize_t r;
|
||||
grub_uint8_t hash_start[2];
|
||||
gcry_mpi_t hmpi;
|
||||
grub_uint64_t keyid = 0;
|
||||
struct grub_public_subkey *sk;
|
||||
grub_uint8_t *readbuf = NULL;
|
||||
ctxt->sig = sig;
|
||||
|
||||
context = grub_zalloc (hash->contextsize);
|
||||
readbuf = grub_zalloc (READBUF_SIZE);
|
||||
if (!context || !readbuf)
|
||||
goto fail;
|
||||
ctxt->hash_context = grub_zalloc (ctxt->hash->contextsize);
|
||||
if (!ctxt->hash_context)
|
||||
return grub_errno;
|
||||
|
||||
hash->init (context);
|
||||
if (buf)
|
||||
hash->write (context, buf, size);
|
||||
else
|
||||
while (1)
|
||||
{
|
||||
r = grub_file_read (f, readbuf, READBUF_SIZE);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
if (r == 0)
|
||||
break;
|
||||
hash->write (context, readbuf, r);
|
||||
}
|
||||
ctxt->hash->init (ctxt->hash_context);
|
||||
|
||||
hash->write (context, &v, sizeof (v));
|
||||
hash->write (context, &v4, sizeof (v4));
|
||||
while (rem)
|
||||
{
|
||||
r = grub_file_read (sig, readbuf,
|
||||
rem < READBUF_SIZE ? rem : READBUF_SIZE);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
if (r == 0)
|
||||
break;
|
||||
hash->write (context, readbuf, r);
|
||||
rem -= r;
|
||||
}
|
||||
hash->write (context, &v, sizeof (v));
|
||||
s = 0xff;
|
||||
hash->write (context, &s, sizeof (s));
|
||||
hash->write (context, &headlen, sizeof (headlen));
|
||||
r = grub_file_read (sig, &unhashed_sub, sizeof (unhashed_sub));
|
||||
if (r != sizeof (unhashed_sub))
|
||||
goto fail;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_pubkey_write (void *ctxt_, void *buf, grub_size_t size)
|
||||
{
|
||||
struct grub_pubkey_context *ctxt = ctxt_;
|
||||
ctxt->hash->write (ctxt->hash_context, buf, size);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_verify_signature_real (struct grub_pubkey_context *ctxt,
|
||||
struct grub_public_key *pkey)
|
||||
{
|
||||
gcry_mpi_t mpis[10];
|
||||
grub_uint8_t pk = ctxt->v4.pkeyalgo;
|
||||
grub_size_t i;
|
||||
grub_uint8_t *readbuf = NULL;
|
||||
unsigned char *hval;
|
||||
grub_ssize_t rem = grub_be_to_cpu16 (ctxt->v4.hashed_sub);
|
||||
grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6);
|
||||
grub_uint8_t s;
|
||||
grub_uint16_t unhashed_sub;
|
||||
grub_ssize_t r;
|
||||
grub_uint8_t hash_start[2];
|
||||
gcry_mpi_t hmpi;
|
||||
grub_uint64_t keyid = 0;
|
||||
struct grub_public_subkey *sk;
|
||||
|
||||
readbuf = grub_malloc (READBUF_SIZE);
|
||||
if (!readbuf)
|
||||
goto fail;
|
||||
|
||||
ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v));
|
||||
ctxt->hash->write (ctxt->hash_context, &ctxt->v4, sizeof (ctxt->v4));
|
||||
while (rem)
|
||||
{
|
||||
grub_uint8_t *ptr;
|
||||
grub_uint32_t l;
|
||||
rem = grub_be_to_cpu16 (unhashed_sub);
|
||||
if (rem > READBUF_SIZE)
|
||||
r = grub_file_read (ctxt->sig, readbuf,
|
||||
rem < READBUF_SIZE ? rem : READBUF_SIZE);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
r = grub_file_read (sig, readbuf, rem);
|
||||
if (r != rem)
|
||||
if (r == 0)
|
||||
break;
|
||||
ctxt->hash->write (ctxt->hash_context, readbuf, r);
|
||||
rem -= r;
|
||||
}
|
||||
ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v));
|
||||
s = 0xff;
|
||||
ctxt->hash->write (ctxt->hash_context, &s, sizeof (s));
|
||||
ctxt->hash->write (ctxt->hash_context, &headlen, sizeof (headlen));
|
||||
r = grub_file_read (ctxt->sig, &unhashed_sub, sizeof (unhashed_sub));
|
||||
if (r != sizeof (unhashed_sub))
|
||||
goto fail;
|
||||
{
|
||||
grub_uint8_t *ptr;
|
||||
grub_uint32_t l;
|
||||
rem = grub_be_to_cpu16 (unhashed_sub);
|
||||
if (rem > READBUF_SIZE)
|
||||
goto fail;
|
||||
r = grub_file_read (ctxt->sig, readbuf, rem);
|
||||
if (r != rem)
|
||||
goto fail;
|
||||
for (ptr = readbuf; ptr < readbuf + rem; ptr += l)
|
||||
{
|
||||
if (*ptr < 192)
|
||||
l = *ptr++;
|
||||
else if (*ptr < 255)
|
||||
{
|
||||
if (ptr + 1 >= readbuf + rem)
|
||||
break;
|
||||
l = (((ptr[0] & ~192) << GRUB_CHAR_BIT) | ptr[1]) + 192;
|
||||
ptr += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ptr + 5 >= readbuf + rem)
|
||||
break;
|
||||
l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1));
|
||||
ptr += 5;
|
||||
}
|
||||
if (*ptr == 0x10 && l >= 8)
|
||||
keyid = grub_get_unaligned64 (ptr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
ctxt->hash->final (ctxt->hash_context);
|
||||
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
|
||||
hval = ctxt->hash->read (ctxt->hash_context);
|
||||
|
||||
if (grub_file_read (ctxt->sig, hash_start, sizeof (hash_start)) != sizeof (hash_start))
|
||||
goto fail;
|
||||
if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0)
|
||||
goto fail;
|
||||
|
||||
grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (ctxt->sig));
|
||||
|
||||
for (i = 0; i < pkalgos[pk].nmpisig; i++)
|
||||
{
|
||||
grub_uint16_t l;
|
||||
grub_size_t lb;
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
if (grub_file_read (ctxt->sig, &l, sizeof (l)) != sizeof (l))
|
||||
goto fail;
|
||||
for (ptr = readbuf; ptr < readbuf + rem; ptr += l)
|
||||
{
|
||||
if (*ptr < 192)
|
||||
l = *ptr++;
|
||||
else if (*ptr < 255)
|
||||
{
|
||||
if (ptr + 1 >= readbuf + rem)
|
||||
break;
|
||||
l = (((ptr[0] & ~192) << GRUB_CHAR_BIT) | ptr[1]) + 192;
|
||||
ptr += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ptr + 5 >= readbuf + rem)
|
||||
break;
|
||||
l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1));
|
||||
ptr += 5;
|
||||
}
|
||||
if (*ptr == 0x10 && l >= 8)
|
||||
keyid = grub_get_unaligned64 (ptr + 1);
|
||||
}
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
lb = (grub_be_to_cpu16 (l) + 7) / 8;
|
||||
grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l));
|
||||
if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
|
||||
goto fail;
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
if (grub_file_read (ctxt->sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
|
||||
goto fail;
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
grub_memcpy (readbuf, &l, sizeof (l));
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
|
||||
if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP,
|
||||
readbuf, lb + sizeof (grub_uint16_t), 0))
|
||||
goto fail;
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
}
|
||||
|
||||
hash->final (context);
|
||||
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
|
||||
hval = hash->read (context);
|
||||
|
||||
if (grub_file_read (sig, hash_start, sizeof (hash_start)) != sizeof (hash_start))
|
||||
if (pkey)
|
||||
sk = grub_crypto_pk_locate_subkey (keyid, pkey);
|
||||
else
|
||||
sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid);
|
||||
if (!sk)
|
||||
{
|
||||
/* TRANSLATORS: %08x is 32-bit key id. */
|
||||
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"),
|
||||
keyid);
|
||||
goto fail;
|
||||
if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0)
|
||||
}
|
||||
|
||||
if (pkalgos[pk].pad (&hmpi, hval, ctxt->hash, sk))
|
||||
goto fail;
|
||||
if (!*pkalgos[pk].algo)
|
||||
{
|
||||
grub_dl_load (pkalgos[pk].module);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
if (!*pkalgos[pk].algo)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"),
|
||||
pkalgos[pk].module);
|
||||
goto fail;
|
||||
}
|
||||
if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0))
|
||||
goto fail;
|
||||
|
||||
grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (sig));
|
||||
grub_free (readbuf);
|
||||
|
||||
for (i = 0; i < pkalgos[pk].nmpisig; i++)
|
||||
{
|
||||
grub_uint16_t l;
|
||||
grub_size_t lb;
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l))
|
||||
goto fail;
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
lb = (grub_be_to_cpu16 (l) + 7) / 8;
|
||||
grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l));
|
||||
if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
|
||||
goto fail;
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
if (grub_file_read (sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
|
||||
goto fail;
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
grub_memcpy (readbuf, &l, sizeof (l));
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP,
|
||||
readbuf, lb + sizeof (grub_uint16_t), 0))
|
||||
goto fail;
|
||||
grub_dprintf ("crypt", "alive\n");
|
||||
}
|
||||
fail:
|
||||
grub_free (readbuf);
|
||||
if (!grub_errno)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (pkey)
|
||||
sk = grub_crypto_pk_locate_subkey (keyid, pkey);
|
||||
else
|
||||
sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid);
|
||||
if (!sk)
|
||||
{
|
||||
/* TRANSLATORS: %08x is 32-bit key id. */
|
||||
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"),
|
||||
keyid);
|
||||
goto fail;
|
||||
}
|
||||
static void
|
||||
grub_pubkey_close_real (struct grub_pubkey_context *ctxt)
|
||||
{
|
||||
if (ctxt->sig)
|
||||
grub_file_close (ctxt->sig);
|
||||
if (ctxt->hash_context)
|
||||
grub_free (ctxt->hash_context);
|
||||
}
|
||||
|
||||
if (pkalgos[pk].pad (&hmpi, hval, hash, sk))
|
||||
goto fail;
|
||||
if (!*pkalgos[pk].algo)
|
||||
{
|
||||
grub_dl_load (pkalgos[pk].module);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
if (!*pkalgos[pk].algo)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"),
|
||||
pkalgos[pk].module);
|
||||
goto fail;
|
||||
}
|
||||
if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0))
|
||||
goto fail;
|
||||
|
||||
grub_free (context);
|
||||
grub_free (readbuf);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
grub_free (context);
|
||||
grub_free (readbuf);
|
||||
if (!grub_errno)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
return grub_errno;
|
||||
}
|
||||
static void
|
||||
grub_pubkey_close (void *ctxt)
|
||||
{
|
||||
grub_pubkey_close_real (ctxt);
|
||||
grub_free (ctxt);
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_verify_signature (grub_file_t f, grub_file_t sig,
|
||||
struct grub_public_key *pkey)
|
||||
{
|
||||
return grub_verify_signature_real (0, 0, f, sig, pkey);
|
||||
grub_err_t err;
|
||||
struct grub_pubkey_context ctxt;
|
||||
grub_uint8_t *readbuf = NULL;
|
||||
err = grub_verify_signature_init (&ctxt, sig);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
readbuf = grub_zalloc (READBUF_SIZE);
|
||||
if (!readbuf)
|
||||
goto fail;
|
||||
|
||||
while (1)
|
||||
{
|
||||
grub_ssize_t r;
|
||||
r = grub_file_read (f, readbuf, READBUF_SIZE);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
if (r == 0)
|
||||
break;
|
||||
err = grub_pubkey_write (&ctxt, readbuf, r);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
grub_verify_signature_real (&ctxt, pkey);
|
||||
fail:
|
||||
grub_pubkey_close_real (&ctxt);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -680,10 +727,12 @@ grub_cmd_trust (grub_extcmd_context_t ctxt,
|
||||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
|
||||
grub_file_filter_disable_compression ();
|
||||
if (ctxt->state[OPTION_SKIP_SIG].set)
|
||||
grub_file_filter_disable_pubkey ();
|
||||
pkf = grub_file_open (args[0]);
|
||||
pkf = grub_file_open (args[0],
|
||||
GRUB_FILE_TYPE_PUBLIC_KEY_TRUST
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||
| (ctxt->state[OPTION_SKIP_SIG].set
|
||||
? GRUB_FILE_TYPE_SKIP_SIGNATURE
|
||||
: 0));
|
||||
if (!pkf)
|
||||
return grub_errno;
|
||||
pk = grub_load_public_key (pkf);
|
||||
@@ -771,10 +820,12 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
|
||||
if (argc > 2)
|
||||
{
|
||||
grub_file_t pkf;
|
||||
grub_file_filter_disable_compression ();
|
||||
if (ctxt->state[OPTION_SKIP_SIG].set)
|
||||
grub_file_filter_disable_pubkey ();
|
||||
pkf = grub_file_open (args[2]);
|
||||
pkf = grub_file_open (args[2],
|
||||
GRUB_FILE_TYPE_PUBLIC_KEY
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS
|
||||
| (ctxt->state[OPTION_SKIP_SIG].set
|
||||
? GRUB_FILE_TYPE_SKIP_SIGNATURE
|
||||
: 0));
|
||||
if (!pkf)
|
||||
return grub_errno;
|
||||
pk = grub_load_public_key (pkf);
|
||||
@@ -786,16 +837,16 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
|
||||
grub_file_close (pkf);
|
||||
}
|
||||
|
||||
grub_file_filter_disable_all ();
|
||||
f = grub_file_open (args[0]);
|
||||
f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
|
||||
if (!f)
|
||||
{
|
||||
err = grub_errno;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
grub_file_filter_disable_all ();
|
||||
sig = grub_file_open (args[1]);
|
||||
sig = grub_file_open (args[1],
|
||||
GRUB_FILE_TYPE_SIGNATURE
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
if (!sig)
|
||||
{
|
||||
err = grub_errno;
|
||||
@@ -815,135 +866,52 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
|
||||
|
||||
static int sec = 0;
|
||||
|
||||
static void
|
||||
verified_free (grub_verified_t verified)
|
||||
{
|
||||
if (verified)
|
||||
{
|
||||
grub_free (verified->buf);
|
||||
grub_free (verified);
|
||||
}
|
||||
}
|
||||
|
||||
static grub_ssize_t
|
||||
verified_read (struct grub_file *file, char *buf, grub_size_t len)
|
||||
{
|
||||
grub_verified_t verified = file->data;
|
||||
|
||||
grub_memcpy (buf, (char *) verified->buf + file->offset, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
verified_close (struct grub_file *file)
|
||||
{
|
||||
grub_verified_t verified = file->data;
|
||||
|
||||
grub_file_close (verified->file);
|
||||
verified_free (verified);
|
||||
file->data = 0;
|
||||
|
||||
/* device and name are freed by parent */
|
||||
file->device = 0;
|
||||
file->name = 0;
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
struct grub_fs verified_fs =
|
||||
{
|
||||
.name = "verified_read",
|
||||
.read = verified_read,
|
||||
.close = verified_close
|
||||
};
|
||||
|
||||
static grub_file_t
|
||||
grub_pubkey_open (grub_file_t io, const char *filename)
|
||||
grub_pubkey_init (grub_file_t io, enum grub_file_type type __attribute__ ((unused)),
|
||||
void **context, enum grub_verify_flags *flags)
|
||||
{
|
||||
grub_file_t sig;
|
||||
char *fsuf, *ptr;
|
||||
grub_err_t err;
|
||||
grub_file_filter_t curfilt[GRUB_FILE_FILTER_MAX];
|
||||
grub_file_t ret;
|
||||
grub_verified_t verified;
|
||||
|
||||
if (!sec)
|
||||
return io;
|
||||
if (io->device->disk &&
|
||||
(io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID
|
||||
|| io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID))
|
||||
return io;
|
||||
fsuf = grub_malloc (grub_strlen (filename) + sizeof (".sig"));
|
||||
{
|
||||
*flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
fsuf = grub_malloc (grub_strlen (io->name) + sizeof (".sig"));
|
||||
if (!fsuf)
|
||||
return NULL;
|
||||
ptr = grub_stpcpy (fsuf, filename);
|
||||
return grub_errno;
|
||||
ptr = grub_stpcpy (fsuf, io->name);
|
||||
grub_memcpy (ptr, ".sig", sizeof (".sig"));
|
||||
|
||||
grub_memcpy (curfilt, grub_file_filters_enabled,
|
||||
sizeof (curfilt));
|
||||
grub_file_filter_disable_all ();
|
||||
sig = grub_file_open (fsuf);
|
||||
grub_memcpy (grub_file_filters_enabled, curfilt,
|
||||
sizeof (curfilt));
|
||||
sig = grub_file_open (fsuf, GRUB_FILE_TYPE_SIGNATURE);
|
||||
grub_free (fsuf);
|
||||
if (!sig)
|
||||
return NULL;
|
||||
return grub_errno;
|
||||
|
||||
ret = grub_malloc (sizeof (*ret));
|
||||
if (!ret)
|
||||
{
|
||||
grub_file_close (sig);
|
||||
return NULL;
|
||||
}
|
||||
*ret = *io;
|
||||
|
||||
ret->fs = &verified_fs;
|
||||
ret->not_easily_seekable = 0;
|
||||
if (ret->size >> (sizeof (grub_size_t) * GRUB_CHAR_BIT - 1))
|
||||
{
|
||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"big file signature isn't implemented yet");
|
||||
grub_file_close (sig);
|
||||
grub_free (ret);
|
||||
return NULL;
|
||||
}
|
||||
verified = grub_malloc (sizeof (*verified));
|
||||
if (!verified)
|
||||
struct grub_pubkey_context *ctxt = grub_malloc (sizeof (*ctxt));
|
||||
if (!ctxt)
|
||||
{
|
||||
grub_file_close (sig);
|
||||
grub_free (ret);
|
||||
return NULL;
|
||||
return grub_errno;
|
||||
}
|
||||
verified->buf = grub_malloc (ret->size);
|
||||
if (!verified->buf)
|
||||
{
|
||||
grub_file_close (sig);
|
||||
grub_free (verified);
|
||||
grub_free (ret);
|
||||
return NULL;
|
||||
}
|
||||
if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
filename);
|
||||
grub_file_close (sig);
|
||||
verified_free (verified);
|
||||
grub_free (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = grub_verify_signature_real (verified->buf, ret->size, 0, sig, NULL);
|
||||
grub_file_close (sig);
|
||||
err = grub_verify_signature_init (ctxt, sig);
|
||||
if (err)
|
||||
{
|
||||
verified_free (verified);
|
||||
grub_free (ret);
|
||||
return NULL;
|
||||
grub_pubkey_close (ctxt);
|
||||
return err;
|
||||
}
|
||||
verified->file = io;
|
||||
ret->data = verified;
|
||||
return ret;
|
||||
*context = ctxt;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_pubkey_fini (void *ctxt)
|
||||
{
|
||||
return grub_verify_signature_real (ctxt, NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -967,8 +935,16 @@ struct grub_fs pseudo_fs =
|
||||
{
|
||||
.name = "pseudo",
|
||||
.read = pseudo_read
|
||||
};
|
||||
};
|
||||
|
||||
struct grub_file_verifier grub_pubkey_verifier =
|
||||
{
|
||||
.name = "pgp",
|
||||
.init = grub_pubkey_init,
|
||||
.fini = grub_pubkey_fini,
|
||||
.write = grub_pubkey_write,
|
||||
.close = grub_pubkey_close,
|
||||
};
|
||||
|
||||
static grub_extcmd_t cmd, cmd_trust;
|
||||
static grub_command_t cmd_distrust, cmd_list;
|
||||
@@ -983,8 +959,6 @@ GRUB_MOD_INIT(verify)
|
||||
sec = 1;
|
||||
else
|
||||
sec = 0;
|
||||
|
||||
grub_file_filter_register (GRUB_FILE_FILTER_PUBKEY, grub_pubkey_open);
|
||||
|
||||
grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec);
|
||||
grub_env_export ("check_signatures");
|
||||
@@ -1030,11 +1004,13 @@ GRUB_MOD_INIT(verify)
|
||||
cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust,
|
||||
N_("PUBKEY_ID"),
|
||||
N_("Remove PUBKEY_ID from trusted keys."));
|
||||
|
||||
grub_verifier_register (&grub_pubkey_verifier);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(verify)
|
||||
{
|
||||
grub_file_filter_unregister (GRUB_FILE_FILTER_PUBKEY);
|
||||
grub_verifier_unregister (&grub_pubkey_verifier);
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_unregister_extcmd (cmd_trust);
|
||||
grub_unregister_command (cmd_list);
|
||||
|
||||
186
grub-core/commands/verify_helper.c
Normal file
186
grub-core/commands/verify_helper.c
Normal file
@@ -0,0 +1,186 @@
|
||||
#include <grub/file.h>
|
||||
#include <grub/verify.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
struct grub_file_verifier *grub_file_verifiers;
|
||||
|
||||
struct grub_verified
|
||||
{
|
||||
grub_file_t file;
|
||||
void *buf;
|
||||
};
|
||||
typedef struct grub_verified *grub_verified_t;
|
||||
|
||||
static void
|
||||
verified_free (grub_verified_t verified)
|
||||
{
|
||||
if (verified)
|
||||
{
|
||||
grub_free (verified->buf);
|
||||
grub_free (verified);
|
||||
}
|
||||
}
|
||||
|
||||
static grub_ssize_t
|
||||
verified_read (struct grub_file *file, char *buf, grub_size_t len)
|
||||
{
|
||||
grub_verified_t verified = file->data;
|
||||
|
||||
grub_memcpy (buf, (char *) verified->buf + file->offset, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
verified_close (struct grub_file *file)
|
||||
{
|
||||
grub_verified_t verified = file->data;
|
||||
|
||||
grub_file_close (verified->file);
|
||||
verified_free (verified);
|
||||
file->data = 0;
|
||||
|
||||
/* device and name are freed by parent */
|
||||
file->device = 0;
|
||||
file->name = 0;
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
struct grub_fs verified_fs =
|
||||
{
|
||||
.name = "verified_read",
|
||||
.read = verified_read,
|
||||
.close = verified_close
|
||||
};
|
||||
|
||||
static grub_file_t
|
||||
grub_verify_helper_open (grub_file_t io, enum grub_file_type type)
|
||||
{
|
||||
grub_verified_t verified = 0;
|
||||
struct grub_file_verifier *ver;
|
||||
void *context;
|
||||
grub_file_t ret = 0;
|
||||
grub_err_t err;
|
||||
|
||||
if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_SIGNATURE
|
||||
|| (type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_VERIFY_SIGNATURE
|
||||
|| (type & GRUB_FILE_TYPE_SKIP_SIGNATURE))
|
||||
return io;
|
||||
|
||||
if (io->device->disk &&
|
||||
(io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID
|
||||
|| io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID))
|
||||
return io;
|
||||
|
||||
FOR_LIST_ELEMENTS(ver, grub_file_verifiers)
|
||||
{
|
||||
enum grub_verify_flags flags = 0;
|
||||
err = ver->init (io, type, &context, &flags);
|
||||
if (err)
|
||||
goto fail_noclose;
|
||||
if (!(flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION))
|
||||
break;
|
||||
}
|
||||
if (!ver)
|
||||
/* No verifiers wanted to verify. Just return underlying file. */
|
||||
return io;
|
||||
|
||||
ret = grub_malloc (sizeof (*ret));
|
||||
if (!ret)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
*ret = *io;
|
||||
|
||||
ret->fs = &verified_fs;
|
||||
ret->not_easily_seekable = 0;
|
||||
if (ret->size >> (sizeof (grub_size_t) * GRUB_CHAR_BIT - 1))
|
||||
{
|
||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"big file signature isn't implemented yet");
|
||||
goto fail;
|
||||
}
|
||||
verified = grub_malloc (sizeof (*verified));
|
||||
if (!verified)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
verified->buf = grub_malloc (ret->size);
|
||||
if (!verified->buf)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
io->name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = ver->write (context, verified->buf, ret->size);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE;
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
ver->close (context);
|
||||
|
||||
FOR_LIST_ELEMENTS_NEXT(ver, grub_file_verifiers)
|
||||
{
|
||||
enum grub_verify_flags flags = 0;
|
||||
err = ver->init (io, type, &context, &flags);
|
||||
if (err)
|
||||
goto fail_noclose;
|
||||
if (flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION)
|
||||
continue;
|
||||
err = ver->write (context, verified->buf, ret->size);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE;
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
ver->close (context);
|
||||
}
|
||||
|
||||
verified->file = io;
|
||||
ret->data = verified;
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
ver->close (context);
|
||||
fail_noclose:
|
||||
verified_free (verified);
|
||||
grub_free (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_verify_string (char *str, enum grub_verify_string_type type)
|
||||
{
|
||||
struct grub_file_verifier *ver;
|
||||
FOR_LIST_ELEMENTS(ver, grub_file_verifiers)
|
||||
{
|
||||
grub_err_t err;
|
||||
err = ver->verify_string ? ver->verify_string (str, type) : GRUB_ERR_NONE;
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
GRUB_MOD_INIT(verify_helper)
|
||||
{
|
||||
grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verify_helper_open);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(verify_helper)
|
||||
{
|
||||
grub_file_filter_unregister (GRUB_FILE_FILTER_VERIFY);
|
||||
}
|
||||
@@ -282,6 +282,7 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
|
||||
break;
|
||||
case GRUB_CRYPTODISK_MODE_IV_PLAIN64:
|
||||
iv[1] = grub_cpu_to_le32 (sector >> 32);
|
||||
/* FALLTHROUGH */
|
||||
case GRUB_CRYPTODISK_MODE_IV_PLAIN:
|
||||
iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF);
|
||||
break;
|
||||
|
||||
@@ -80,6 +80,15 @@ make_devices (void)
|
||||
/* This should not happen... Why? */
|
||||
continue;
|
||||
|
||||
/* iPXE adds stub Block IO protocol to loaded image device handle. It is
|
||||
completely non-functional and simply returns an error for every method.
|
||||
So attempt to detect and skip it. Magic number is literal "iPXE" and
|
||||
check block size as well */
|
||||
/* FIXME: shoud we close it? We do not do it elsewhere */
|
||||
if (bio->media && bio->media->media_id == 0x69505845U &&
|
||||
bio->media->block_size == 1)
|
||||
continue;
|
||||
|
||||
d = grub_malloc (sizeof (*d));
|
||||
if (! d)
|
||||
{
|
||||
@@ -215,7 +224,7 @@ name_devices (struct grub_efidisk_data *devices)
|
||||
{
|
||||
case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
|
||||
is_hard_drive = 1;
|
||||
/* Fall through by intention. */
|
||||
/* Intentionally fall through. */
|
||||
case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
|
||||
{
|
||||
struct grub_efidisk_data *parent, *parent2;
|
||||
@@ -493,8 +502,15 @@ grub_efidisk_open (const char *name, struct grub_disk *disk)
|
||||
m = d->block_io->media;
|
||||
/* FIXME: Probably it is better to store the block size in the disk,
|
||||
and total sectors should be replaced with total blocks. */
|
||||
grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
|
||||
m, (unsigned long long) m->last_block, m->block_size);
|
||||
grub_dprintf ("efidisk",
|
||||
"m = %p, last block = %llx, block size = %x, io align = %x\n",
|
||||
m, (unsigned long long) m->last_block, m->block_size,
|
||||
m->io_align);
|
||||
|
||||
/* Ensure required buffer alignment is a power of two (or is zero). */
|
||||
if (m->io_align & (m->io_align - 1))
|
||||
return grub_error (GRUB_ERR_IO, "invalid buffer alignment %d", m->io_align);
|
||||
|
||||
disk->total_sectors = m->last_block + 1;
|
||||
/* Don't increase this value due to bug in some EFI. */
|
||||
disk->max_agglomerate = 0xa0000 >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS);
|
||||
@@ -524,15 +540,42 @@ grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector,
|
||||
{
|
||||
struct grub_efidisk_data *d;
|
||||
grub_efi_block_io_t *bio;
|
||||
grub_efi_status_t status;
|
||||
grub_size_t io_align, num_bytes;
|
||||
char *aligned_buf;
|
||||
|
||||
d = disk->data;
|
||||
bio = d->block_io;
|
||||
|
||||
return efi_call_5 ((wr ? bio->write_blocks : bio->read_blocks), bio,
|
||||
bio->media->media_id,
|
||||
(grub_efi_uint64_t) sector,
|
||||
(grub_efi_uintn_t) size << disk->log_sector_size,
|
||||
buf);
|
||||
/* Set alignment to 1 if 0 specified */
|
||||
io_align = bio->media->io_align ? bio->media->io_align : 1;
|
||||
num_bytes = size << disk->log_sector_size;
|
||||
|
||||
if ((grub_addr_t) buf & (io_align - 1))
|
||||
{
|
||||
aligned_buf = grub_memalign (io_align, num_bytes);
|
||||
if (! aligned_buf)
|
||||
return GRUB_EFI_OUT_OF_RESOURCES;
|
||||
if (wr)
|
||||
grub_memcpy (aligned_buf, buf, num_bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
aligned_buf = buf;
|
||||
}
|
||||
|
||||
status = efi_call_5 ((wr ? bio->write_blocks : bio->read_blocks), bio,
|
||||
bio->media->media_id, (grub_efi_uint64_t) sector,
|
||||
(grub_efi_uintn_t) num_bytes, aligned_buf);
|
||||
|
||||
if ((grub_addr_t) buf & (io_align - 1))
|
||||
{
|
||||
if (!wr)
|
||||
grub_memcpy (buf, aligned_buf, num_bytes);
|
||||
grub_free (aligned_buf);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -547,7 +590,9 @@ grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector,
|
||||
|
||||
status = grub_efidisk_readwrite (disk, sector, size, buf, 0);
|
||||
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
if (status == GRUB_EFI_NO_MEDIA)
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no media in `%s'"), disk->name);
|
||||
else if (status != GRUB_EFI_SUCCESS)
|
||||
return grub_error (GRUB_ERR_READ_ERROR,
|
||||
N_("failure reading sector 0x%llx from `%s'"),
|
||||
(unsigned long long) sector,
|
||||
@@ -568,7 +613,9 @@ grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector,
|
||||
|
||||
status = grub_efidisk_readwrite (disk, sector, size, (char *) buf, 1);
|
||||
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
if (status == GRUB_EFI_NO_MEDIA)
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no media in `%s'"), disk->name);
|
||||
else if (status != GRUB_EFI_SUCCESS)
|
||||
return grub_error (GRUB_ERR_WRITE_ERROR,
|
||||
N_("failure writing sector 0x%llx to `%s'"),
|
||||
(unsigned long long) sector, disk->name);
|
||||
|
||||
@@ -92,7 +92,8 @@ grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (argc < 2)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
file = grub_file_open (args[1]);
|
||||
file = grub_file_open (args[1], GRUB_FILE_TYPE_LOOPBACK
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ grub_efiemu_load_file (const char *filename)
|
||||
grub_file_t file;
|
||||
grub_err_t err;
|
||||
|
||||
file = grub_file_open (filename);
|
||||
file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
|
||||
@@ -417,6 +417,7 @@ fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
|
||||
default:
|
||||
grub_dprintf ("efiemu",
|
||||
"Unknown memory type %d. Assuming unusable\n", type);
|
||||
/* FALLTHROUGH */
|
||||
case GRUB_MEMORY_RESERVED:
|
||||
return grub_efiemu_add_to_mmap (addr, size,
|
||||
GRUB_EFI_UNUSABLE_MEMORY);
|
||||
|
||||
@@ -418,7 +418,7 @@ grub_font_load (const char *filename)
|
||||
#endif
|
||||
|
||||
if (filename[0] == '(' || filename[0] == '/' || filename[0] == '+')
|
||||
file = grub_buffile_open (filename, 1024);
|
||||
file = grub_buffile_open (filename, GRUB_FILE_TYPE_FONT, 1024);
|
||||
else
|
||||
{
|
||||
const char *prefix = grub_env_get ("prefix");
|
||||
@@ -438,7 +438,7 @@ grub_font_load (const char *filename)
|
||||
ptr = grub_stpcpy (ptr, filename);
|
||||
ptr = grub_stpcpy (ptr, ".pf2");
|
||||
*ptr = 0;
|
||||
file = grub_buffile_open (fullname, 1024);
|
||||
file = grub_buffile_open (fullname, GRUB_FILE_TYPE_FONT, 1024);
|
||||
grub_free (fullname);
|
||||
}
|
||||
if (!file)
|
||||
|
||||
@@ -227,11 +227,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
|
||||
static grub_err_t
|
||||
read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb)
|
||||
{
|
||||
struct grub_btrfs_superblock sblock;
|
||||
unsigned i;
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
for (i = 0; i < ARRAY_SIZE (superblock_sectors); i++)
|
||||
{
|
||||
struct grub_btrfs_superblock sblock;
|
||||
/* Don't try additional superblocks beyond device size. */
|
||||
if (i && (grub_le_to_cpu64 (sblock.this_device.size)
|
||||
>> GRUB_DISK_SECTOR_BITS) <= superblock_sectors[i])
|
||||
|
||||
@@ -189,7 +189,11 @@ struct grub_fshelp_node {
|
||||
struct grub_fat_data *data;
|
||||
|
||||
grub_uint8_t attr;
|
||||
grub_ssize_t file_size;
|
||||
#ifndef MODE_EXFAT
|
||||
grub_uint32_t file_size;
|
||||
#else
|
||||
grub_uint64_t file_size;
|
||||
#endif
|
||||
grub_uint32_t file_cluster;
|
||||
grub_uint32_t cur_cluster_num;
|
||||
grub_uint32_t cur_cluster;
|
||||
|
||||
@@ -750,19 +750,15 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||
|
||||
if (dir->data->joliet && !ctx.filename)
|
||||
{
|
||||
char *oldname, *semicolon;
|
||||
char *semicolon;
|
||||
|
||||
oldname = name;
|
||||
ctx.filename = grub_iso9660_convert_string
|
||||
((grub_uint8_t *) oldname, dirent.namelen >> 1);
|
||||
((grub_uint8_t *) name, dirent.namelen >> 1);
|
||||
|
||||
semicolon = grub_strrchr (ctx.filename, ';');
|
||||
if (semicolon)
|
||||
*semicolon = '\0';
|
||||
|
||||
if (ctx.filename_alloc)
|
||||
grub_free (oldname);
|
||||
|
||||
ctx.filename_alloc = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -823,7 +823,12 @@ direct_read (struct grub_squash_data *data,
|
||||
curread = data->blksz - boff;
|
||||
if (curread > len)
|
||||
curread = len;
|
||||
if (!(ino->block_sizes[i]
|
||||
if (!ino->block_sizes[i])
|
||||
{
|
||||
/* Sparse block */
|
||||
grub_memset (buf, '\0', curread);
|
||||
}
|
||||
else if (!(ino->block_sizes[i]
|
||||
& grub_cpu_to_le32_compile_time (SQUASH_BLOCK_UNCOMPRESSED)))
|
||||
{
|
||||
char *block;
|
||||
@@ -873,36 +878,57 @@ direct_read (struct grub_squash_data *data,
|
||||
|
||||
|
||||
static grub_ssize_t
|
||||
grub_squash_read_data (struct grub_squash_data *data,
|
||||
struct grub_squash_cache_inode *ino,
|
||||
grub_off_t off, char *buf, grub_size_t len)
|
||||
grub_squash_read (grub_file_t file, char *buf, grub_size_t len)
|
||||
{
|
||||
struct grub_squash_data *data = file->data;
|
||||
struct grub_squash_cache_inode *ino = &data->ino;
|
||||
grub_off_t off = file->offset;
|
||||
grub_err_t err;
|
||||
grub_uint64_t a = 0, b;
|
||||
grub_uint64_t a, b;
|
||||
grub_uint32_t fragment = 0;
|
||||
int compressed = 0;
|
||||
struct grub_squash_frag_desc frag;
|
||||
grub_off_t direct_len;
|
||||
grub_uint64_t mask = grub_le_to_cpu32 (data->sb.block_size) - 1;
|
||||
grub_size_t orig_len = len;
|
||||
|
||||
switch (ino->ino.type)
|
||||
{
|
||||
case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR):
|
||||
a = grub_le_to_cpu64 (ino->ino.long_file.chunk);
|
||||
fragment = grub_le_to_cpu32 (ino->ino.long_file.fragment);
|
||||
break;
|
||||
case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR):
|
||||
a = grub_le_to_cpu32 (ino->ino.file.chunk);
|
||||
fragment = grub_le_to_cpu32 (ino->ino.file.fragment);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fragment == 0xffffffff)
|
||||
return direct_read (data, ino, off, buf, len);
|
||||
/* Squash may pack file tail as fragment. So read initial part directly and
|
||||
get tail from fragments */
|
||||
direct_len = fragment == 0xffffffff ? file->size : file->size & ~mask;
|
||||
if (off < direct_len)
|
||||
{
|
||||
grub_size_t read_len = direct_len - off;
|
||||
grub_ssize_t res;
|
||||
|
||||
if (read_len > len)
|
||||
read_len = len;
|
||||
res = direct_read (data, ino, off, buf, read_len);
|
||||
if ((grub_size_t) res != read_len)
|
||||
return -1; /* FIXME: is short read possible here? */
|
||||
len -= read_len;
|
||||
if (!len)
|
||||
return read_len;
|
||||
buf += read_len;
|
||||
off = 0;
|
||||
}
|
||||
else
|
||||
off -= direct_len;
|
||||
|
||||
err = read_chunk (data, &frag, sizeof (frag),
|
||||
data->fragments, sizeof (frag) * fragment);
|
||||
if (err)
|
||||
return -1;
|
||||
a += grub_le_to_cpu64 (frag.offset);
|
||||
a = grub_le_to_cpu64 (frag.offset);
|
||||
compressed = !(frag.size & grub_cpu_to_le32_compile_time (SQUASH_BLOCK_UNCOMPRESSED));
|
||||
if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR))
|
||||
b = grub_le_to_cpu32 (ino->ino.long_file.offset) + off;
|
||||
@@ -943,16 +969,7 @@ grub_squash_read_data (struct grub_squash_data *data,
|
||||
if (err)
|
||||
return -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static grub_ssize_t
|
||||
grub_squash_read (grub_file_t file, char *buf, grub_size_t len)
|
||||
{
|
||||
struct grub_squash_data *data = file->data;
|
||||
|
||||
return grub_squash_read_data (data, &data->ino,
|
||||
file->offset, buf, len);
|
||||
return orig_len;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
||||
@@ -76,8 +76,13 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* incompat feature flags */
|
||||
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
|
||||
#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
|
||||
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
|
||||
|
||||
/* We do not currently verify metadata UUID so it is safe to read such filesystem */
|
||||
#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
|
||||
(XFS_SB_FEAT_INCOMPAT_FTYPE)
|
||||
(XFS_SB_FEAT_INCOMPAT_FTYPE | \
|
||||
XFS_SB_FEAT_INCOMPAT_META_UUID)
|
||||
|
||||
struct grub_xfs_sblock
|
||||
{
|
||||
|
||||
@@ -425,7 +425,7 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (argc > 0)
|
||||
{
|
||||
grub_file_t file;
|
||||
file = grub_file_open (args[0]);
|
||||
file = grub_file_open (args[0], GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY);
|
||||
if (!file)
|
||||
return grub_errno;
|
||||
real_size = grub_file_read (file, buf, 1024);
|
||||
|
||||
@@ -336,6 +336,7 @@ grub_gdb_trap (int trap_no)
|
||||
/* sAA..AA: Step one instruction from AA..AA(optional). */
|
||||
case 's':
|
||||
stepping = 1;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
/* cAA..AA: Continue at address AA..AA(optional). */
|
||||
case 'c':
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/sh
|
||||
#! @BUILD_SHEBANG@
|
||||
set -e
|
||||
|
||||
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
@@ -94,6 +94,6 @@ else
|
||||
rm -f $tmpfile.bin
|
||||
fi
|
||||
if test x@platform@ != xemu; then
|
||||
./build-grub-module-verifier@BUILD_EXEEXT@ $tmpfile @target_cpu@
|
||||
./build-grub-module-verifier@BUILD_EXEEXT@ $tmpfile @target_cpu@ @platform@
|
||||
fi
|
||||
mv $tmpfile $outfile
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/sh
|
||||
#! @BUILD_SHEBANG@
|
||||
set -e
|
||||
|
||||
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
@@ -291,7 +291,7 @@ grub_mofile_open (struct grub_gettext_context *ctx,
|
||||
/* Using fd_mo and not another variable because
|
||||
it's needed for grub_gettext_get_info. */
|
||||
|
||||
fd = grub_file_open (filename);
|
||||
fd = grub_file_open (filename, GRUB_FILE_TYPE_GETTEXT_CATALOG);
|
||||
|
||||
if (!fd)
|
||||
return grub_errno;
|
||||
|
||||
@@ -743,7 +743,7 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
|
||||
p.view = view;
|
||||
p.theme_dir = grub_get_dirname (theme_path);
|
||||
|
||||
file = grub_file_open (theme_path);
|
||||
file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME);
|
||||
if (! file)
|
||||
{
|
||||
grub_free (p.theme_dir);
|
||||
|
||||
14
grub-core/gnulib-fix-gcc7-fallthrough.diff
Normal file
14
grub-core/gnulib-fix-gcc7-fallthrough.diff
Normal file
@@ -0,0 +1,14 @@
|
||||
diff --git grub-core/gnulib/regexec.c grub-core/gnulib/regexec.c
|
||||
index f632cd4..a7776f0 100644
|
||||
--- grub-core/gnulib/regexec.c
|
||||
+++ grub-core/gnulib/regexec.c
|
||||
@@ -4099,6 +4099,9 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
|
||||
case OP_UTF8_PERIOD:
|
||||
if (ch >= ASCII_CHARS)
|
||||
return false;
|
||||
+#if defined __GNUC__ && __GNUC__ >= 7
|
||||
+ __attribute__ ((fallthrough));
|
||||
+#endif
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
case OP_PERIOD:
|
||||
@@ -4099,6 +4099,9 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
|
||||
case OP_UTF8_PERIOD:
|
||||
if (ch >= ASCII_CHARS)
|
||||
return false;
|
||||
#if defined __GNUC__ && __GNUC__ >= 7
|
||||
__attribute__ ((fallthrough));
|
||||
#endif
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
case OP_PERIOD:
|
||||
|
||||
@@ -43,7 +43,8 @@ typedef struct grub_bufio *grub_bufio_t;
|
||||
static struct grub_fs grub_bufio_fs;
|
||||
|
||||
grub_file_t
|
||||
grub_bufio_open (grub_file_t io, int size)
|
||||
grub_bufio_open (grub_file_t io,
|
||||
grub_size_t size)
|
||||
{
|
||||
grub_file_t file;
|
||||
grub_bufio_t bufio = 0;
|
||||
@@ -57,7 +58,7 @@ grub_bufio_open (grub_file_t io, int size)
|
||||
else if (size > GRUB_BUFIO_MAX_SIZE)
|
||||
size = GRUB_BUFIO_MAX_SIZE;
|
||||
|
||||
if ((size < 0) || ((unsigned) size > io->size))
|
||||
if (size > io->size)
|
||||
size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE :
|
||||
io->size);
|
||||
|
||||
@@ -81,11 +82,12 @@ grub_bufio_open (grub_file_t io, int size)
|
||||
}
|
||||
|
||||
grub_file_t
|
||||
grub_buffile_open (const char *name, int size)
|
||||
grub_buffile_open (const char *name, enum grub_file_type type,
|
||||
grub_size_t size)
|
||||
{
|
||||
grub_file_t io, file;
|
||||
|
||||
io = grub_file_open (name);
|
||||
io = grub_file_open (name, type);
|
||||
if (! io)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -1125,11 +1125,14 @@ initialize_tables (grub_gzio_t gzio)
|
||||
even if IO does not contain data compressed by gzip, return a valid file
|
||||
object. Note that this function won't close IO, even if an error occurs. */
|
||||
static grub_file_t
|
||||
grub_gzio_open (grub_file_t io, const char *name __attribute__ ((unused)))
|
||||
grub_gzio_open (grub_file_t io, enum grub_file_type type)
|
||||
{
|
||||
grub_file_t file;
|
||||
grub_gzio_t gzio = 0;
|
||||
|
||||
if (type & GRUB_FILE_TYPE_NO_DECOMPRESS)
|
||||
return io;
|
||||
|
||||
file = (grub_file_t) grub_zalloc (sizeof (*file));
|
||||
if (! file)
|
||||
return 0;
|
||||
|
||||
@@ -407,12 +407,14 @@ CORRUPTED:
|
||||
}
|
||||
|
||||
static grub_file_t
|
||||
grub_lzopio_open (grub_file_t io,
|
||||
const char *name __attribute__ ((unused)))
|
||||
grub_lzopio_open (grub_file_t io, enum grub_file_type type)
|
||||
{
|
||||
grub_file_t file;
|
||||
grub_lzopio_t lzopio;
|
||||
|
||||
if (type & GRUB_FILE_TYPE_NO_DECOMPRESS)
|
||||
return io;
|
||||
|
||||
file = (grub_file_t) grub_zalloc (sizeof (*file));
|
||||
if (!file)
|
||||
return 0;
|
||||
|
||||
@@ -69,7 +69,8 @@ grub_file_offset_close (grub_file_t file)
|
||||
}
|
||||
|
||||
grub_file_t
|
||||
grub_file_offset_open (grub_file_t parent, grub_off_t start, grub_off_t size)
|
||||
grub_file_offset_open (grub_file_t parent, enum grub_file_type type,
|
||||
grub_off_t start, grub_off_t size)
|
||||
{
|
||||
struct grub_offset_file *off_data;
|
||||
grub_file_t off_file, last_off_file;
|
||||
@@ -95,10 +96,10 @@ grub_file_offset_open (grub_file_t parent, grub_off_t start, grub_off_t size)
|
||||
last_off_file = NULL;
|
||||
for (filter = GRUB_FILE_FILTER_COMPRESSION_FIRST;
|
||||
off_file && filter <= GRUB_FILE_FILTER_COMPRESSION_LAST; filter++)
|
||||
if (grub_file_filters_enabled[filter])
|
||||
if (grub_file_filters[filter])
|
||||
{
|
||||
last_off_file = off_file;
|
||||
off_file = grub_file_filters_enabled[filter] (off_file, parent->name);
|
||||
off_file = grub_file_filters[filter] (off_file, type);
|
||||
}
|
||||
|
||||
if (!off_file)
|
||||
|
||||
@@ -169,12 +169,14 @@ ERROR:
|
||||
}
|
||||
|
||||
static grub_file_t
|
||||
grub_xzio_open (grub_file_t io,
|
||||
const char *name __attribute__ ((unused)))
|
||||
grub_xzio_open (grub_file_t io, enum grub_file_type type)
|
||||
{
|
||||
grub_file_t file;
|
||||
grub_xzio_t xzio;
|
||||
|
||||
if (type & GRUB_FILE_TYPE_NO_DECOMPRESS)
|
||||
return io;
|
||||
|
||||
file = (grub_file_t) grub_zalloc (sizeof (*file));
|
||||
if (!file)
|
||||
return 0;
|
||||
|
||||
@@ -135,4 +135,4 @@ clean_invalidate_dcache:
|
||||
pop {r4-r12, lr}
|
||||
bx lr
|
||||
|
||||
#include "cache.S"
|
||||
#include "cache.S"
|
||||
@@ -27,48 +27,14 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
/* Helper for grub_linuxbios_table_iterate. */
|
||||
static int
|
||||
check_signature (grub_linuxbios_table_header_t tbl_header)
|
||||
{
|
||||
if (! grub_memcmp (tbl_header->signature, "LBIO", 4))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t,
|
||||
void *),
|
||||
void *hook_data)
|
||||
grub_linuxbios_table_header_t
|
||||
grub_linuxbios_get_tables (void)
|
||||
{
|
||||
grub_linuxbios_table_header_t table_header
|
||||
= (grub_linuxbios_table_header_t) grub_arm_saved_registers.r[0];
|
||||
grub_linuxbios_table_item_t table_item;
|
||||
|
||||
if (!check_signature (table_header))
|
||||
if (!grub_linuxbios_check_signature (table_header))
|
||||
return 0;
|
||||
|
||||
signature_found:
|
||||
table_item =
|
||||
(grub_linuxbios_table_item_t) ((char *) table_header +
|
||||
table_header->header_size);
|
||||
for (; table_item < (grub_linuxbios_table_item_t) ((char *) table_header
|
||||
+ table_header->header_size
|
||||
+ table_header->table_size);
|
||||
table_item = (grub_linuxbios_table_item_t) ((char *) table_item + table_item->size))
|
||||
{
|
||||
if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK
|
||||
&& check_signature ((grub_linuxbios_table_header_t) (grub_addr_t)
|
||||
*(grub_uint64_t *) (table_item + 1)))
|
||||
{
|
||||
table_header = (grub_linuxbios_table_header_t) (grub_addr_t)
|
||||
*(grub_uint64_t *) (table_item + 1);
|
||||
goto signature_found;
|
||||
}
|
||||
if (hook (table_item, hook_data))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return table_header;
|
||||
}
|
||||
|
||||
@@ -97,30 +97,12 @@ heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const void *dtb;
|
||||
static grub_size_t dtb_size;
|
||||
|
||||
static int
|
||||
iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data __attribute__ ((unused)))
|
||||
{
|
||||
if (table_item->tag != GRUB_LINUXBIOS_MEMBER_DTB)
|
||||
return 0;
|
||||
|
||||
if (grub_fdt_check_header (table_item + 1, table_item->size) >= 0)
|
||||
{
|
||||
dtb = table_item + 1;
|
||||
dtb_size = table_item->size;
|
||||
}
|
||||
else
|
||||
grub_printf ("Invalid DTB supplied by coreboot\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
grub_machine_init (void)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
void *dtb = 0;
|
||||
grub_size_t dtb_size = 0;
|
||||
|
||||
modend = grub_modules_get_end ();
|
||||
|
||||
@@ -146,12 +128,12 @@ grub_machine_init (void)
|
||||
grub_memmove (dtb_copy, dtb_orig_addr, dtb_size);
|
||||
break;
|
||||
}
|
||||
if (!dtb)
|
||||
grub_linuxbios_table_iterate (iterate_linuxbios_table, 0);
|
||||
if (!dtb)
|
||||
grub_fatal ("No DTB found");
|
||||
grub_fdtbus_init (dtb, dtb_size);
|
||||
|
||||
grub_rk3288_spi_init ();
|
||||
|
||||
grub_machine_timer_init ();
|
||||
grub_cros_init ();
|
||||
grub_pl050_init ();
|
||||
|
||||
@@ -173,6 +173,8 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||
sym_addr += grub_arm_thm_call_get_offset ((grub_uint16_t *) target);
|
||||
|
||||
grub_dprintf ("dl", " sym_addr = 0x%08x\n", sym_addr);
|
||||
if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
|
||||
sym_addr |= 1;
|
||||
|
||||
offset = sym_addr - (grub_uint32_t) target;
|
||||
|
||||
@@ -227,13 +229,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||
|
||||
sym_addr += grub_arm_thm_jump19_get_offset ((grub_uint16_t *) target);
|
||||
|
||||
if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
|
||||
sym_addr |= 1;
|
||||
|
||||
offset = sym_addr - (grub_uint32_t) target;
|
||||
|
||||
if (!grub_arm_thm_jump19_check_offset (offset)
|
||||
|| !(sym_addr & 1))
|
||||
{
|
||||
struct trampoline_thumb *tp = mod->gotptr;
|
||||
mod->gotptr = tp + 1;
|
||||
struct trampoline_thumb *tp = mod->trampptr;
|
||||
mod->trampptr = tp + 1;
|
||||
grub_memcpy (tp->template, thumb_template, sizeof (tp->template));
|
||||
tp->neg_addr = -sym_addr - 4;
|
||||
offset = ((grub_uint8_t *) tp - (grub_uint8_t *) target - 4) | 1;
|
||||
|
||||
@@ -167,7 +167,7 @@ VARIABLE(grub_arm_saved_registers)
|
||||
.long 0 @ r4
|
||||
.long 0 @ r5
|
||||
.long 0 @ r6
|
||||
.long 0 @ r7
|
||||
.long 0 @ r7
|
||||
.long 0 @ r8
|
||||
.long 0 @ r9
|
||||
.long 0 @ r10
|
||||
|
||||
@@ -29,10 +29,10 @@ grub_uboot_get_machine_type (void)
|
||||
return grub_arm_saved_registers.r[1];
|
||||
}
|
||||
|
||||
const void *
|
||||
grub_addr_t
|
||||
grub_uboot_get_boot_data (void)
|
||||
{
|
||||
return (const void *) grub_arm_saved_registers.r[2];
|
||||
return grub_arm_saved_registers.r[2];
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -25,14 +25,9 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/cpu/reloc.h>
|
||||
|
||||
struct trampoline
|
||||
{
|
||||
#define LDR 0x58000050
|
||||
#define BR 0xd61f0200
|
||||
grub_uint32_t ldr; /* ldr x16, 8 */
|
||||
grub_uint32_t br; /* br x16 */
|
||||
grub_uint64_t addr;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Check if EHDR is a valid ELF header.
|
||||
@@ -53,42 +48,6 @@ grub_arch_dl_check_header (void *ehdr)
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
grub_err_t
|
||||
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
|
||||
grub_size_t *got)
|
||||
{
|
||||
const Elf_Ehdr *e = ehdr;
|
||||
const Elf_Shdr *s;
|
||||
unsigned i;
|
||||
|
||||
*tramp = 0;
|
||||
*got = 0;
|
||||
|
||||
for (i = 0, s = (const Elf_Shdr *) ((grub_addr_t) e + e->e_shoff);
|
||||
i < e->e_shnum;
|
||||
i++, s = (const Elf_Shdr *) ((grub_addr_t) s + e->e_shentsize))
|
||||
if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA)
|
||||
{
|
||||
const Elf_Rel *rel, *max;
|
||||
|
||||
for (rel = (const Elf_Rel *) ((grub_addr_t) e + s->sh_offset),
|
||||
max = rel + s->sh_size / s->sh_entsize;
|
||||
rel < max;
|
||||
rel = (const Elf_Rel *) ((grub_addr_t) rel + s->sh_entsize))
|
||||
switch (ELF_R_TYPE (rel->r_info))
|
||||
{
|
||||
case R_AARCH64_CALL26:
|
||||
case R_AARCH64_JUMP26:
|
||||
{
|
||||
*tramp += sizeof (struct trampoline);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unified function for both REL and RELA
|
||||
*/
|
||||
@@ -97,6 +56,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||
Elf_Shdr *s, grub_dl_segment_t seg)
|
||||
{
|
||||
Elf_Rel *rel, *max;
|
||||
unsigned unmatched_adr_got_page = 0;
|
||||
|
||||
for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset),
|
||||
max = (Elf_Rel *) ((char *) rel + s->sh_size);
|
||||
@@ -145,7 +105,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||
|
||||
if (!grub_arm_64_check_xxxx26_offset (offset))
|
||||
{
|
||||
struct trampoline *tp = mod->trampptr;
|
||||
struct grub_arm64_trampoline *tp = mod->trampptr;
|
||||
mod->trampptr = tp + 1;
|
||||
tp->ldr = LDR;
|
||||
tp->br = BR;
|
||||
@@ -160,6 +120,56 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||
grub_arm64_set_xxxx26_offset (place, offset);
|
||||
}
|
||||
break;
|
||||
case R_AARCH64_PREL32:
|
||||
{
|
||||
grub_int64_t value;
|
||||
Elf64_Word *addr32 = place;
|
||||
value = ((grub_int32_t) *addr32) + sym_addr -
|
||||
(Elf64_Xword) (grub_addr_t) seg->addr - rel->r_offset;
|
||||
if (value != (grub_int32_t) value)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
|
||||
grub_dprintf("dl", " reloc_prel32 %p => 0x%016llx\n",
|
||||
place, (unsigned long long) sym_addr);
|
||||
*addr32 = value;
|
||||
}
|
||||
break;
|
||||
case R_AARCH64_ADR_GOT_PAGE:
|
||||
{
|
||||
grub_uint64_t *gp = mod->gotptr;
|
||||
Elf_Rela *rel2;
|
||||
grub_int64_t gpoffset = ((grub_uint64_t) gp & ~0xfffULL) - (((grub_uint64_t) place) & ~0xfffULL);
|
||||
*gp = (grub_uint64_t) sym_addr;
|
||||
mod->gotptr = gp + 1;
|
||||
unmatched_adr_got_page++;
|
||||
grub_dprintf("dl", " reloc_got %p => 0x%016llx (0x%016llx)\n",
|
||||
place, (unsigned long long) sym_addr, (unsigned long long) gp);
|
||||
if (!grub_arm64_check_hi21_signed (gpoffset))
|
||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||
"HI21 out of range");
|
||||
grub_arm64_set_hi21(place, gpoffset);
|
||||
for (rel2 = (Elf_Rela *) ((char *) rel + s->sh_entsize);
|
||||
rel2 < (Elf_Rela *) max;
|
||||
rel2 = (Elf_Rela *) ((char *) rel2 + s->sh_entsize))
|
||||
if (ELF_R_SYM (rel2->r_info)
|
||||
== ELF_R_SYM (rel->r_info)
|
||||
&& ((Elf_Rela *) rel)->r_addend == rel2->r_addend
|
||||
&& ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC)
|
||||
{
|
||||
grub_arm64_set_abs_lo12_ldst64 ((void *) ((grub_addr_t) seg->addr + rel2->r_offset),
|
||||
(grub_uint64_t)gp);
|
||||
break;
|
||||
}
|
||||
if (rel2 >= (Elf_Rela *) max)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||
"ADR_GOT_PAGE without matching LD64_GOT_LO12_NC");
|
||||
}
|
||||
break;
|
||||
case R_AARCH64_LD64_GOT_LO12_NC:
|
||||
if (unmatched_adr_got_page == 0)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||
"LD64_GOT_LO12_NC without matching ADR_GOT_PAGE");
|
||||
unmatched_adr_got_page--;
|
||||
break;
|
||||
case R_AARCH64_ADR_PREL_PG_HI21:
|
||||
{
|
||||
grub_int64_t offset = (sym_addr & ~0xfffULL) - (((grub_uint64_t) place) & ~0xfffULL);
|
||||
|
||||
@@ -93,3 +93,42 @@ grub_arm64_set_abs_lo12_ldst64 (grub_uint32_t *place, grub_int64_t target)
|
||||
*place &= insmask;
|
||||
*place |= grub_cpu_to_le32 (target << 7) & ~insmask;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
grub_err_t
|
||||
grub_arm64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
|
||||
grub_size_t *got)
|
||||
{
|
||||
const Elf64_Ehdr *e = ehdr;
|
||||
const Elf64_Shdr *s;
|
||||
unsigned i;
|
||||
|
||||
*tramp = 0;
|
||||
*got = 0;
|
||||
|
||||
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu64 (e->e_shoff));
|
||||
i < grub_le_to_cpu16 (e->e_shnum);
|
||||
i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize)))
|
||||
if (s->sh_type == grub_cpu_to_le32_compile_time (SHT_REL)
|
||||
|| s->sh_type == grub_cpu_to_le32_compile_time (SHT_RELA))
|
||||
{
|
||||
const Elf64_Rela *rel, *max;
|
||||
|
||||
for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu64 (s->sh_offset)),
|
||||
max = (const Elf64_Rela *) ((char *) rel + grub_le_to_cpu64 (s->sh_size));
|
||||
rel < max; rel = (const Elf64_Rela *) ((char *) rel + grub_le_to_cpu64 (s->sh_entsize)))
|
||||
switch (ELF64_R_TYPE (rel->r_info))
|
||||
{
|
||||
case R_AARCH64_CALL26:
|
||||
case R_AARCH64_JUMP26:
|
||||
*tramp += sizeof (struct grub_arm64_trampoline);
|
||||
break;
|
||||
case R_AARCH64_ADR_GOT_PAGE:
|
||||
*got += 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
72
grub-core/kern/coreboot/cbtable.c
Normal file
72
grub-core/kern/coreboot/cbtable.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2007,2008,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/i386/coreboot/memory.h>
|
||||
#include <grub/coreboot/lbio.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
/* Helper for grub_linuxbios_table_iterate. */
|
||||
int
|
||||
grub_linuxbios_check_signature (grub_linuxbios_table_header_t tbl_header)
|
||||
{
|
||||
if (! grub_memcmp (tbl_header->signature, "LBIO", 4))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t,
|
||||
void *),
|
||||
void *hook_data)
|
||||
{
|
||||
grub_linuxbios_table_header_t table_header = grub_linuxbios_get_tables ();
|
||||
grub_linuxbios_table_item_t table_item;
|
||||
|
||||
if (!table_header)
|
||||
return 0;
|
||||
|
||||
signature_found:
|
||||
|
||||
table_item =
|
||||
(grub_linuxbios_table_item_t) ((char *) table_header +
|
||||
table_header->header_size);
|
||||
for (; table_item < (grub_linuxbios_table_item_t) ((char *) table_header
|
||||
+ table_header->header_size
|
||||
+ table_header->table_size);
|
||||
table_item = (grub_linuxbios_table_item_t) ((char *) table_item + table_item->size))
|
||||
{
|
||||
if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK
|
||||
&& grub_linuxbios_check_signature ((grub_linuxbios_table_header_t) (grub_addr_t)
|
||||
*(grub_uint64_t *) (table_item + 1)))
|
||||
{
|
||||
table_header = (grub_linuxbios_table_header_t) (grub_addr_t)
|
||||
*(grub_uint64_t *) (table_item + 1);
|
||||
goto signature_found;
|
||||
}
|
||||
if (hook (table_item, hook_data))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -688,7 +688,7 @@ grub_dl_load_file (const char *filename)
|
||||
|
||||
grub_boot_time ("Loading module %s", filename);
|
||||
|
||||
file = grub_file_open (filename);
|
||||
file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE);
|
||||
if (! file)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -366,6 +366,9 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
||||
len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
|
||||
/ sizeof (grub_efi_char16_t));
|
||||
fp = (grub_efi_file_path_device_path_t *) dp;
|
||||
/* According to EFI spec Path Name is NULL terminated */
|
||||
while (len > 0 && fp->path_name[len - 1] == 0)
|
||||
len--;
|
||||
|
||||
p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, fp->path_name, len);
|
||||
}
|
||||
|
||||
43
grub-core/kern/efi/fdt.c
Normal file
43
grub-core/kern/efi/fdt.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/* fdt.c - EFI Flattened Device Tree interaction */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2006,2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/mm.h>
|
||||
|
||||
void *
|
||||
grub_efi_get_firmware_fdt (void)
|
||||
{
|
||||
grub_efi_configuration_table_t *tables;
|
||||
grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
|
||||
void *firmware_fdt = NULL;
|
||||
unsigned int i;
|
||||
|
||||
/* Look for FDT in UEFI config tables. */
|
||||
tables = grub_efi_system_table->configuration_table;
|
||||
|
||||
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||
if (grub_memcmp (&tables[i].vendor_guid, &fdt_guid, sizeof (fdt_guid)) == 0)
|
||||
{
|
||||
firmware_fdt = tables[i].vendor_table;
|
||||
grub_dprintf ("linux", "found registered FDT @ %p\n", firmware_fdt);
|
||||
break;
|
||||
}
|
||||
|
||||
return firmware_fdt;
|
||||
}
|
||||
@@ -59,10 +59,13 @@ grub_machine_get_bootlocation (char **device, char **path)
|
||||
if (!image)
|
||||
return;
|
||||
*device = grub_efidisk_get_device_name (image->device_handle);
|
||||
*path = grub_efi_get_filename (image->file_path);
|
||||
if (!*device && grub_efi_net_config)
|
||||
grub_efi_net_config (image->device_handle, device, path);
|
||||
{
|
||||
grub_efi_net_config (image->device_handle, device, path);
|
||||
return;
|
||||
}
|
||||
|
||||
*path = grub_efi_get_filename (image->file_path);
|
||||
if (*path)
|
||||
{
|
||||
/* Get the directory. */
|
||||
|
||||
@@ -136,12 +136,12 @@ fail:
|
||||
}
|
||||
|
||||
grub_elf_t
|
||||
grub_elf_open (const char *name)
|
||||
grub_elf_open (const char *name, enum grub_file_type type)
|
||||
{
|
||||
grub_file_t file;
|
||||
grub_elf_t elf;
|
||||
|
||||
file = grub_file_open (name);
|
||||
file = grub_file_open (name, type);
|
||||
if (! file)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ void
|
||||
grub_reboot (void)
|
||||
{
|
||||
longjmp (main_env, 1);
|
||||
grub_fatal ("longjmp failed");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -127,6 +127,7 @@ xasprintf (const char *fmt, ...)
|
||||
|
||||
va_start (ap, fmt);
|
||||
result = grub_xvasprintf (fmt, ap);
|
||||
va_end (ap);
|
||||
if (!result)
|
||||
grub_util_error ("%s", _("out of memory"));
|
||||
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
|
||||
void (*EXPORT_VAR (grub_grubnet_fini)) (void);
|
||||
|
||||
grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX];
|
||||
grub_file_filter_t grub_file_filters_enabled[GRUB_FILE_FILTER_MAX];
|
||||
grub_file_filter_t grub_file_filters[GRUB_FILE_FILTER_MAX];
|
||||
|
||||
/* Get the device part of the filename NAME. It is enclosed by parentheses. */
|
||||
char *
|
||||
@@ -59,7 +58,7 @@ grub_file_get_device_name (const char *name)
|
||||
}
|
||||
|
||||
grub_file_t
|
||||
grub_file_open (const char *name)
|
||||
grub_file_open (const char *name, enum grub_file_type type)
|
||||
{
|
||||
grub_device_t device = 0;
|
||||
grub_file_t file = 0, last_file = 0;
|
||||
@@ -114,18 +113,20 @@ grub_file_open (const char *name)
|
||||
file->name = grub_strdup (name);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters_enabled);
|
||||
for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters);
|
||||
filter++)
|
||||
if (grub_file_filters_enabled[filter])
|
||||
if (grub_file_filters[filter])
|
||||
{
|
||||
last_file = file;
|
||||
file = grub_file_filters_enabled[filter] (file, name);
|
||||
file = grub_file_filters[filter] (file, type);
|
||||
if (file && file != last_file)
|
||||
{
|
||||
file->name = grub_strdup (name);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
if (!file)
|
||||
grub_file_close (last_file);
|
||||
|
||||
grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
|
||||
sizeof (grub_file_filters_enabled));
|
||||
|
||||
return file;
|
||||
|
||||
@@ -137,9 +138,6 @@ grub_file_open (const char *name)
|
||||
|
||||
grub_free (file);
|
||||
|
||||
grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
|
||||
sizeof (grub_file_filters_enabled));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,59 +25,20 @@
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* Helper for grub_linuxbios_table_iterate. */
|
||||
static int
|
||||
check_signature (grub_linuxbios_table_header_t tbl_header)
|
||||
{
|
||||
if (! grub_memcmp (tbl_header->signature, "LBIO", 4))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t,
|
||||
void *),
|
||||
void *hook_data)
|
||||
grub_linuxbios_table_header_t
|
||||
grub_linuxbios_get_tables (void)
|
||||
{
|
||||
grub_linuxbios_table_header_t table_header;
|
||||
grub_linuxbios_table_item_t table_item;
|
||||
|
||||
/* Assuming table_header is aligned to its size (8 bytes). */
|
||||
|
||||
for (table_header = (grub_linuxbios_table_header_t) 0x500;
|
||||
table_header < (grub_linuxbios_table_header_t) 0x1000; table_header++)
|
||||
if (check_signature (table_header))
|
||||
goto signature_found;
|
||||
if (grub_linuxbios_check_signature (table_header))
|
||||
return table_header;
|
||||
|
||||
for (table_header = (grub_linuxbios_table_header_t) 0xf0000;
|
||||
table_header < (grub_linuxbios_table_header_t) 0x100000; table_header++)
|
||||
if (check_signature (table_header))
|
||||
goto signature_found;
|
||||
|
||||
return 0;
|
||||
|
||||
signature_found:
|
||||
|
||||
table_item =
|
||||
(grub_linuxbios_table_item_t) ((char *) table_header +
|
||||
table_header->header_size);
|
||||
for (; table_item < (grub_linuxbios_table_item_t) ((char *) table_header
|
||||
+ table_header->header_size
|
||||
+ table_header->table_size);
|
||||
table_item = (grub_linuxbios_table_item_t) ((char *) table_item + table_item->size))
|
||||
{
|
||||
if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK
|
||||
&& check_signature ((grub_linuxbios_table_header_t) (grub_addr_t)
|
||||
*(grub_uint64_t *) (table_item + 1)))
|
||||
{
|
||||
table_header = (grub_linuxbios_table_header_t) (grub_addr_t)
|
||||
*(grub_uint64_t *) (table_item + 1);
|
||||
goto signature_found;
|
||||
}
|
||||
if (hook (table_item, hook_data))
|
||||
return 1;
|
||||
}
|
||||
if (grub_linuxbios_check_signature (table_header))
|
||||
return table_header;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -104,6 +104,9 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||
case R_IA64_PCREL64LSB:
|
||||
*(grub_uint64_t *) addr += value - addr;
|
||||
break;
|
||||
case R_IA64_GPREL64I:
|
||||
grub_ia64_set_immu64 (addr, value - (grub_addr_t) mod->base);
|
||||
break;
|
||||
case R_IA64_GPREL22:
|
||||
if ((value - (grub_addr_t) mod->base) & ~MASK20)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||
@@ -116,6 +119,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||
case R_IA64_LTOFF22:
|
||||
if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
|
||||
value = *(grub_uint64_t *) sym->st_value + rel->r_addend;
|
||||
/* Fallthrough. */
|
||||
case R_IA64_LTOFF_FPTR22:
|
||||
{
|
||||
grub_uint64_t *gpptr = mod->gotptr;
|
||||
|
||||
@@ -30,6 +30,40 @@
|
||||
#define MASK20 ((1 << 20) - 1)
|
||||
#define MASK3 (~(grub_addr_t) 3)
|
||||
|
||||
void
|
||||
grub_ia64_set_immu64 (grub_addr_t addr, grub_uint64_t val)
|
||||
{
|
||||
/* Copied from binutils. */
|
||||
grub_uint64_t *ptr = ((grub_uint64_t *) (addr & MASK3));
|
||||
grub_uint64_t t0, t1;
|
||||
|
||||
t0 = grub_le_to_cpu64 (ptr[0]);
|
||||
t1 = grub_le_to_cpu64 (ptr[1]);
|
||||
|
||||
/* tmpl/s: bits 0.. 5 in t0
|
||||
slot 0: bits 5..45 in t0
|
||||
slot 1: bits 46..63 in t0, bits 0..22 in t1
|
||||
slot 2: bits 23..63 in t1 */
|
||||
|
||||
/* First, clear the bits that form the 64 bit constant. */
|
||||
t0 &= ~(0x3ffffLL << 46);
|
||||
t1 &= ~(0x7fffffLL
|
||||
| (( (0x07fLL << 13) | (0x1ffLL << 27)
|
||||
| (0x01fLL << 22) | (0x001LL << 21)
|
||||
| (0x001LL << 36)) << 23));
|
||||
|
||||
t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
|
||||
t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
|
||||
t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
|
||||
| (((val >> 7) & 0x1ff) << 27) /* imm9d */
|
||||
| (((val >> 16) & 0x01f) << 22) /* imm5c */
|
||||
| (((val >> 21) & 0x001) << 21) /* ic */
|
||||
| (((val >> 63) & 0x001) << 36)) << 23; /* i */
|
||||
|
||||
ptr[0] = t0;
|
||||
ptr[1] = t1;
|
||||
}
|
||||
|
||||
void
|
||||
grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value)
|
||||
{
|
||||
@@ -182,11 +216,11 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
|
||||
i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize)))
|
||||
if (s->sh_type == grub_cpu_to_le32_compile_time (SHT_RELA))
|
||||
{
|
||||
Elf64_Rela *rel, *max;
|
||||
const Elf64_Rela *rel, *max;
|
||||
|
||||
for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu64 (s->sh_offset)),
|
||||
max = rel + grub_le_to_cpu64 (s->sh_size) / grub_le_to_cpu64 (s->sh_entsize);
|
||||
rel < max; rel++)
|
||||
max = (const Elf64_Rela *) ((char *) rel + grub_le_to_cpu64 (s->sh_size));
|
||||
rel < max; rel = (const Elf64_Rela *) ((char *) rel + grub_le_to_cpu64 (s->sh_entsize)))
|
||||
switch (ELF64_R_TYPE (grub_le_to_cpu64 (rel->r_info)))
|
||||
{
|
||||
case R_IA64_PCREL21B:
|
||||
|
||||
@@ -25,7 +25,7 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
|
||||
{
|
||||
grub_ieee1275_phandle_t root;
|
||||
grub_ieee1275_phandle_t memory;
|
||||
grub_uint32_t available[32];
|
||||
grub_uint32_t available[128];
|
||||
grub_ssize_t available_size;
|
||||
grub_uint32_t address_cells = 1;
|
||||
grub_uint32_t size_cells = 1;
|
||||
@@ -49,6 +49,9 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
|
||||
sizeof available, &available_size))
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
|
||||
"couldn't examine /memory/available property");
|
||||
if (available_size < 0 || (grub_size_t) available_size > sizeof (available))
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
|
||||
"/memory response buffer exceeded");
|
||||
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS))
|
||||
{
|
||||
|
||||
@@ -236,6 +236,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||
sym_value &= 0xffff0000;
|
||||
*(grub_uint16_t *) addr = 0;
|
||||
}
|
||||
/* Fallthrough. */
|
||||
case R_MIPS_CALL16:
|
||||
{
|
||||
grub_uint32_t *gpptr = mod->gotptr;
|
||||
|
||||
@@ -391,12 +391,13 @@ grub_strtoull (const char *str, char **end, int base)
|
||||
unsigned long digit;
|
||||
|
||||
digit = grub_tolower (*str) - '0';
|
||||
if (digit > 9)
|
||||
{
|
||||
digit += '0' - 'a' + 10;
|
||||
if (digit >= (unsigned long) base)
|
||||
break;
|
||||
}
|
||||
if (digit >= 'a' - '0')
|
||||
digit += '0' - 'a' + 10;
|
||||
else if (digit > 9)
|
||||
break;
|
||||
|
||||
if (digit >= (unsigned long) base)
|
||||
break;
|
||||
|
||||
found = 1;
|
||||
|
||||
|
||||
@@ -159,6 +159,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||
if (value >> 32)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||
"address out of 32 bits range");
|
||||
/* Fallthrough. */
|
||||
case R_SPARC_LM22:
|
||||
*addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF);
|
||||
break;
|
||||
|
||||
@@ -62,12 +62,13 @@ unsigned int grub_loader_cmdline_size (int argc, char *argv[])
|
||||
return size;
|
||||
}
|
||||
|
||||
int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
|
||||
grub_size_t size)
|
||||
grub_err_t
|
||||
grub_create_loader_cmdline (int argc, char *argv[], char *buf,
|
||||
grub_size_t size, enum grub_verify_string_type type)
|
||||
{
|
||||
int i, space;
|
||||
unsigned int arg_size;
|
||||
char *c;
|
||||
char *c, *orig_buf = buf;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
@@ -104,5 +105,5 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
|
||||
|
||||
*buf = 0;
|
||||
|
||||
return i;
|
||||
return grub_verify_string (orig_buf, type);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/uboot/uboot.h>
|
||||
#include <grub/datetime.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
@@ -30,12 +29,12 @@ grub_err_t
|
||||
grub_get_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
|
||||
{
|
||||
return grub_error (GRUB_ERR_INVALID_COMMAND,
|
||||
"can\'t get datetime using U-Boot");
|
||||
"can\'t get datetime on this machine");
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_set_datetime (struct grub_datetime * datetime __attribute__ ((unused)))
|
||||
{
|
||||
return grub_error (GRUB_ERR_INVALID_COMMAND,
|
||||
"can\'t set datetime using U-Boot");
|
||||
"can\'t set datetime on this machine");
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
/* ehci.c - EHCI Support. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,27 +18,15 @@
|
||||
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/usb.h>
|
||||
#include <grub/fdtbus.h>
|
||||
|
||||
static grub_err_t
|
||||
dwc2_attach(const struct grub_fdtbus_dev *dev)
|
||||
{
|
||||
grub_dprintf ("dwc2", "Found snps-dwc2\n");
|
||||
|
||||
grub_dwc2_init_device (grub_fdtbus_map_reg (dev, 0, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct grub_fdtbus_driver dwc2 =
|
||||
{
|
||||
.compatible = "snps,dwc2",
|
||||
.attach = dwc2_attach
|
||||
};
|
||||
#include <grub/kernel.h>
|
||||
#include <grub/loader.h>
|
||||
|
||||
void
|
||||
grub_dwc2_pci_scan (void)
|
||||
grub_reboot (void)
|
||||
{
|
||||
grub_fdtbus_register (&dwc2);
|
||||
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
|
||||
|
||||
/* Just stop here */
|
||||
|
||||
while (1);
|
||||
}
|
||||
@@ -73,6 +73,22 @@ VARIABLE(grub_relocator64_rsp)
|
||||
|
||||
movq %rax, %rsp
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
jmp LOCAL(skip_efi_stack_align)
|
||||
|
||||
/*
|
||||
* Here is grub_relocator64_efi_start() entry point. Most of the
|
||||
* code below is shared between grub_relocator64_efi_start()
|
||||
* and grub_relocator64_start().
|
||||
*
|
||||
* Think twice before changing anything there!!!
|
||||
*/
|
||||
VARIABLE(grub_relocator64_efi_start)
|
||||
/* Align the stack as UEFI spec requires. */
|
||||
andq $~15, %rsp
|
||||
|
||||
LOCAL(skip_efi_stack_align):
|
||||
#endif
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
@@ -120,6 +136,11 @@ LOCAL(jump_addr):
|
||||
VARIABLE(grub_relocator64_rip)
|
||||
.quad 0
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
/* Here grub_relocator64_efi_start() ends. Ufff... */
|
||||
VARIABLE(grub_relocator64_efi_end)
|
||||
#endif
|
||||
|
||||
#ifndef __x86_64__
|
||||
.p2align 4
|
||||
LOCAL(gdt):
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/i386/memory.h>
|
||||
#include <grub/i386/types.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/xen.h>
|
||||
|
||||
@@ -23,78 +25,86 @@
|
||||
|
||||
VARIABLE(grub_relocator_xen_remap_start)
|
||||
LOCAL(base):
|
||||
/* mov imm32, %ebx */
|
||||
/* Remap the remapper to it's new address. */
|
||||
/* mov imm32, %ebx - %ebx: new virtual address of remapper */
|
||||
.byte 0xbb
|
||||
VARIABLE(grub_relocator_xen_remapper_virt)
|
||||
.long 0
|
||||
|
||||
/* mov imm32, %ecx */
|
||||
/* mov imm32, %ecx - %ecx: low part of page table entry */
|
||||
.byte 0xb9
|
||||
VARIABLE(grub_relocator_xen_remapper_map)
|
||||
.long 0
|
||||
|
||||
/* mov imm32, %edx */
|
||||
/* mov imm32, %edx - %edx: high part of page table entry */
|
||||
.byte 0xba
|
||||
VARIABLE(grub_relocator_xen_remapper_map_high)
|
||||
.long 0
|
||||
|
||||
movl %ebx, %ebp
|
||||
movl %ebx, %ebp /* %ebx is clobbered by hypercall */
|
||||
|
||||
movl $2, %esi
|
||||
movl $UVMF_INVLPG, %esi /* esi: flags (inv. single entry) */
|
||||
movl $__HYPERVISOR_update_va_mapping, %eax
|
||||
int $0x82
|
||||
|
||||
movl %ebp, %ebx
|
||||
addl $(LOCAL(cont) - LOCAL(base)), %ebx
|
||||
|
||||
jmp *%ebx
|
||||
jmp *%ebx /* Continue with new virtual address */
|
||||
|
||||
LOCAL(cont):
|
||||
xorl %eax, %eax
|
||||
movl %eax, %ebp
|
||||
/* Modify mappings of new page tables to be read-only. */
|
||||
/* mov imm32, %eax */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_paging_areas_addr)
|
||||
.long 0
|
||||
movl %eax, %ebx
|
||||
1:
|
||||
movl 0(%ebx), %ebp /* Get start pfn of the current area */
|
||||
movl GRUB_TARGET_SIZEOF_LONG(%ebx), %ecx /* Get # of pg tables */
|
||||
testl %ecx, %ecx /* 0 -> last area reached */
|
||||
jz 3f
|
||||
addl $(2 * GRUB_TARGET_SIZEOF_LONG), %ebx
|
||||
movl %ebx, %esp /* Save current area pointer */
|
||||
|
||||
2:
|
||||
movl %ecx, %edi
|
||||
/* mov imm32, %eax */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_mfn_list)
|
||||
.long 0
|
||||
movl %eax, %edi
|
||||
movl %ebp, %eax
|
||||
movl 0(%edi, %eax, 4), %ecx
|
||||
|
||||
/* mov imm32, %ebx */
|
||||
.byte 0xbb
|
||||
VARIABLE(grub_relocator_xen_paging_start)
|
||||
.long 0
|
||||
shll $12, %eax
|
||||
addl %eax, %ebx
|
||||
movl 0(%eax, %ebp, 4), %ecx /* mfn */
|
||||
movl %ebp, %ebx
|
||||
shll $PAGE_SHIFT, %ebx /* virtual address (1:1 mapping) */
|
||||
movl %ecx, %edx
|
||||
shll $12, %ecx
|
||||
shrl $20, %edx
|
||||
orl $5, %ecx
|
||||
movl $2, %esi
|
||||
shll $PAGE_SHIFT, %ecx /* prepare pte low part */
|
||||
shrl $(32 - PAGE_SHIFT), %edx /* pte high part */
|
||||
orl $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %ecx /* pte low */
|
||||
movl $UVMF_INVLPG, %esi
|
||||
movl $__HYPERVISOR_update_va_mapping, %eax
|
||||
int $0x82
|
||||
int $0x82 /* parameters: eax, ebx, ecx, edx, esi */
|
||||
|
||||
incl %ebp
|
||||
/* mov imm32, %ecx */
|
||||
.byte 0xb9
|
||||
VARIABLE(grub_relocator_xen_paging_size)
|
||||
.long 0
|
||||
cmpl %ebp, %ecx
|
||||
incl %ebp /* next pfn */
|
||||
movl %edi, %ecx
|
||||
|
||||
ja 1b
|
||||
loop 2b
|
||||
|
||||
mov %esp, %ebx /* restore area poniter */
|
||||
jmp 1b
|
||||
|
||||
3:
|
||||
/* Switch page tables: pin new L3 pt, load cr3, unpin old L3. */
|
||||
/* mov imm32, %ebx */
|
||||
.byte 0xbb
|
||||
VARIABLE(grub_relocator_xen_mmu_op_addr)
|
||||
.long 0
|
||||
movl $3, %ecx
|
||||
movl $0, %edx
|
||||
movl $0x7FF0, %esi
|
||||
movl $3, %ecx /* 3 mmu ops */
|
||||
movl $0, %edx /* pdone (not used) */
|
||||
movl $DOMID_SELF, %esi
|
||||
movl $__HYPERVISOR_mmuext_op, %eax
|
||||
int $0x82
|
||||
|
||||
/* Continue in virtual kernel mapping. */
|
||||
/* mov imm32, %eax */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remap_continue)
|
||||
@@ -102,6 +112,9 @@ VARIABLE(grub_relocator_xen_remap_continue)
|
||||
|
||||
jmp *%eax
|
||||
|
||||
VARIABLE(grub_relocator_xen_paging_areas)
|
||||
.long 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
VARIABLE(grub_relocator_xen_mmu_op)
|
||||
.space 256
|
||||
|
||||
@@ -109,21 +122,22 @@ VARIABLE(grub_relocator_xen_remap_end)
|
||||
|
||||
|
||||
VARIABLE(grub_relocator_xen_start)
|
||||
/* Unmap old remapper area. */
|
||||
/* mov imm32, %eax */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remapper_virt2)
|
||||
.long 0
|
||||
|
||||
movl %eax, %edi
|
||||
movl %eax, %ebx
|
||||
|
||||
xorl %ecx, %ecx
|
||||
xorl %ecx, %ecx /* Invalid pte */
|
||||
xorl %edx, %edx
|
||||
|
||||
movl $2, %esi
|
||||
movl $UVMF_INVLPG, %esi
|
||||
movl $__HYPERVISOR_update_va_mapping, %eax
|
||||
int $0x82
|
||||
|
||||
|
||||
/* Prepare registers for starting kernel. */
|
||||
/* mov imm32, %eax */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_stack)
|
||||
@@ -145,6 +159,7 @@ VARIABLE(grub_relocator_xen_start_info)
|
||||
VARIABLE(grub_relocator_xen_entry_point)
|
||||
.long 0
|
||||
|
||||
/* Now start the new kernel. */
|
||||
jmp *%eax
|
||||
|
||||
VARIABLE(grub_relocator_xen_end)
|
||||
|
||||
@@ -696,7 +696,7 @@ syslinux_parse_real (struct syslinux_menu *menu)
|
||||
char *buf = NULL;
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
|
||||
file = grub_file_open (menu->filename);
|
||||
file = grub_file_open (menu->filename, GRUB_FILE_TYPE_CONFIG);
|
||||
if (!file)
|
||||
return grub_errno;
|
||||
while ((grub_free (buf), buf = grub_file_getline (file)))
|
||||
|
||||
80
grub-core/lib/x86_64/efi/relocator.c
Normal file
80
grub-core/lib/x86_64/efi/relocator.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2016 Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
|
||||
#include <grub/i386/relocator.h>
|
||||
#include <grub/relocator_private.h>
|
||||
|
||||
extern grub_uint64_t grub_relocator64_rax;
|
||||
extern grub_uint64_t grub_relocator64_rbx;
|
||||
extern grub_uint64_t grub_relocator64_rcx;
|
||||
extern grub_uint64_t grub_relocator64_rdx;
|
||||
extern grub_uint64_t grub_relocator64_rip;
|
||||
extern grub_uint64_t grub_relocator64_rsi;
|
||||
|
||||
extern grub_uint8_t grub_relocator64_efi_start;
|
||||
extern grub_uint8_t grub_relocator64_efi_end;
|
||||
|
||||
#define RELOCATOR_SIZEOF(x) (&grub_relocator##x##_end - &grub_relocator##x##_start)
|
||||
|
||||
grub_err_t
|
||||
grub_relocator64_efi_boot (struct grub_relocator *rel,
|
||||
struct grub_relocator64_efi_state state)
|
||||
{
|
||||
grub_err_t err;
|
||||
void *relst;
|
||||
grub_relocator_chunk_t ch;
|
||||
|
||||
/*
|
||||
* 64-bit relocator code may live above 4 GiB quite well.
|
||||
* However, I do not want ask for problems. Just in case.
|
||||
*/
|
||||
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||
0x100000000 - RELOCATOR_SIZEOF (64_efi),
|
||||
RELOCATOR_SIZEOF (64_efi), 16,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Do not touch %rsp! It points to EFI created stack. */
|
||||
grub_relocator64_rax = state.rax;
|
||||
grub_relocator64_rbx = state.rbx;
|
||||
grub_relocator64_rcx = state.rcx;
|
||||
grub_relocator64_rdx = state.rdx;
|
||||
grub_relocator64_rip = state.rip;
|
||||
grub_relocator64_rsi = state.rsi;
|
||||
|
||||
grub_memmove (get_virtual_current_address (ch), &grub_relocator64_efi_start,
|
||||
RELOCATOR_SIZEOF (64_efi));
|
||||
|
||||
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
|
||||
&relst, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
((void (*) (void)) relst) ();
|
||||
|
||||
/* Not reached. */
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -16,95 +16,85 @@
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/x86_64/memory.h>
|
||||
#include <grub/x86_64/types.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/xen.h>
|
||||
|
||||
/* Macro to load an imm64 value stored by the C-part into %rax: */
|
||||
#define MOV_IMM64_RAX(var) .byte 0x48, 0xb8; VARIABLE(var); .quad 0
|
||||
|
||||
.p2align 4 /* force 16-byte alignment */
|
||||
|
||||
VARIABLE(grub_relocator_xen_remap_start)
|
||||
LOCAL(base):
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remapper_virt)
|
||||
.quad 0
|
||||
/* Remap the remapper to it's new address. */
|
||||
MOV_IMM64_RAX(grub_relocator_xen_remapper_virt)
|
||||
|
||||
movq %rax, %rdi
|
||||
movq %rax, %rbx
|
||||
movq %rax, %rdi /* %rdi: new virtual address of remapper */
|
||||
movq %rax, %rbx /* Remember new virtual address */
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remapper_map)
|
||||
.quad 0
|
||||
MOV_IMM64_RAX(grub_relocator_xen_remapper_map)
|
||||
|
||||
movq %rax, %rsi
|
||||
movq %rax, %rsi /* %rsi: page table entry */
|
||||
|
||||
movq $2, %rdx
|
||||
movq $UVMF_INVLPG, %rdx /* %rdx: flags (inv. single entry) */
|
||||
movq $__HYPERVISOR_update_va_mapping, %rax
|
||||
syscall
|
||||
syscall /* Do the remap operation */
|
||||
|
||||
addq $(LOCAL(cont) - LOCAL(base)), %rbx
|
||||
|
||||
jmp *%rbx
|
||||
jmp *%rbx /* Continue with new virtual address */
|
||||
|
||||
LOCAL(cont):
|
||||
|
||||
/* mov imm64, %rcx */
|
||||
.byte 0x48
|
||||
.byte 0xb9
|
||||
VARIABLE(grub_relocator_xen_paging_size)
|
||||
.quad 0
|
||||
/* Modify mappings of new page tables to be read-only. */
|
||||
MOV_IMM64_RAX(grub_relocator_xen_mfn_list)
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_paging_start)
|
||||
.quad 0
|
||||
movq %rax, %rbx /* %rbx is the base of the p2m list */
|
||||
leaq EXT_C(grub_relocator_xen_paging_areas) (%rip), %r8
|
||||
|
||||
movq %rax, %r12
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_mfn_list)
|
||||
.quad 0
|
||||
|
||||
movq %rax, %rsi
|
||||
1:
|
||||
movq 0(%r8), %r12 /* Get start pfn of the current area */
|
||||
movq GRUB_TARGET_SIZEOF_LONG(%r8), %rcx /* Get # of pg tables */
|
||||
testq %rcx, %rcx /* 0 -> last area reached */
|
||||
jz 3f
|
||||
2:
|
||||
movq %r12, %rdi
|
||||
movq %rsi, %rbx
|
||||
movq 0(%rsi), %rsi
|
||||
shlq $12, %rsi
|
||||
orq $5, %rsi
|
||||
movq $2, %rdx
|
||||
movq %rcx, %r9
|
||||
shlq $PAGE_SHIFT, %rdi /* virtual address (1:1 mapping) */
|
||||
movq (%rbx, %r12, 8), %rsi /* mfn */
|
||||
shlq $PAGE_SHIFT, %rsi
|
||||
orq $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %rsi /* Build pte */
|
||||
movq $UVMF_INVLPG, %rdx
|
||||
movq %rcx, %r9 /* %rcx clobbered by hypercall */
|
||||
movq $__HYPERVISOR_update_va_mapping, %rax
|
||||
syscall
|
||||
|
||||
movq %r9, %rcx
|
||||
addq $8, %rbx
|
||||
addq $4096, %r12
|
||||
movq %rbx, %rsi
|
||||
incq %r12 /* next pfn */
|
||||
|
||||
loop 1b
|
||||
loop 2b
|
||||
|
||||
leaq LOCAL(mmu_op) (%rip), %rdi
|
||||
movq $3, %rsi
|
||||
movq $0, %rdx
|
||||
movq $0x7FF0, %r10
|
||||
addq $(2 * GRUB_TARGET_SIZEOF_LONG), %r8 /* next pg table area */
|
||||
jmp 1b
|
||||
|
||||
3:
|
||||
/* Switch page tables: pin new L4 pt, load cr3, unpin old L4. */
|
||||
leaq EXT_C(grub_relocator_xen_mmu_op) (%rip), %rdi
|
||||
movq $3, %rsi /* 3 mmu ops */
|
||||
movq $0, %rdx /* pdone (not used) */
|
||||
movq $DOMID_SELF, %r10
|
||||
movq $__HYPERVISOR_mmuext_op, %rax
|
||||
syscall
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remap_continue)
|
||||
.quad 0
|
||||
/* Continue in virtual kernel mapping. */
|
||||
MOV_IMM64_RAX(grub_relocator_xen_remap_continue)
|
||||
|
||||
jmp *%rax
|
||||
|
||||
LOCAL(mmu_op):
|
||||
VARIABLE(grub_relocator_xen_paging_areas)
|
||||
/* array of start, size pairs, size 0 is end marker */
|
||||
.quad 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
VARIABLE(grub_relocator_xen_mmu_op)
|
||||
.space 256
|
||||
|
||||
@@ -112,46 +102,32 @@ VARIABLE(grub_relocator_xen_remap_end)
|
||||
|
||||
|
||||
VARIABLE(grub_relocator_xen_start)
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_remapper_virt2)
|
||||
.quad 0
|
||||
/* Unmap old remapper area. */
|
||||
MOV_IMM64_RAX(grub_relocator_xen_remapper_virt2)
|
||||
|
||||
movq %rax, %rdi
|
||||
|
||||
xorq %rax, %rax
|
||||
xorq %rax, %rax /* Invalid pte */
|
||||
movq %rax, %rsi
|
||||
|
||||
movq $2, %rdx
|
||||
movq $UVMF_INVLPG, %rdx
|
||||
movq $__HYPERVISOR_update_va_mapping, %rax
|
||||
syscall
|
||||
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_stack)
|
||||
.quad 0
|
||||
/* Prepare registers for starting kernel. */
|
||||
MOV_IMM64_RAX(grub_relocator_xen_stack)
|
||||
|
||||
movq %rax, %rsp
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_start_info)
|
||||
.quad 0
|
||||
MOV_IMM64_RAX(grub_relocator_xen_start_info)
|
||||
|
||||
movq %rax, %rsi
|
||||
|
||||
cld
|
||||
|
||||
/* mov imm64, %rax */
|
||||
.byte 0x48
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator_xen_entry_point)
|
||||
.quad 0
|
||||
MOV_IMM64_RAX(grub_relocator_xen_entry_point)
|
||||
|
||||
/* Now start the new kernel. */
|
||||
jmp *%rax
|
||||
|
||||
VARIABLE(grub_relocator_xen_end)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user