mirror of
http://cgit.git.savannah.gnu.org/git/grub.git
synced 2026-04-28 14:33:34 +00:00
Compare commits
223 Commits
phcoder/c3
...
2.02
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
e3745f9087 | ||
|
|
01d50c2539 | ||
|
|
8d69065f52 | ||
|
|
59ec05bcf8 | ||
|
|
fabde8324d | ||
|
|
5cae910665 | ||
|
|
25492a0f04 | ||
|
|
080a20861c | ||
|
|
f96b34224e | ||
|
|
a2ab8c2172 | ||
|
|
ce01054ec3 | ||
|
|
feef882f98 | ||
|
|
eba6db6323 | ||
|
|
6e1ace590a | ||
|
|
7c35f65aac | ||
|
|
4598cafa7d | ||
|
|
6f4189ffc1 | ||
|
|
127cfea8be | ||
|
|
22aa31bcc3 | ||
|
|
e72de13b9e | ||
|
|
342d6edb97 | ||
|
|
e5c9300191 | ||
|
|
d9a3bfead8 | ||
|
|
1933d37371 | ||
|
|
b29638222e | ||
|
|
8ad190cac2 | ||
|
|
281baeecd3 | ||
|
|
df4df4d887 | ||
|
|
2d425ffdd5 | ||
|
|
67dba97e45 | ||
|
|
7290bb5623 | ||
|
|
ff84a9b868 | ||
|
|
605eecc985 | ||
|
|
b6a03dfd32 | ||
|
|
5f2b285bf8 | ||
|
|
ae3b83a4d4 | ||
|
|
dab148891e | ||
|
|
64e2d139fe | ||
|
|
0edd750e50 | ||
|
|
cc2ed41039 | ||
|
|
7c6c2ad42c | ||
|
|
47e67d809c | ||
|
|
92bbf25714 | ||
|
|
95440b41d3 | ||
|
|
f826d914e2 | ||
|
|
77002c65d3 | ||
|
|
d4561cd080 | ||
|
|
9b4256bf05 | ||
|
|
eefa3239c2 | ||
|
|
4f8fe948b9 | ||
|
|
b95e926788 | ||
|
|
26533fe6bc | ||
|
|
29862fdc3a | ||
|
|
9daf7aae8b | ||
|
|
a4b1326f0d | ||
|
|
dbb0f9fa4f | ||
|
|
e9d71db53a | ||
|
|
6c35ce72ba | ||
|
|
f3c84fa798 | ||
|
|
5db2190f2c | ||
|
|
1bff60e5aa | ||
|
|
8fe17d91af | ||
|
|
66768b99f1 | ||
|
|
962b69d950 | ||
|
|
528256932b | ||
|
|
269a522c7d | ||
|
|
5a5a3c6963 | ||
|
|
670c43af27 | ||
|
|
dc27d254f2 | ||
|
|
31f6506c57 | ||
|
|
9fecb0588e | ||
|
|
aafd205c92 | ||
|
|
bd60f5a207 | ||
|
|
725548a285 | ||
|
|
d5cc487d39 | ||
|
|
fa2af21ec8 | ||
|
|
0e075ac385 | ||
|
|
57e7f1b775 | ||
|
|
67d9ce82ac | ||
|
|
12bf87466f | ||
|
|
97c41e1216 | ||
|
|
8ab2675ede | ||
|
|
efc04d65c7 |
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.
|
||||
|
||||
70
Makefile.am
70
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.
|
||||
@@ -409,8 +422,9 @@ BOOTCHECK_TIMEOUT=180
|
||||
bootcheck: $(BOOTCHECKS)
|
||||
|
||||
if COND_i386_coreboot
|
||||
default_payload.elf: grub-mkstandalone grub-mkimage
|
||||
pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos xfs 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' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
|
||||
default_payload.elf: grub-mkstandalone grub-mkimage FORCE
|
||||
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
|
||||
|
||||
endif
|
||||
|
||||
@@ -172,6 +172,8 @@ program = {
|
||||
|
||||
common = util/grub-mkimage.c;
|
||||
common = util/mkimage.c;
|
||||
common = util/grub-mkimage32.c;
|
||||
common = util/grub-mkimage64.c;
|
||||
common = util/resolve.c;
|
||||
common = grub-core/kern/emu/argp_common.c;
|
||||
common = grub-core/osdep/init.c;
|
||||
@@ -414,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 = {
|
||||
@@ -510,6 +512,8 @@ program = {
|
||||
common = util/render-label.c;
|
||||
common = util/glue-efi.c;
|
||||
common = util/mkimage.c;
|
||||
common = util/grub-mkimage32.c;
|
||||
common = util/grub-mkimage64.c;
|
||||
common = util/grub-install-common.c;
|
||||
common = util/setup_bios.c;
|
||||
common = util/setup_sparc.c;
|
||||
@@ -552,6 +556,8 @@ program = {
|
||||
common = util/render-label.c;
|
||||
common = util/glue-efi.c;
|
||||
common = util/mkimage.c;
|
||||
common = util/grub-mkimage32.c;
|
||||
common = util/grub-mkimage64.c;
|
||||
common = util/grub-install-common.c;
|
||||
common = util/setup_bios.c;
|
||||
common = util/setup_sparc.c;
|
||||
@@ -595,6 +601,8 @@ program = {
|
||||
common = util/grub-install.c;
|
||||
common = util/probe.c;
|
||||
common = util/mkimage.c;
|
||||
common = util/grub-mkimage32.c;
|
||||
common = util/grub-mkimage64.c;
|
||||
common = util/grub-install-common.c;
|
||||
common = util/setup_bios.c;
|
||||
common = util/setup_sparc.c;
|
||||
@@ -632,6 +640,8 @@ program = {
|
||||
common = util/grub-mknetdir.c;
|
||||
|
||||
common = util/mkimage.c;
|
||||
common = util/grub-mkimage32.c;
|
||||
common = util/grub-mkimage64.c;
|
||||
common = util/grub-install-common.c;
|
||||
common = util/setup_bios.c;
|
||||
common = util/setup_sparc.c;
|
||||
|
||||
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.
|
||||
|
||||
|
||||
4
TODO
4
TODO
@@ -7,7 +7,3 @@ glance. So write to <grub-devel@gnu.org> first.
|
||||
For bug tracking, refer to:
|
||||
|
||||
http://savannah.gnu.org/bugs/?group=grub
|
||||
|
||||
Our wiki also lists some areas that need work:
|
||||
|
||||
http://grub.enbug.org/
|
||||
|
||||
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
|
||||
|
||||
69
configure.ac
69
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.02],[bug-grub@gnu.org])
|
||||
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
@@ -388,7 +388,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>
|
||||
@@ -1144,14 +1152,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"
|
||||
@@ -1184,13 +1201,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
|
||||
@@ -1199,9 +1229,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"
|
||||
@@ -1554,11 +1587,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
|
||||
|
||||
@@ -1628,11 +1661,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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -2538,6 +2542,8 @@ team are:
|
||||
85:3
|
||||
@item Asus EeePC 1005PE
|
||||
84:1 (unconfirmed)
|
||||
@item LENOVO ThinkPad T410s (2912W1C)
|
||||
101:3
|
||||
@end table
|
||||
|
||||
To take full advantage of this function, install GRUB into the MBR
|
||||
@@ -3060,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::
|
||||
@@ -3211,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:
|
||||
|
||||
@@ -3229,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}.
|
||||
@@ -3420,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
|
||||
|
||||
@@ -4073,12 +4089,15 @@ after @command{configfile} returns.
|
||||
@node cpuid
|
||||
@subsection cpuid
|
||||
|
||||
@deffn Command cpuid [-l]
|
||||
@deffn Command cpuid [-l] [-p]
|
||||
Check for CPU features. This command is only available on x86 systems.
|
||||
|
||||
With the @option{-l} option, return true if the CPU supports long mode
|
||||
(64-bit).
|
||||
|
||||
With the @option{-p} option, return true if the CPU supports Physical
|
||||
Address Extension (PAE).
|
||||
|
||||
If invoked without options, this command currently behaves as if it had been
|
||||
invoked with @option{-l}. This may change in the future.
|
||||
@end deffn
|
||||
@@ -5042,6 +5061,8 @@ the length of @var{string} is zero
|
||||
@var{expression} is false
|
||||
@item @var{expression1} @code{-a} @var{expression2}
|
||||
both @var{expression1} and @var{expression2} are true
|
||||
@item @var{expression1} @var{expression2}
|
||||
both @var{expression1} and @var{expression2} are true. This syntax is not POSIX-compliant and is not recommended.
|
||||
@item @var{expression1} @code{-o} @var{expression2}
|
||||
either @var{expression1} or @var{expression2} is true
|
||||
@end table
|
||||
|
||||
@@ -107,6 +107,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
|
||||
endif
|
||||
|
||||
if COND_i386_coreboot
|
||||
@@ -162,6 +163,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
|
||||
endif
|
||||
|
||||
if COND_ia64_efi
|
||||
|
||||
@@ -90,7 +90,7 @@ kernel = {
|
||||
i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
|
||||
emu_cflags = '$(CFLAGS_GNULIB)';
|
||||
emu_cppflags = '$(CPPFLAGS_GNULIB)';
|
||||
arm_uboot_ldflags = '-Wl,-Ttext=0x08000000';
|
||||
arm_uboot_ldflags = '-Wl,-r,-d';
|
||||
arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
|
||||
|
||||
i386_pc_startup = kern/i386/pc/startup.S;
|
||||
@@ -212,8 +212,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/arm/efi/init.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;
|
||||
@@ -1531,6 +1533,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;
|
||||
@@ -1685,7 +1688,32 @@ module = {
|
||||
x86 = loader/i386/xnu.c;
|
||||
x86 = loader/xnu.c;
|
||||
|
||||
enable = x86;
|
||||
/* Code is pretty generic but relies on RNG which
|
||||
is available only on few platforms. It's not a
|
||||
big deal as xnu needs ACPI anyway and we have
|
||||
RNG on all platforms with ACPI.
|
||||
*/
|
||||
enable = i386_multiboot;
|
||||
enable = i386_coreboot;
|
||||
enable = i386_pc;
|
||||
enable = i386_efi;
|
||||
enable = x86_64_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = random;
|
||||
x86 = lib/i386/random.c;
|
||||
common = lib/random.c;
|
||||
|
||||
i386_multiboot = kern/i386/tsc_pmtimer.c;
|
||||
i386_coreboot = kern/i386/tsc_pmtimer.c;
|
||||
i386_pc = kern/i386/tsc_pmtimer.c;
|
||||
|
||||
enable = i386_multiboot;
|
||||
enable = i386_coreboot;
|
||||
enable = i386_pc;
|
||||
enable = i386_efi;
|
||||
enable = x86_64_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <grub/loader.h>
|
||||
#include <grub/cs5536.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/cache.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -337,6 +338,21 @@ struct grub_ehci
|
||||
|
||||
static struct grub_ehci *ehci;
|
||||
|
||||
static void
|
||||
sync_all_caches (struct grub_ehci *e)
|
||||
{
|
||||
if (!e)
|
||||
return;
|
||||
if (e->td_virt)
|
||||
grub_arch_sync_dma_caches (e->td_virt, sizeof (struct grub_ehci_td) *
|
||||
GRUB_EHCI_N_TD);
|
||||
if (e->qh_virt)
|
||||
grub_arch_sync_dma_caches (e->qh_virt, sizeof (struct grub_ehci_qh) *
|
||||
GRUB_EHCI_N_QH);
|
||||
if (e->framelist_virt)
|
||||
grub_arch_sync_dma_caches (e->framelist_virt, 4096);
|
||||
}
|
||||
|
||||
/* EHCC registers access functions */
|
||||
static inline grub_uint32_t
|
||||
grub_ehci_ehcc_read32 (struct grub_ehci *e, grub_uint32_t addr)
|
||||
@@ -437,6 +453,8 @@ grub_ehci_reset (struct grub_ehci *e)
|
||||
{
|
||||
grub_uint64_t maxtime;
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
|
||||
GRUB_EHCI_CMD_HC_RESET
|
||||
| grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
|
||||
@@ -840,6 +858,8 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
|
||||
e->next = ehci;
|
||||
ehci = e;
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: OK at all\n");
|
||||
|
||||
grub_dprintf ("ehci",
|
||||
@@ -1020,6 +1040,7 @@ grub_ehci_find_qh (struct grub_ehci *e, grub_usb_transfer_t transfer)
|
||||
/* Found proper existing (and linked) QH, do setup of QH */
|
||||
grub_dprintf ("ehci", "find_qh: found, QH=%p\n", qh_iter);
|
||||
grub_ehci_setup_qh (qh_iter, transfer);
|
||||
sync_all_caches (e);
|
||||
return qh_iter;
|
||||
}
|
||||
|
||||
@@ -1121,7 +1142,7 @@ grub_ehci_free_tds (struct grub_ehci *e, grub_ehci_td_t td,
|
||||
token = grub_le_to_cpu32 (td->token);
|
||||
to_transfer = (token & GRUB_EHCI_TOTAL_MASK) >> GRUB_EHCI_TOTAL_OFF;
|
||||
|
||||
/* Check state of TD - if it did not transfered
|
||||
/* Check state of TD - if it did not transfer
|
||||
* whole data then set last_trans - it should be last executed TD
|
||||
* in case when something went wrong. */
|
||||
if (transfer && (td->size != to_transfer))
|
||||
@@ -1289,16 +1310,28 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
|
||||
grub_ehci_td_t td_prev = NULL;
|
||||
int i;
|
||||
struct grub_ehci_transfer_controller_data *cdata;
|
||||
grub_uint32_t status;
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
/* Check if EHCI is running and AL is enabled */
|
||||
if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)
|
||||
& GRUB_EHCI_ST_HC_HALTED) != 0)
|
||||
status = grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS);
|
||||
if ((status & GRUB_EHCI_ST_HC_HALTED) != 0)
|
||||
/* XXX: Fix it: Currently we don't do anything to restart EHCI */
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)
|
||||
{
|
||||
grub_dprintf ("ehci", "setup_transfer: halted, status = 0x%x\n",
|
||||
status);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
status = grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS);
|
||||
if ((status
|
||||
& (GRUB_EHCI_ST_AS_STATUS | GRUB_EHCI_ST_PS_STATUS)) == 0)
|
||||
/* XXX: Fix it: Currently we don't do anything to restart EHCI */
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
{
|
||||
grub_dprintf ("ehci", "setup_transfer: no AS/PS, status = 0x%x\n",
|
||||
status);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
/* Allocate memory for controller transfer data. */
|
||||
cdata = grub_malloc (sizeof (*cdata));
|
||||
@@ -1310,6 +1343,7 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
|
||||
cdata->qh_virt = grub_ehci_find_qh (e, transfer);
|
||||
if (!cdata->qh_virt)
|
||||
{
|
||||
grub_dprintf ("ehci", "setup_transfer: no QH\n");
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
@@ -1319,6 +1353,7 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
|
||||
cdata->td_alt_virt = grub_ehci_alloc_td (e);
|
||||
if (!cdata->td_alt_virt)
|
||||
{
|
||||
grub_dprintf ("ehci", "setup_transfer: no TDs\n");
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
@@ -1345,6 +1380,7 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
|
||||
grub_ehci_free_tds (e, cdata->td_first_virt, NULL, &actual);
|
||||
|
||||
grub_free (cdata);
|
||||
grub_dprintf ("ehci", "setup_transfer: no TD\n");
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
@@ -1386,6 +1422,8 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
|
||||
* i.e. reset token */
|
||||
cdata->qh_virt->td_overlay.token = grub_cpu_to_le32_compile_time (0);
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
/* Finito */
|
||||
transfer->controller_data = cdata;
|
||||
|
||||
@@ -1434,6 +1472,8 @@ grub_ehci_parse_notrun (grub_usb_controller_t dev,
|
||||
grub_ehci_free_td (e, cdata->td_alt_virt);
|
||||
grub_free (cdata);
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
/* Additionally, do something with EHCI to make it running (what?) */
|
||||
/* Try enable EHCI and AL */
|
||||
grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
|
||||
@@ -1469,6 +1509,8 @@ grub_ehci_parse_halt (grub_usb_controller_t dev,
|
||||
grub_ehci_free_td (e, cdata->td_alt_virt);
|
||||
grub_free (cdata);
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
/* Evaluation of error code - currently we don't have GRUB USB error
|
||||
* codes for some EHCI states, GRUB_USB_ERR_DATA is used for them.
|
||||
* Order of evaluation is critical, specially bubble/stall. */
|
||||
@@ -1502,6 +1544,8 @@ grub_ehci_parse_success (grub_usb_controller_t dev,
|
||||
grub_ehci_free_td (e, cdata->td_alt_virt);
|
||||
grub_free (cdata);
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
@@ -1515,6 +1559,8 @@ grub_ehci_check_transfer (grub_usb_controller_t dev,
|
||||
transfer->controller_data;
|
||||
grub_uint32_t token, token_ftd;
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
grub_dprintf ("ehci",
|
||||
"check_transfer: EHCI STATUS=%08x, cdata=%p, qh=%p\n",
|
||||
grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS),
|
||||
@@ -1581,6 +1627,9 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev,
|
||||
int i;
|
||||
grub_uint64_t maxtime;
|
||||
grub_uint32_t qh_phys;
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
grub_uint32_t interrupt =
|
||||
cdata->qh_virt->ep_cap & GRUB_EHCI_SMASK_MASK;
|
||||
|
||||
@@ -1600,6 +1649,7 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev,
|
||||
grub_ehci_free_tds (e, cdata->td_first_virt, transfer, &actual);
|
||||
grub_ehci_free_td (e, cdata->td_alt_virt);
|
||||
grub_free (cdata);
|
||||
sync_all_caches (e);
|
||||
grub_dprintf ("ehci", "cancel_transfer: end - EHCI not running\n");
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
@@ -1622,6 +1672,8 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev,
|
||||
/* Unlink QH from AL */
|
||||
e->qh_virt[i].qh_hptr = cdata->qh_virt->qh_hptr;
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
/* If this is an interrupt transfer, we just wait for the periodic
|
||||
* schedule to advance a few times and then assume that the EHCI
|
||||
* controller has read the updated QH. */
|
||||
@@ -1676,6 +1728,8 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev,
|
||||
|
||||
grub_dprintf ("ehci", "cancel_transfer: end\n");
|
||||
|
||||
sync_all_caches (e);
|
||||
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
@@ -1777,11 +1831,6 @@ grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
|
||||
|
||||
status = grub_ehci_port_read (e, port);
|
||||
|
||||
grub_dprintf ("ehci", "detect_dev: EHCI STATUS: %08x\n",
|
||||
grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS));
|
||||
grub_dprintf ("ehci", "detect_dev: iobase=%p, port=%d, status=0x%02x\n",
|
||||
e->iobase, port, status);
|
||||
|
||||
/* Connect Status Change bit - it detects change of connection */
|
||||
if (status & GRUB_EHCI_PORT_CONNECT_CH)
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <grub/usb.h>
|
||||
#include <grub/usbtrans.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/cache.h>
|
||||
|
||||
|
||||
static inline unsigned int
|
||||
@@ -101,6 +102,8 @@ grub_usb_control_msg (grub_usb_device_t dev,
|
||||
data_addr = grub_dma_get_phys (data_chunk);
|
||||
grub_memcpy ((char *) data, data_in, size);
|
||||
|
||||
grub_arch_sync_dma_caches (data, size);
|
||||
|
||||
grub_dprintf ("usb",
|
||||
"control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%lu\n",
|
||||
reqtype, request, value, index, (unsigned long)size);
|
||||
@@ -161,6 +164,8 @@ grub_usb_control_msg (grub_usb_device_t dev,
|
||||
setupdata->value = value;
|
||||
setupdata->index = index;
|
||||
setupdata->length = size;
|
||||
grub_arch_sync_dma_caches (setupdata, sizeof (*setupdata));
|
||||
|
||||
transfer->transactions[0].size = sizeof (*setupdata);
|
||||
transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP;
|
||||
transfer->transactions[0].data = setupdata_addr;
|
||||
@@ -202,11 +207,13 @@ grub_usb_control_msg (grub_usb_device_t dev,
|
||||
grub_free (transfer->transactions);
|
||||
|
||||
grub_free (transfer);
|
||||
grub_dma_free (data_chunk);
|
||||
grub_dma_free (setupdata_chunk);
|
||||
|
||||
grub_arch_sync_dma_caches (data, size0);
|
||||
grub_memcpy (data_in, (char *) data, size0);
|
||||
|
||||
grub_dma_free (data_chunk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -236,7 +243,10 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev,
|
||||
data = grub_dma_get_virt (data_chunk);
|
||||
data_addr = grub_dma_get_phys (data_chunk);
|
||||
if (type == GRUB_USB_TRANSFER_TYPE_OUT)
|
||||
grub_memcpy ((char *) data, data_in, size);
|
||||
{
|
||||
grub_memcpy ((char *) data, data_in, size);
|
||||
grub_arch_sync_dma_caches (data, size);
|
||||
}
|
||||
|
||||
/* Create a transfer. */
|
||||
transfer = grub_malloc (sizeof (struct grub_usb_transfer));
|
||||
@@ -306,9 +316,13 @@ grub_usb_bulk_finish_readwrite (grub_usb_transfer_t transfer)
|
||||
dev->toggle[transfer->endpoint] = toggle;
|
||||
|
||||
if (transfer->dir == GRUB_USB_TRANSFER_TYPE_IN)
|
||||
grub_memcpy (transfer->data, (void *)
|
||||
grub_dma_get_virt (transfer->data_chunk),
|
||||
transfer->size + 1);
|
||||
{
|
||||
grub_arch_sync_dma_caches (grub_dma_get_virt (transfer->data_chunk),
|
||||
transfer->size + 1);
|
||||
grub_memcpy (transfer->data, (void *)
|
||||
grub_dma_get_virt (transfer->data_chunk),
|
||||
transfer->size + 1);
|
||||
}
|
||||
|
||||
grub_free (transfer->transactions);
|
||||
grub_dma_free (transfer->data_chunk);
|
||||
|
||||
@@ -593,6 +593,9 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||
if (! table->addr)
|
||||
{
|
||||
free_tables ();
|
||||
grub_free (exclude);
|
||||
grub_free (load_only);
|
||||
grub_free (table);
|
||||
return grub_errno;
|
||||
}
|
||||
table->next = acpi_tables;
|
||||
@@ -758,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
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -45,7 +45,7 @@ static grub_err_t
|
||||
grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int byte, bit;
|
||||
int byte = 0, bit = 0;
|
||||
grub_err_t err;
|
||||
grub_uint8_t value;
|
||||
|
||||
@@ -67,7 +67,7 @@ static grub_err_t
|
||||
grub_cmd_cmosclean (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int byte, bit;
|
||||
int byte = 0, bit = 0;
|
||||
grub_err_t err;
|
||||
grub_uint8_t value;
|
||||
|
||||
@@ -85,7 +85,7 @@ static grub_err_t
|
||||
grub_cmd_cmosset (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int byte, bit;
|
||||
int byte = 0, bit = 0;
|
||||
grub_err_t err;
|
||||
grub_uint8_t value;
|
||||
|
||||
|
||||
@@ -253,6 +253,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
struct grub_command *cmd;
|
||||
char **cutargs;
|
||||
int cutargc;
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
@@ -314,6 +315,8 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1));
|
||||
if (!cutargs)
|
||||
return grub_errno;
|
||||
cutargc = argc - 1;
|
||||
grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2));
|
||||
cutargs[0] = args[0];
|
||||
@@ -333,7 +336,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
if (!(cmd->func) (cmd, cutargc, cutargs))
|
||||
{
|
||||
kernel_type = LINUX;
|
||||
return GRUB_ERR_NONE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
@@ -348,7 +351,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
if (!(cmd->func) (cmd, argc, args))
|
||||
{
|
||||
kernel_type = MULTIBOOT;
|
||||
return GRUB_ERR_NONE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
@@ -413,7 +416,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
if (!(cmd->func) (cmd, cutargc, cutargs))
|
||||
{
|
||||
kernel_type = KFREEBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
@@ -422,6 +425,8 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
char **bsdargs;
|
||||
int bsdargc;
|
||||
char bsddevname[sizeof ("wdXXXXXXXXXXXXY")];
|
||||
int found = 0;
|
||||
|
||||
if (bsd_device == -1)
|
||||
{
|
||||
bsdargs = cutargs;
|
||||
@@ -432,6 +437,11 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
char rbuf[3] = "-r";
|
||||
bsdargc = cutargc + 2;
|
||||
bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc);
|
||||
if (!bsdargs)
|
||||
{
|
||||
err = grub_errno;
|
||||
goto out;
|
||||
}
|
||||
grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0]));
|
||||
bsdargs[argc] = rbuf;
|
||||
bsdargs[argc + 1] = bsddevname;
|
||||
@@ -447,7 +457,8 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
if (!(cmd->func) (cmd, bsdargc, bsdargs))
|
||||
{
|
||||
kernel_type = KNETBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
found = 1;
|
||||
goto free_bsdargs;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
@@ -460,20 +471,28 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
if (!(cmd->func) (cmd, bsdargc, bsdargs))
|
||||
{
|
||||
kernel_type = KOPENBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
found = 1;
|
||||
goto free_bsdargs;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
free_bsdargs:
|
||||
if (bsdargs != cutargs)
|
||||
grub_free (bsdargs);
|
||||
if (found)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (0);
|
||||
|
||||
return grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s",
|
||||
args[0]);
|
||||
err = grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s",
|
||||
args[0]);
|
||||
out:
|
||||
grub_free (cutargs);
|
||||
return err;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -498,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)
|
||||
{
|
||||
@@ -534,15 +553,17 @@ grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused
|
||||
char **newargs;
|
||||
grub_err_t err;
|
||||
char nounzipbuf[10] = "--nounzip";
|
||||
|
||||
cmd = grub_command_find ("module");
|
||||
if (!cmd)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
|
||||
"module");
|
||||
|
||||
newargs = grub_malloc ((argc + 1) * sizeof (newargs[0]));
|
||||
if (!newargs)
|
||||
return grub_errno;
|
||||
grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0]));
|
||||
newargs[0] = nounzipbuf;
|
||||
cmd = grub_command_find ("module");
|
||||
if (!cmd)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
|
||||
"module");
|
||||
|
||||
err = cmd->func (cmd, argc + 1, newargs);
|
||||
grub_free (newargs);
|
||||
|
||||
@@ -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. */
|
||||
@@ -198,7 +199,10 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
|
||||
return grub_errno;
|
||||
|
||||
if (get_uuid (NULL, &uuid_root, 0))
|
||||
return grub_errno;
|
||||
{
|
||||
grub_free (mods);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
prefdev = grub_file_get_device_name (prefix);
|
||||
if (grub_errno)
|
||||
@@ -210,6 +214,8 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
|
||||
if (get_uuid (prefdev, &uuid_prefix, 0))
|
||||
{
|
||||
grub_free (uuid_root);
|
||||
grub_free (prefdev);
|
||||
grub_free (mods);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
@@ -289,12 +295,15 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
grub_free (uuid_root);
|
||||
grub_free (uuid_prefix);
|
||||
grub_free (prefdev);
|
||||
grub_free (mods);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
grub_free (uuid_root);
|
||||
grub_free (uuid_prefix);
|
||||
grub_free (prefdev);
|
||||
|
||||
for (i = 0; i < mods_loaded; i++)
|
||||
if (mods[i])
|
||||
@@ -302,6 +311,8 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
|
||||
mods[i]->fini = 0;
|
||||
grub_dl_unload (mods[i]);
|
||||
}
|
||||
grub_free (mods);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
|
||||
@@ -283,6 +283,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
if (! cur)
|
||||
{
|
||||
grub_free (parsed);
|
||||
grub_device_close (dev);
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown argument `%s'"),
|
||||
args[i]);
|
||||
|
||||
@@ -45,6 +45,7 @@ check_password (const char *user, const char *entered, void *pin)
|
||||
grub_uint8_t *buf;
|
||||
struct pbkdf2_password *pass = pin;
|
||||
gcry_err_code_t err;
|
||||
grub_err_t ret;
|
||||
|
||||
buf = grub_malloc (pass->buflen);
|
||||
if (!buf)
|
||||
@@ -55,17 +56,17 @@ check_password (const char *user, const char *entered, void *pin)
|
||||
pass->salt, pass->saltlen, pass->c,
|
||||
buf, pass->buflen);
|
||||
if (err)
|
||||
ret = grub_crypto_gcry_error (err);
|
||||
else if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0)
|
||||
ret = GRUB_ACCESS_DENIED;
|
||||
else
|
||||
{
|
||||
grub_free (buf);
|
||||
return grub_crypto_gcry_error (err);
|
||||
grub_auth_authenticate (user);
|
||||
ret = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0)
|
||||
return GRUB_ACCESS_DENIED;
|
||||
|
||||
grub_auth_authenticate (user);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
grub_free (buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -324,19 +324,19 @@ grub_load_public_key (grub_file_t f)
|
||||
if (grub_file_read (f, &l, sizeof (l)) != sizeof (l))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
|
||||
lb = (grub_be_to_cpu16 (l) + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT;
|
||||
if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
if (grub_file_read (f, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
grub_memcpy (buffer, &l, sizeof (l));
|
||||
|
||||
@@ -346,10 +346,16 @@ grub_load_public_key (grub_file_t f)
|
||||
buffer, lb + sizeof (grub_uint16_t), 0))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < pkalgos[pk].nmpipub)
|
||||
{
|
||||
grub_free (sk);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
GRUB_MD_SHA1->final (fingerprint_context);
|
||||
|
||||
grub_memcpy (sk->fingerprint, GRUB_MD_SHA1->read (fingerprint_context), 20);
|
||||
|
||||
@@ -32,7 +32,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
struct grub_ahci_cmd_head
|
||||
{
|
||||
grub_uint32_t config;
|
||||
grub_uint32_t transfered;
|
||||
grub_uint32_t transferred;
|
||||
grub_uint64_t command_table_base;
|
||||
grub_uint32_t unused[4];
|
||||
};
|
||||
@@ -954,7 +954,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
|
||||
grub_dprintf ("ahci", "AHCI tfd = %x\n",
|
||||
dev->hba->ports[dev->port].task_file_data);
|
||||
|
||||
dev->command_list[0].transfered = 0;
|
||||
dev->command_list[0].transferred = 0;
|
||||
dev->command_list[0].command_table_base
|
||||
= grub_dma_get_phys (dev->command_table_chunk);
|
||||
|
||||
@@ -1044,7 +1044,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
|
||||
dev->hba->ports[dev->port].command_issue,
|
||||
dev->hba->ports[dev->port].intstatus,
|
||||
dev->hba->ports[dev->port].task_file_data,
|
||||
dev->command_list[0].transfered,
|
||||
dev->command_list[0].transferred,
|
||||
dev->hba->ports[dev->port].sata_error,
|
||||
((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x00],
|
||||
((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x18]);
|
||||
|
||||
@@ -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,11 +80,26 @@ 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)
|
||||
{
|
||||
/* Uggh. */
|
||||
grub_free (handles);
|
||||
while (devices)
|
||||
{
|
||||
d = devices->next;
|
||||
grub_free (devices);
|
||||
devices = d;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -209,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;
|
||||
@@ -487,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);
|
||||
@@ -518,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
|
||||
@@ -541,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,
|
||||
@@ -562,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);
|
||||
|
||||
@@ -154,7 +154,10 @@ grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const Elf_Ehdr *e)
|
||||
s->sh_flags & SHF_EXECINSTR ? GRUB_EFI_RUNTIME_SERVICES_CODE
|
||||
: GRUB_EFI_RUNTIME_SERVICES_DATA);
|
||||
if (seg->handle < 0)
|
||||
return grub_errno;
|
||||
{
|
||||
grub_free (seg);
|
||||
return grub_errno;
|
||||
}
|
||||
seg->off = 0;
|
||||
}
|
||||
|
||||
@@ -343,7 +346,7 @@ SUFFIX (grub_efiemu_loadcore_init) (void *core, const char *filename,
|
||||
return grub_error (GRUB_ERR_BAD_MODULE, N_("this ELF file is not of the right type"));
|
||||
|
||||
/* Make sure that every section is within the core. */
|
||||
if ((grub_size_t) core_size < e->e_shoff + e->e_shentsize * e->e_shnum)
|
||||
if ((grub_size_t) core_size < e->e_shoff + (grub_uint32_t) e->e_shentsize * e->e_shnum)
|
||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||
filename);
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ grub_efiemu_load_file (const char *filename)
|
||||
{
|
||||
grub_file_close (file);
|
||||
grub_efiemu_unload ();
|
||||
return grub_errno;
|
||||
return err;
|
||||
}
|
||||
|
||||
grub_dprintf ("efiemu", "mm initialized\n");
|
||||
|
||||
@@ -99,7 +99,8 @@ grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
|
||||
grub_size_t align_overhead;
|
||||
struct grub_efiemu_memrequest *ret, *cur, *prev;
|
||||
/* Check that the request is correct */
|
||||
if (type >= GRUB_EFI_MAX_MEMORY_TYPE || type <= GRUB_EFI_LOADER_CODE)
|
||||
if (type <= GRUB_EFI_LOADER_CODE || type == GRUB_EFI_PERSISTENT_MEMORY ||
|
||||
type >= GRUB_EFI_MAX_MEMORY_TYPE)
|
||||
return -2;
|
||||
|
||||
/* Add new size to requested size */
|
||||
@@ -166,6 +167,13 @@ efiemu_alloc_requests (void)
|
||||
GRUB_EFI_MEMORY_MAPPED_IO,
|
||||
GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
|
||||
GRUB_EFI_PAL_CODE
|
||||
|
||||
/*
|
||||
* These are not allocatable:
|
||||
* GRUB_EFI_RESERVED_MEMORY_TYPE
|
||||
* GRUB_EFI_PERSISTENT_MEMORY
|
||||
* >= GRUB_EFI_MAX_MEMORY_TYPE
|
||||
*/
|
||||
};
|
||||
|
||||
/* Compute total memory needed */
|
||||
@@ -402,9 +410,14 @@ fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
|
||||
return grub_efiemu_add_to_mmap (addr, size,
|
||||
GRUB_EFI_ACPI_MEMORY_NVS);
|
||||
|
||||
case GRUB_MEMORY_PERSISTENT:
|
||||
case GRUB_MEMORY_PERSISTENT_LEGACY:
|
||||
return grub_efiemu_add_to_mmap (addr, size,
|
||||
GRUB_EFI_PERSISTENT_MEMORY);
|
||||
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);
|
||||
@@ -445,7 +458,7 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
|
||||
case GRUB_EFI_MEMORY_MAPPED_IO:
|
||||
case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
|
||||
case GRUB_EFI_PAL_CODE:
|
||||
case GRUB_EFI_MAX_MEMORY_TYPE:
|
||||
default:
|
||||
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
|
||||
GRUB_MEMORY_RESERVED, hook_data);
|
||||
break;
|
||||
@@ -468,6 +481,12 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
|
||||
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
|
||||
GRUB_MEMORY_NVS, hook_data);
|
||||
break;
|
||||
|
||||
case GRUB_EFI_PERSISTENT_MEMORY:
|
||||
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
|
||||
GRUB_MEMORY_PERSISTENT, hook_data);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -503,7 +522,8 @@ grub_efiemu_mmap_sort_and_uniq (void)
|
||||
[GRUB_EFI_ACPI_MEMORY_NVS] = 3,
|
||||
[GRUB_EFI_MEMORY_MAPPED_IO] = 4,
|
||||
[GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE] = 4,
|
||||
[GRUB_EFI_PAL_CODE] = 4
|
||||
[GRUB_EFI_PAL_CODE] = 4,
|
||||
[GRUB_EFI_PERSISTENT_MEMORY] = 4
|
||||
};
|
||||
|
||||
int i, j, k, done;
|
||||
|
||||
@@ -83,10 +83,16 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks,
|
||||
((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);
|
||||
|
||||
/* Put pointer to the list of configuration tables in system table */
|
||||
grub_efiemu_write_value
|
||||
(&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
|
||||
conftable_handle, 0, 1,
|
||||
sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table));
|
||||
err = grub_efiemu_write_value
|
||||
(&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
|
||||
conftable_handle, 0, 1,
|
||||
sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table));
|
||||
if (err)
|
||||
{
|
||||
grub_efiemu_unload ();
|
||||
return err;
|
||||
}
|
||||
|
||||
SUFFIX(grub_efiemu_system_table)->num_table_entries = cntconftables;
|
||||
|
||||
/* Fill the list of configuration tables */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1308,6 +1308,7 @@ grub_hfs_open (struct grub_file *file, const char *name)
|
||||
if (grub_hfs_find_dir (data, name, &found, GRUB_FSHELP_REG))
|
||||
{
|
||||
grub_free (data);
|
||||
grub_free (found);
|
||||
grub_dl_unref (my_mod);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest)
|
||||
if (tag & 1)
|
||||
{
|
||||
grub_uint32_t i, len, delta, code, lmask, dshift;
|
||||
grub_uint16_t word;
|
||||
grub_uint16_t word = 0;
|
||||
|
||||
if (decomp_get16 (cc, &word))
|
||||
return grub_errno;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -775,7 +780,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
c = de->name[de->len];
|
||||
de->name[de->len] = '\0';
|
||||
if (iterate_dir_call_hook (ino, de->name, &ctx))
|
||||
return 1;
|
||||
{
|
||||
de->name[de->len] = c;
|
||||
return 1;
|
||||
}
|
||||
de->name[de->len] = c;
|
||||
|
||||
de = grub_xfs_inline_next_de(dir->data, head, de);
|
||||
|
||||
@@ -3132,7 +3132,7 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data)
|
||||
{
|
||||
void *osp;
|
||||
blkptr_t *bp;
|
||||
grub_size_t ospsize;
|
||||
grub_size_t ospsize = 0;
|
||||
grub_err_t err;
|
||||
|
||||
grub_dprintf ("zfs", "endian = %d\n", mdn->endian);
|
||||
|
||||
@@ -184,6 +184,8 @@ LZ4_uncompress_unknownOutputSize(const char *source,
|
||||
}
|
||||
}
|
||||
/* copy literals */
|
||||
if ((grub_addr_t) length > ~(grub_addr_t)op)
|
||||
goto _output_error;
|
||||
cpy = op + length;
|
||||
if ((cpy > oend - COPYLENGTH) ||
|
||||
(ip + length > iend - COPYLENGTH)) {
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -45,6 +45,7 @@ grub_font_draw_string (const char *str, grub_font_t font,
|
||||
grub_uint32_t *logical;
|
||||
grub_ssize_t logical_len, visual_len;
|
||||
struct grub_unicode_glyph *visual, *ptr;
|
||||
grub_err_t err;
|
||||
|
||||
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
|
||||
if (logical_len < 0)
|
||||
@@ -56,24 +57,28 @@ grub_font_draw_string (const char *str, grub_font_t font,
|
||||
if (visual_len < 0)
|
||||
return grub_errno;
|
||||
|
||||
err = GRUB_ERR_NONE;
|
||||
for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++)
|
||||
{
|
||||
grub_err_t err;
|
||||
struct grub_font_glyph *glyph;
|
||||
glyph = grub_font_construct_glyph (font, ptr);
|
||||
if (!glyph)
|
||||
return grub_errno;
|
||||
{
|
||||
err = grub_errno;
|
||||
goto out;
|
||||
}
|
||||
err = grub_font_draw_glyph (glyph, color, x, baseline_y);
|
||||
x += glyph->device_width;
|
||||
if (err)
|
||||
return err;
|
||||
goto out;
|
||||
x += glyph->device_width;
|
||||
}
|
||||
|
||||
out:
|
||||
for (ptr = visual; ptr < visual + visual_len; ptr++)
|
||||
grub_unicode_destroy_glyph (ptr);
|
||||
grub_free (visual);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Get the width in pixels of the specified UTF-8 string, when rendered in
|
||||
|
||||
@@ -63,14 +63,14 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
|
||||
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"),
|
||||
"theme");
|
||||
|
||||
instance = grub_zalloc (sizeof (*instance));
|
||||
if (!instance)
|
||||
return grub_errno;
|
||||
|
||||
err = grub_video_get_info (&mode_info);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
instance = grub_zalloc (sizeof (*instance));
|
||||
if (!instance)
|
||||
return grub_errno;
|
||||
|
||||
if (theme_path[0] != '/' && theme_path[0] != '(')
|
||||
{
|
||||
const char *prefix;
|
||||
|
||||
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:
|
||||
|
||||
@@ -32,3 +32,88 @@ grub_byte_checksum (void *base, grub_size_t size)
|
||||
ret += *ptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *
|
||||
grub_acpi_rsdt_find_table (struct grub_acpi_table_header *rsdt, const char *sig)
|
||||
{
|
||||
grub_size_t s;
|
||||
grub_unaligned_uint32_t *ptr;
|
||||
|
||||
if (!rsdt)
|
||||
return 0;
|
||||
|
||||
if (grub_memcmp (rsdt->signature, "RSDT", 4) != 0)
|
||||
return 0;
|
||||
|
||||
ptr = (grub_unaligned_uint32_t *) (rsdt + 1);
|
||||
s = (rsdt->length - sizeof (*rsdt)) / sizeof (grub_uint32_t);
|
||||
for (; s; s--, ptr++)
|
||||
{
|
||||
struct grub_acpi_table_header *tbl;
|
||||
tbl = (struct grub_acpi_table_header *) (grub_addr_t) ptr->val;
|
||||
if (grub_memcmp (tbl->signature, sig, 4) == 0)
|
||||
return tbl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *
|
||||
grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char *sig)
|
||||
{
|
||||
grub_size_t s;
|
||||
grub_unaligned_uint64_t *ptr;
|
||||
|
||||
if (!xsdt)
|
||||
return 0;
|
||||
|
||||
if (grub_memcmp (xsdt->signature, "XSDT", 4) != 0)
|
||||
return 0;
|
||||
|
||||
ptr = (grub_unaligned_uint64_t *) (xsdt + 1);
|
||||
s = (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint32_t);
|
||||
for (; s; s--, ptr++)
|
||||
{
|
||||
struct grub_acpi_table_header *tbl;
|
||||
#if GRUB_CPU_SIZEOF_VOID_P != 8
|
||||
if (ptr->val >> 32)
|
||||
continue;
|
||||
#endif
|
||||
tbl = (struct grub_acpi_table_header *) (grub_addr_t) ptr->val;
|
||||
if (grub_memcmp (tbl->signature, sig, 4) == 0)
|
||||
return tbl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct grub_acpi_fadt *
|
||||
grub_acpi_find_fadt (void)
|
||||
{
|
||||
struct grub_acpi_fadt *fadt = 0;
|
||||
struct grub_acpi_rsdp_v10 *rsdpv1;
|
||||
struct grub_acpi_rsdp_v20 *rsdpv2;
|
||||
rsdpv1 = grub_machine_acpi_get_rsdpv1 ();
|
||||
if (rsdpv1)
|
||||
fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *)
|
||||
(grub_addr_t) rsdpv1->rsdt_addr,
|
||||
GRUB_ACPI_FADT_SIGNATURE);
|
||||
if (fadt)
|
||||
return fadt;
|
||||
rsdpv2 = grub_machine_acpi_get_rsdpv2 ();
|
||||
if (rsdpv2)
|
||||
fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *)
|
||||
(grub_addr_t) rsdpv2->rsdpv1.rsdt_addr,
|
||||
GRUB_ACPI_FADT_SIGNATURE);
|
||||
if (fadt)
|
||||
return fadt;
|
||||
if (rsdpv2
|
||||
#if GRUB_CPU_SIZEOF_VOID_P != 8
|
||||
&& !(rsdpv2->xsdt_addr >> 32)
|
||||
#endif
|
||||
)
|
||||
fadt = grub_acpi_xsdt_find_table ((struct grub_acpi_table_header *)
|
||||
(grub_addr_t) rsdpv2->xsdt_addr,
|
||||
GRUB_ACPI_FADT_SIGNATURE);
|
||||
if (fadt)
|
||||
return fadt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -55,10 +55,6 @@ FUNCTION(_start)
|
||||
VARIABLE(grub_total_module_size)
|
||||
.long 0
|
||||
|
||||
VARIABLE(grub_uboot_machine_type)
|
||||
.long 0
|
||||
VARIABLE(grub_uboot_boot_data)
|
||||
.long 0
|
||||
VARIABLE(grub_modbase)
|
||||
.long 0
|
||||
bss_start_ptr:
|
||||
@@ -66,29 +62,66 @@ bss_start_ptr:
|
||||
end_ptr:
|
||||
.long EXT_C(_end)
|
||||
|
||||
@ Memory map at start:
|
||||
@ * text+data
|
||||
@ * list relocations
|
||||
@ * modules
|
||||
@ Before we enter C, we need to apply the relocations
|
||||
@ and get following map:
|
||||
@ * text+data
|
||||
@ * BSS (cleared)
|
||||
@ * stack
|
||||
@ * modules
|
||||
@
|
||||
@ To make things easier we ensure
|
||||
@ that BSS+stack is larger than list of relocations
|
||||
@ by increasing stack if necessarry.
|
||||
@ This allows us to always unconditionally copy backwards
|
||||
@ Currently list of relocations is ~5K and stack is set
|
||||
@ to be at least 256K
|
||||
|
||||
FUNCTION(codestart)
|
||||
@ Store context: Machine ID, atags/dtb, ...
|
||||
@ U-Boot API signature is stored on the U-Boot heap
|
||||
@ Stack pointer used as start address for signature probing
|
||||
mov r12, sp
|
||||
adr sp, entry_state
|
||||
push {r4-r12,lr} @ store U-Boot context (sp in r12)
|
||||
push {r1-r12,lr} @ store U-Boot context (sp in r12)
|
||||
|
||||
str r1, EXT_C(grub_uboot_machine_type)
|
||||
str r2, EXT_C(grub_uboot_boot_data)
|
||||
|
||||
@ Modules have been stored as a blob in BSS,
|
||||
@ they need to be manually relocated to _end
|
||||
adr r1, _start
|
||||
ldr r0, bss_start_ptr @ src
|
||||
add r0, r0, r1
|
||||
|
||||
add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
|
||||
mvn r2, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
|
||||
and r0, r0, r2
|
||||
1:
|
||||
ldr r3, [r0], #4 @load next offset
|
||||
@ both -2 and -1 are treated the same as we have only one type of relocs
|
||||
@ -2 means "end of this type of relocs" and -1 means "end of all relocs"
|
||||
add r2, r3, #2
|
||||
cmp r2, #1
|
||||
bls reloc_done
|
||||
@ Adjust next offset
|
||||
ldr r2, [r3, r1]
|
||||
add r2, r2, r1
|
||||
str r2, [r3, r1]
|
||||
b 1b
|
||||
|
||||
reloc_done:
|
||||
|
||||
@ Modules have been stored as a blob
|
||||
@ they need to be manually relocated to _end
|
||||
add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
|
||||
mvn r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
|
||||
and r0, r0, r1
|
||||
and r0, r0, r1 @ src = aligned end of relocations
|
||||
|
||||
ldr r1, end_ptr @ dst = End of BSS
|
||||
ldr r2, grub_total_module_size @ blob size
|
||||
|
||||
add r1, r1, #GRUB_KERNEL_MACHINE_STACK_SIZE
|
||||
and r1, r1, #~0x7 @ Ensure 8-byte alignment
|
||||
|
||||
sub sp, r1, #8
|
||||
add r1, r1, #1024
|
||||
|
||||
@@ -157,6 +190,11 @@ FUNCTION(grub_uboot_return)
|
||||
.align 3
|
||||
@ U-boot context stack space
|
||||
entry_state_end:
|
||||
VARIABLE(grub_uboot_machine_type)
|
||||
.long 0 @ r1
|
||||
VARIABLE(grub_uboot_boot_data)
|
||||
.long 0 @ r2
|
||||
.long 0 @ r3
|
||||
.long 0 @ r4
|
||||
.long 0 @ r5
|
||||
.long 0 @ r6
|
||||
|
||||
@@ -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);
|
||||
@@ -132,6 +92,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
|
||||
*abs_place = (grub_uint64_t) sym_addr;
|
||||
}
|
||||
break;
|
||||
case R_AARCH64_ADD_ABS_LO12_NC:
|
||||
grub_arm64_set_abs_lo12 (place, sym_addr);
|
||||
break;
|
||||
case R_AARCH64_LDST64_ABS_LO12_NC:
|
||||
grub_arm64_set_abs_lo12_ldst64 (place, sym_addr);
|
||||
break;
|
||||
case R_AARCH64_CALL26:
|
||||
case R_AARCH64_JUMP26:
|
||||
{
|
||||
@@ -139,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;
|
||||
@@ -154,6 +120,68 @@ 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);
|
||||
|
||||
if (!grub_arm64_check_hi21_signed (offset))
|
||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||
"HI21 out of range");
|
||||
|
||||
grub_arm64_set_hi21 (place, offset);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
N_("relocation 0x%x is not implemented yet"),
|
||||
|
||||
@@ -53,3 +53,82 @@ grub_arm64_set_xxxx26_offset (grub_uint32_t *place, grub_int64_t offset)
|
||||
*place &= insmask;
|
||||
*place |= grub_cpu_to_le32 (offset >> 2) & ~insmask;
|
||||
}
|
||||
|
||||
int
|
||||
grub_arm64_check_hi21_signed (grub_int64_t offset)
|
||||
{
|
||||
if (offset != (grub_int64_t)(grub_int32_t)offset)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
grub_arm64_set_hi21 (grub_uint32_t *place, grub_int64_t offset)
|
||||
{
|
||||
const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0x9f00001f);
|
||||
grub_uint32_t val;
|
||||
|
||||
offset >>= 12;
|
||||
|
||||
val = ((offset & 3) << 29) | (((offset >> 2) & 0x7ffff) << 5);
|
||||
|
||||
*place &= insmask;
|
||||
*place |= grub_cpu_to_le32 (val) & ~insmask;
|
||||
}
|
||||
|
||||
void
|
||||
grub_arm64_set_abs_lo12 (grub_uint32_t *place, grub_int64_t target)
|
||||
{
|
||||
const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffc003ff);
|
||||
|
||||
*place &= insmask;
|
||||
*place |= grub_cpu_to_le32 (target << 10) & ~insmask;
|
||||
}
|
||||
|
||||
void
|
||||
grub_arm64_set_abs_lo12_ldst64 (grub_uint32_t *place, grub_int64_t target)
|
||||
{
|
||||
const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfff803ff);
|
||||
|
||||
*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;
|
||||
}
|
||||
|
||||
60
grub-core/kern/arm64/efi/init.c
Normal file
60
grub-core/kern/arm64/efi/init.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/* init.c - initialize an arm-based EFI system */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* 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/env.h>
|
||||
#include <grub/kernel.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/loader.h>
|
||||
|
||||
static grub_uint64_t timer_frequency_in_khz;
|
||||
|
||||
static grub_uint64_t
|
||||
grub_efi_get_time_ms (void)
|
||||
{
|
||||
grub_uint64_t tmr;
|
||||
asm volatile("mrs %0, cntvct_el0" : "=r" (tmr));
|
||||
|
||||
return tmr / timer_frequency_in_khz;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
grub_machine_init (void)
|
||||
{
|
||||
grub_uint64_t timer_frequency;
|
||||
|
||||
grub_efi_init ();
|
||||
|
||||
asm volatile("mrs %0, cntfrq_el0" : "=r" (timer_frequency));
|
||||
timer_frequency_in_khz = timer_frequency / 1000;
|
||||
|
||||
grub_install_get_time_ms (grub_efi_get_time_ms);
|
||||
}
|
||||
|
||||
void
|
||||
grub_machine_fini (int flags)
|
||||
{
|
||||
if (!(flags & GRUB_LOADER_FLAG_NORETURN))
|
||||
return;
|
||||
|
||||
grub_efi_fini ();
|
||||
}
|
||||
@@ -333,8 +333,11 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
|
||||
if (s->sh_type == SHT_SYMTAB)
|
||||
break;
|
||||
|
||||
/* Module without symbol table may still be used to pull in dependencies.
|
||||
We verify at build time that such modules do not contain any relocations
|
||||
that may reference symbol table. */
|
||||
if (i == e->e_shnum)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
#ifdef GRUB_MODULES_MACHINE_READONLY
|
||||
mod->symtab = grub_malloc (s->sh_size);
|
||||
@@ -576,6 +579,9 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||
|
||||
if (seg)
|
||||
{
|
||||
if (!mod->symtab)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol table");
|
||||
|
||||
err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -605,7 +611,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
|
||||
}
|
||||
|
||||
/* Make sure that every section is within the core. */
|
||||
if (size < e->e_shoff + e->e_shentsize * e->e_shnum)
|
||||
if (size < e->e_shoff + (grub_uint32_t) e->e_shentsize * e->e_shnum)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core");
|
||||
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. */
|
||||
|
||||
@@ -12,7 +12,7 @@ grub_elfXX_load_phdrs (grub_elf_t elf)
|
||||
if (elf->phdrs)
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
phdrs_size = elf->ehdr.ehdrXX.e_phnum * elf->ehdr.ehdrXX.e_phentsize;
|
||||
phdrs_size = (grub_uint32_t) elf->ehdr.ehdrXX.e_phnum * elf->ehdr.ehdrXX.e_phentsize;
|
||||
|
||||
grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n",
|
||||
(unsigned long long) elf->ehdr.ehdrXX.e_phoff,
|
||||
|
||||
@@ -161,9 +161,9 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
|
||||
{
|
||||
struct stat st;
|
||||
# if GRUB_DISK_DEVS_ARE_CHAR
|
||||
if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
|
||||
if (fstat (fd, &st) >= 0 && S_ISCHR (st.st_mode))
|
||||
# else
|
||||
if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode))
|
||||
if (fstat (fd, &st) >= 0 && S_ISBLK (st.st_mode))
|
||||
# endif
|
||||
data->is_disk = 1;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,13 @@ void
|
||||
grub_reboot (void)
|
||||
{
|
||||
longjmp (main_env, 1);
|
||||
grub_fatal ("longjmp failed");
|
||||
}
|
||||
|
||||
void
|
||||
grub_exit (void)
|
||||
{
|
||||
grub_reboot ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -195,7 +202,7 @@ main (int argc, char *argv[])
|
||||
volatile int hold = 0;
|
||||
size_t total_module_size = sizeof (struct grub_module_info), memdisk_size = 0;
|
||||
struct grub_module_info *modinfo;
|
||||
char *mods;
|
||||
void *mods;
|
||||
|
||||
grub_util_host_init (&argc, &argv);
|
||||
|
||||
@@ -226,10 +233,10 @@ main (int argc, char *argv[])
|
||||
struct grub_module_header *header = (struct grub_module_header *) mods;
|
||||
header->type = OBJ_TYPE_MEMDISK;
|
||||
header->size = memdisk_size + sizeof (*header);
|
||||
mods += sizeof (*header);
|
||||
mods = header + 1;
|
||||
|
||||
grub_util_load_image (arguments.mem_disk, mods);
|
||||
mods += memdisk_size;
|
||||
mods = (char *) mods + memdisk_size;
|
||||
}
|
||||
|
||||
grub_modbase = (grub_addr_t) modinfo;
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -134,11 +135,13 @@ xasprintf (const char *fmt, ...)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL)
|
||||
void
|
||||
grub_exit (void)
|
||||
{
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
grub_uint64_t
|
||||
grub_get_time_ms (void)
|
||||
|
||||
@@ -44,6 +44,13 @@ FUNCTION(grub_bios_interrupt)
|
||||
movl 24(%edx), %esi
|
||||
movl 28(%edx), %edx
|
||||
|
||||
/*
|
||||
Via C3 CPUs have cache coherence problems, so we need to call
|
||||
wbinvd at these 2 points. As wbinvd slows down boot, don't do
|
||||
it on non-VIA. 9090 is nop nop. */
|
||||
VARIABLE(grub_bios_via_workaround1)
|
||||
.byte 0x90, 0x90
|
||||
|
||||
PROT_TO_REAL
|
||||
.code16
|
||||
pushf
|
||||
@@ -92,6 +99,10 @@ intno:
|
||||
movw %ax, LOCAL(bios_register_es)
|
||||
|
||||
popf
|
||||
|
||||
VARIABLE(grub_bios_via_workaround2)
|
||||
.byte 0x90, 0x90
|
||||
|
||||
REAL_TO_PROT
|
||||
.code32
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <grub/env.h>
|
||||
#include <grub/cache.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/cpu/cpuid.h>
|
||||
#include <grub/cpu/tsc.h>
|
||||
#include <grub/machine/time.h>
|
||||
|
||||
@@ -184,6 +185,26 @@ mmap_iterate_hook (grub_uint64_t addr, grub_uint64_t size,
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern grub_uint16_t grub_bios_via_workaround1, grub_bios_via_workaround2;
|
||||
|
||||
/* Via needs additional wbinvd. */
|
||||
static void
|
||||
grub_via_workaround_init (void)
|
||||
{
|
||||
grub_uint32_t manufacturer[3], max_cpuid;
|
||||
if (! grub_cpu_is_cpuid_supported ())
|
||||
return;
|
||||
|
||||
grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);
|
||||
|
||||
if (grub_memcmp (manufacturer, "CentaurHauls", 12) != 0)
|
||||
return;
|
||||
|
||||
grub_bios_via_workaround1 = 0x090f;
|
||||
grub_bios_via_workaround2 = 0x090f;
|
||||
asm volatile ("wbinvd");
|
||||
}
|
||||
|
||||
void
|
||||
grub_machine_init (void)
|
||||
{
|
||||
@@ -193,6 +214,9 @@ grub_machine_init (void)
|
||||
#endif
|
||||
grub_addr_t modend;
|
||||
|
||||
/* This has to happen before any BIOS calls. */
|
||||
grub_via_workaround_init ();
|
||||
|
||||
grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start);
|
||||
|
||||
/* Initialize the console as early as possible. */
|
||||
|
||||
@@ -43,22 +43,6 @@ grub_tsc_get_time_ms (void)
|
||||
return ((al * grub_tsc_rate) >> 32) + ah * grub_tsc_rate;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
grub_cpu_is_tsc_supported (void)
|
||||
{
|
||||
#ifndef GRUB_MACHINE_XEN
|
||||
grub_uint32_t a,b,c,d;
|
||||
if (! grub_cpu_is_cpuid_supported ())
|
||||
return 0;
|
||||
|
||||
grub_cpuid(1,a,b,c,d);
|
||||
|
||||
return (d & (1 << 4)) != 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
calibrate_tsc_hardcode (void)
|
||||
{
|
||||
|
||||
@@ -24,129 +24,35 @@
|
||||
#include <grub/time.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i386/tsc.h>
|
||||
#include <grub/i386/pmtimer.h>
|
||||
#include <grub/acpi.h>
|
||||
#include <grub/cpu/io.h>
|
||||
|
||||
static void *
|
||||
grub_acpi_rsdt_find_table (struct grub_acpi_table_header *rsdt, const char *sig)
|
||||
{
|
||||
grub_size_t s;
|
||||
grub_uint32_t *ptr;
|
||||
|
||||
if (!rsdt)
|
||||
return 0;
|
||||
|
||||
if (grub_memcmp (rsdt->signature, "RSDT", 4) != 0)
|
||||
return 0;
|
||||
|
||||
ptr = (grub_uint32_t *) (rsdt + 1);
|
||||
s = (rsdt->length - sizeof (*rsdt)) / sizeof (grub_uint32_t);
|
||||
for (; s; s--, ptr++)
|
||||
{
|
||||
struct grub_acpi_table_header *tbl;
|
||||
tbl = (struct grub_acpi_table_header *) (grub_addr_t) *ptr;
|
||||
if (grub_memcmp (tbl->signature, sig, 4) == 0)
|
||||
return tbl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *
|
||||
grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char *sig)
|
||||
{
|
||||
grub_size_t s;
|
||||
grub_uint64_t *ptr;
|
||||
|
||||
if (!xsdt)
|
||||
return 0;
|
||||
|
||||
if (grub_memcmp (xsdt->signature, "XSDT", 4) != 0)
|
||||
return 0;
|
||||
|
||||
ptr = (grub_uint64_t *) (xsdt + 1);
|
||||
s = (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint32_t);
|
||||
for (; s; s--, ptr++)
|
||||
{
|
||||
struct grub_acpi_table_header *tbl;
|
||||
#if GRUB_CPU_SIZEOF_VOID_P != 8
|
||||
if (*ptr >> 32)
|
||||
continue;
|
||||
#endif
|
||||
tbl = (struct grub_acpi_table_header *) (grub_addr_t) *ptr;
|
||||
if (grub_memcmp (tbl->signature, sig, 4) == 0)
|
||||
return tbl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct grub_acpi_fadt *
|
||||
grub_acpi_find_fadt (void)
|
||||
{
|
||||
struct grub_acpi_fadt *fadt = 0;
|
||||
struct grub_acpi_rsdp_v10 *rsdpv1;
|
||||
struct grub_acpi_rsdp_v20 *rsdpv2;
|
||||
rsdpv1 = grub_machine_acpi_get_rsdpv1 ();
|
||||
if (rsdpv1)
|
||||
fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *)
|
||||
(grub_addr_t) rsdpv1->rsdt_addr,
|
||||
GRUB_ACPI_FADT_SIGNATURE);
|
||||
if (fadt)
|
||||
return fadt;
|
||||
rsdpv2 = grub_machine_acpi_get_rsdpv2 ();
|
||||
if (rsdpv2)
|
||||
fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *)
|
||||
(grub_addr_t) rsdpv2->rsdpv1.rsdt_addr,
|
||||
GRUB_ACPI_FADT_SIGNATURE);
|
||||
if (fadt)
|
||||
return fadt;
|
||||
if (rsdpv2
|
||||
#if GRUB_CPU_SIZEOF_VOID_P != 8
|
||||
&& !(rsdpv2->xsdt_addr >> 32)
|
||||
#endif
|
||||
)
|
||||
fadt = grub_acpi_xsdt_find_table ((struct grub_acpi_table_header *)
|
||||
(grub_addr_t) rsdpv2->xsdt_addr,
|
||||
GRUB_ACPI_FADT_SIGNATURE);
|
||||
if (fadt)
|
||||
return fadt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
grub_tsc_calibrate_from_pmtimer (void)
|
||||
grub_uint64_t
|
||||
grub_pmtimer_wait_count_tsc (grub_port_t pmtimer,
|
||||
grub_uint16_t num_pm_ticks)
|
||||
{
|
||||
grub_uint32_t start;
|
||||
grub_uint32_t last;
|
||||
grub_uint32_t cur, end;
|
||||
struct grub_acpi_fadt *fadt;
|
||||
grub_port_t p;
|
||||
grub_uint64_t start_tsc;
|
||||
grub_uint64_t end_tsc;
|
||||
int num_iter = 0;
|
||||
|
||||
fadt = grub_acpi_find_fadt ();
|
||||
if (!fadt)
|
||||
return 0;
|
||||
p = fadt->pmtimer;
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
start = grub_inl (p) & 0xffffff;
|
||||
start = grub_inl (pmtimer) & 0xffffff;
|
||||
last = start;
|
||||
/* It's 3.579545 MHz clock. Wait 1 ms. */
|
||||
end = start + 3580;
|
||||
end = start + num_pm_ticks;
|
||||
start_tsc = grub_get_tsc ();
|
||||
while (1)
|
||||
{
|
||||
cur = grub_inl (p) & 0xffffff;
|
||||
cur = grub_inl (pmtimer) & 0xffffff;
|
||||
if (cur < last)
|
||||
cur |= 0x1000000;
|
||||
num_iter++;
|
||||
if (cur >= end)
|
||||
{
|
||||
end_tsc = grub_get_tsc ();
|
||||
grub_tsc_rate = grub_divmod64 ((1ULL << 32), end_tsc - start_tsc, 0);
|
||||
return 1;
|
||||
return end_tsc - start_tsc;
|
||||
}
|
||||
/* Check for broken PM timer.
|
||||
50000000 TSCs is between 5 ms (10GHz) and 200 ms (250 MHz)
|
||||
@@ -158,3 +64,25 @@ grub_tsc_calibrate_from_pmtimer (void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
grub_tsc_calibrate_from_pmtimer (void)
|
||||
{
|
||||
struct grub_acpi_fadt *fadt;
|
||||
grub_port_t pmtimer;
|
||||
grub_uint64_t tsc_diff;
|
||||
|
||||
fadt = grub_acpi_find_fadt ();
|
||||
if (!fadt)
|
||||
return 0;
|
||||
pmtimer = fadt->pmtimer;
|
||||
if (!pmtimer)
|
||||
return 0;
|
||||
|
||||
/* It's 3.579545 MHz clock. Wait 1 ms. */
|
||||
tsc_diff = grub_pmtimer_wait_count_tsc (pmtimer, 3580);
|
||||
if (tsc_diff == 0)
|
||||
return 0;
|
||||
grub_tsc_rate = grub_divmod64 ((1ULL << 32), tsc_diff, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -46,11 +46,19 @@
|
||||
#define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024)
|
||||
|
||||
/* The maximum heap size we're going to claim */
|
||||
#ifdef __i386__
|
||||
#define HEAP_MAX_SIZE (unsigned long) (64 * 1024 * 1024)
|
||||
#else
|
||||
#define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
/* If possible, we will avoid claiming heap above this address, because it
|
||||
seems to cause relocation problems with OSes that link at 4 MiB */
|
||||
#ifdef __i386__
|
||||
#define HEAP_MAX_ADDR (unsigned long) (64 * 1024 * 1024)
|
||||
#else
|
||||
#define HEAP_MAX_ADDR (unsigned long) (32 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
extern char _start[];
|
||||
extern char _end[];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -740,6 +740,12 @@ parse_printf_args (const char *fmt0, struct printf_args *args,
|
||||
fmt++;
|
||||
|
||||
c = *fmt++;
|
||||
if (c == '%')
|
||||
{
|
||||
n--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == 'l')
|
||||
{
|
||||
c = *fmt++;
|
||||
@@ -876,6 +882,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
|
||||
if (c == '%')
|
||||
{
|
||||
write_char (str, &count, max_len,c);
|
||||
n--;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1099,6 +1106,8 @@ grub_fatal (const char *fmt, ...)
|
||||
grub_vprintf (_(fmt), ap);
|
||||
va_end (ap);
|
||||
|
||||
grub_refresh ();
|
||||
|
||||
grub_abort ();
|
||||
}
|
||||
|
||||
|
||||
@@ -325,6 +325,15 @@ grub_memalign (grub_size_t align, grub_size_t size)
|
||||
if (!grub_mm_base)
|
||||
goto fail;
|
||||
|
||||
if (size > ~(grub_size_t) align)
|
||||
goto fail;
|
||||
|
||||
/* We currently assume at least a 32-bit grub_size_t,
|
||||
so limiting allocations to <adress space size> - 1MiB
|
||||
in name of sanity is beneficial. */
|
||||
if ((size + align) > ~(grub_size_t) 0x100000)
|
||||
goto fail;
|
||||
|
||||
align = (align >> GRUB_MM_ALIGN_LOG2);
|
||||
if (align == 0)
|
||||
align = 1;
|
||||
|
||||
@@ -43,13 +43,17 @@ grub_rescue_parse_line (char *line,
|
||||
|
||||
/* In case of an assignment set the environment accordingly
|
||||
instead of calling a function. */
|
||||
if (n == 1 && grub_strchr (line, '='))
|
||||
if (n == 1)
|
||||
{
|
||||
char *val = grub_strchr (args[0], '=');
|
||||
val[0] = 0;
|
||||
grub_env_set (args[0], val + 1);
|
||||
val[0] = '=';
|
||||
goto quit;
|
||||
|
||||
if (val)
|
||||
{
|
||||
val[0] = 0;
|
||||
grub_env_set (args[0], val + 1);
|
||||
val[0] = '=';
|
||||
goto quit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the command name. */
|
||||
@@ -72,6 +76,7 @@ grub_rescue_parse_line (char *line,
|
||||
}
|
||||
|
||||
quit:
|
||||
/* Arguments are returned in single memory chunk separated by zeroes */
|
||||
grub_free (args[0]);
|
||||
grub_free (args);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
103
grub-core/lib/i386/random.c
Normal file
103
grub-core/lib/i386/random.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2016 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/random.h>
|
||||
#include <grub/i386/io.h>
|
||||
#include <grub/i386/tsc.h>
|
||||
#include <grub/i386/pmtimer.h>
|
||||
#include <grub/acpi.h>
|
||||
|
||||
static int have_tsc = -1, have_pmtimer = -1;
|
||||
static grub_port_t pmtimer_port;
|
||||
|
||||
static int
|
||||
detect_pmtimer (void)
|
||||
{
|
||||
struct grub_acpi_fadt *fadt;
|
||||
fadt = grub_acpi_find_fadt ();
|
||||
if (!fadt)
|
||||
return 0;
|
||||
pmtimer_port = fadt->pmtimer;
|
||||
if (!pmtimer_port)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pmtimer_tsc_get_random_bit (void)
|
||||
{
|
||||
/* It's hard to come up with figures about pmtimer and tsc jitter but
|
||||
50 ppm seems to be typical. So we need 10^6/50 tsc cycles to get drift
|
||||
of one tsc cycle. With TSC at least of 800 MHz it means 1/(50*800)
|
||||
= 1/40000 s or about 3579545 / 40000 = 90 pmtimer ticks.
|
||||
This gives us rate of 40000 bit/s or 5 kB/s.
|
||||
*/
|
||||
grub_uint64_t tsc_diff;
|
||||
tsc_diff = grub_pmtimer_wait_count_tsc (pmtimer_port, 90);
|
||||
if (tsc_diff == 0)
|
||||
{
|
||||
have_pmtimer = 0;
|
||||
return -1;
|
||||
}
|
||||
return tsc_diff & 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pmtimer_tsc_get_random_byte (void)
|
||||
{
|
||||
grub_uint8_t ret = 0;
|
||||
int i, c;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
c = pmtimer_tsc_get_random_bit ();
|
||||
if (c < 0)
|
||||
return -1;
|
||||
ret |= c << i;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
pmtimer_fill_buffer (void *buffer, grub_size_t sz)
|
||||
{
|
||||
grub_uint8_t *p = buffer;
|
||||
int c;
|
||||
while (sz)
|
||||
{
|
||||
c = pmtimer_tsc_get_random_byte ();
|
||||
if (c < 0)
|
||||
return 0;
|
||||
*p++ = c;
|
||||
sz--;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
grub_crypto_arch_get_random (void *buffer, grub_size_t sz)
|
||||
{
|
||||
if (have_tsc == -1)
|
||||
have_tsc = grub_cpu_is_tsc_supported ();
|
||||
if (!have_tsc)
|
||||
return 0;
|
||||
if (have_pmtimer == -1)
|
||||
have_pmtimer = detect_pmtimer ();
|
||||
if (!have_pmtimer)
|
||||
return 0;
|
||||
return pmtimer_fill_buffer (buffer, sz);
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -31,7 +31,6 @@ GRUB_MOD_LICENSE ("GPLv2+");
|
||||
desired derived output length DKLEN. Output buffer is DK which
|
||||
must have room for at least DKLEN octets. The output buffer will
|
||||
be filled with the derived data. */
|
||||
#pragma GCC diagnostic ignored "-Wunreachable-code"
|
||||
|
||||
gcry_err_code_t
|
||||
grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
|
||||
120
grub-core/lib/random.c
Normal file
120
grub-core/lib/random.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2016 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/random.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/lib/hexdump.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/mm.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
grub_err_t
|
||||
grub_crypto_get_random (void *buffer, grub_size_t sz)
|
||||
{
|
||||
/* This is an arbitrer between different methods.
|
||||
TODO: Add more methods in the future. */
|
||||
/* TODO: Add some PRNG smartness to reduce damage from bad entropy. */
|
||||
if (grub_crypto_arch_get_random (buffer, sz))
|
||||
return GRUB_ERR_NONE;
|
||||
return grub_error (GRUB_ERR_IO, "no random sources found");
|
||||
}
|
||||
|
||||
static int
|
||||
get_num_digits (int val)
|
||||
{
|
||||
int ret = 0;
|
||||
while (val != 0)
|
||||
{
|
||||
ret++;
|
||||
val /= 10;
|
||||
}
|
||||
if (ret == 0)
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_hexdump_random (grub_command_t cmd __attribute__ ((unused)), int argc, char **args)
|
||||
{
|
||||
grub_size_t length = 64;
|
||||
grub_err_t err;
|
||||
void *buffer;
|
||||
grub_uint8_t *ptr;
|
||||
int stats[256];
|
||||
int i, digits = 2;
|
||||
char template[10];
|
||||
|
||||
if (argc >= 1)
|
||||
length = grub_strtoull (args[0], 0, 0);
|
||||
|
||||
if (length == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "length pust be positive");
|
||||
|
||||
buffer = grub_malloc (length);
|
||||
if (!buffer)
|
||||
return grub_errno;
|
||||
|
||||
err = grub_crypto_get_random (buffer, length);
|
||||
if (err)
|
||||
{
|
||||
grub_free (buffer);
|
||||
return err;
|
||||
}
|
||||
|
||||
hexdump (0, buffer, length);
|
||||
grub_memset(stats, 0, sizeof(stats));
|
||||
for (ptr = buffer; ptr < (grub_uint8_t *) buffer + length; ptr++)
|
||||
stats[*ptr]++;
|
||||
grub_printf ("Statistics:\n");
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
int z = get_num_digits (stats[i]);
|
||||
if (z > digits)
|
||||
digits = z;
|
||||
}
|
||||
|
||||
grub_snprintf (template, sizeof (template), "%%0%dd ", digits);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
grub_printf ("%s", template);//, stats[i]);
|
||||
if ((i & 0xf) == 0xf)
|
||||
grub_printf ("\n");
|
||||
}
|
||||
|
||||
grub_free (buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT (random)
|
||||
{
|
||||
cmd = grub_register_command ("hexdump_random", grub_cmd_hexdump_random,
|
||||
N_("[LENGTH]"),
|
||||
N_("Hexdump random data."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (random)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
||||
@@ -736,26 +736,36 @@ malloc_in_range (struct grub_relocator *rel,
|
||||
}
|
||||
isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw)
|
||||
&& !nblockfw)));
|
||||
if (!isinsidebefore && isinsideafter)
|
||||
starta = from_low_priv ? ALIGN_UP (events[j].pos, align)
|
||||
: ALIGN_DOWN (events[j].pos - size, align) + size;
|
||||
if (isinsidebefore && !isinsideafter && from_low_priv)
|
||||
{
|
||||
target = starta;
|
||||
if (target < start)
|
||||
target = start;
|
||||
if (target + size <= end && target + size <= events[j].pos)
|
||||
/* Found an usable address. */
|
||||
goto found;
|
||||
}
|
||||
if (isinsidebefore && !isinsideafter && !from_low_priv)
|
||||
{
|
||||
target = starta - size;
|
||||
if (target > end - size)
|
||||
target = end - size;
|
||||
if (target >= start && target >= events[j].pos)
|
||||
goto found;
|
||||
}
|
||||
if (from_low_priv) {
|
||||
if (!isinsidebefore && isinsideafter)
|
||||
starta = ALIGN_UP (events[j].pos, align);
|
||||
|
||||
if (isinsidebefore && !isinsideafter)
|
||||
{
|
||||
target = starta;
|
||||
if (target < start)
|
||||
target = start;
|
||||
if (target + size <= end && target + size <= events[j].pos)
|
||||
/* Found an usable address. */
|
||||
goto found;
|
||||
}
|
||||
} else {
|
||||
if (!isinsidebefore && isinsideafter)
|
||||
{
|
||||
if (events[j].pos >= size)
|
||||
starta = ALIGN_DOWN (events[j].pos - size, align) + size;
|
||||
else
|
||||
starta = 0;
|
||||
}
|
||||
if (isinsidebefore && !isinsideafter && starta >= size)
|
||||
{
|
||||
target = starta - size;
|
||||
if (target > end - size)
|
||||
target = end - size;
|
||||
if (target >= start && target >= events[j].pos)
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
|
||||
typedef grub_addr_t grub_xen_reg_t;
|
||||
|
||||
struct grub_relocator_xen_paging_area {
|
||||
grub_xen_reg_t start;
|
||||
grub_xen_reg_t size;
|
||||
} GRUB_PACKED;
|
||||
|
||||
extern grub_uint8_t grub_relocator_xen_start;
|
||||
extern grub_uint8_t grub_relocator_xen_end;
|
||||
extern grub_uint8_t grub_relocator_xen_remap_start;
|
||||
@@ -36,15 +41,16 @@ extern grub_uint8_t grub_relocator_xen_remap_end;
|
||||
extern grub_xen_reg_t grub_relocator_xen_stack;
|
||||
extern grub_xen_reg_t grub_relocator_xen_start_info;
|
||||
extern grub_xen_reg_t grub_relocator_xen_entry_point;
|
||||
extern grub_xen_reg_t grub_relocator_xen_paging_start;
|
||||
extern grub_xen_reg_t grub_relocator_xen_paging_size;
|
||||
extern grub_xen_reg_t grub_relocator_xen_remapper_virt;
|
||||
extern grub_xen_reg_t grub_relocator_xen_remapper_virt2;
|
||||
extern grub_xen_reg_t grub_relocator_xen_remapper_map;
|
||||
extern grub_xen_reg_t grub_relocator_xen_mfn_list;
|
||||
extern struct grub_relocator_xen_paging_area
|
||||
grub_relocator_xen_paging_areas[XEN_MAX_MAPPINGS];
|
||||
extern grub_xen_reg_t grub_relocator_xen_remap_continue;
|
||||
#ifdef __i386__
|
||||
extern grub_xen_reg_t grub_relocator_xen_mmu_op_addr;
|
||||
extern grub_xen_reg_t grub_relocator_xen_paging_areas_addr;
|
||||
extern grub_xen_reg_t grub_relocator_xen_remapper_map_high;
|
||||
#endif
|
||||
extern mmuext_op_t grub_relocator_xen_mmu_op[3];
|
||||
@@ -61,6 +67,7 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
|
||||
{
|
||||
grub_err_t err;
|
||||
void *relst;
|
||||
int i;
|
||||
grub_relocator_chunk_t ch, ch_tramp;
|
||||
grub_xen_mfn_t *mfn_list =
|
||||
(grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list;
|
||||
@@ -77,8 +84,11 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
|
||||
grub_relocator_xen_stack = state.stack;
|
||||
grub_relocator_xen_start_info = state.start_info;
|
||||
grub_relocator_xen_entry_point = state.entry_point;
|
||||
grub_relocator_xen_paging_start = state.paging_start << 12;
|
||||
grub_relocator_xen_paging_size = state.paging_size;
|
||||
for (i = 0; i < XEN_MAX_MAPPINGS; i++)
|
||||
{
|
||||
grub_relocator_xen_paging_areas[i].start = state.paging_start[i];
|
||||
grub_relocator_xen_paging_areas[i].size = state.paging_size[i];
|
||||
}
|
||||
grub_relocator_xen_remapper_virt = remapper_virt;
|
||||
grub_relocator_xen_remapper_virt2 = remapper_virt;
|
||||
grub_relocator_xen_remap_continue = trampoline_virt;
|
||||
@@ -88,10 +98,12 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
|
||||
grub_relocator_xen_remapper_map_high = (mfn_list[remapper_pfn] >> 20);
|
||||
grub_relocator_xen_mmu_op_addr = (char *) &grub_relocator_xen_mmu_op
|
||||
- (char *) &grub_relocator_xen_remap_start + remapper_virt;
|
||||
grub_relocator_xen_paging_areas_addr =
|
||||
(char *) &grub_relocator_xen_paging_areas
|
||||
- (char *) &grub_relocator_xen_remap_start + remapper_virt;
|
||||
#endif
|
||||
|
||||
grub_relocator_xen_mfn_list = state.mfn_list
|
||||
+ state.paging_start * sizeof (grub_addr_t);
|
||||
grub_relocator_xen_mfn_list = state.mfn_list;
|
||||
|
||||
grub_memset (grub_relocator_xen_mmu_op, 0,
|
||||
sizeof (grub_relocator_xen_mmu_op));
|
||||
@@ -100,9 +112,9 @@ grub_relocator_xen_boot (struct grub_relocator *rel,
|
||||
#else
|
||||
grub_relocator_xen_mmu_op[0].cmd = MMUEXT_PIN_L4_TABLE;
|
||||
#endif
|
||||
grub_relocator_xen_mmu_op[0].arg1.mfn = mfn_list[state.paging_start];
|
||||
grub_relocator_xen_mmu_op[0].arg1.mfn = mfn_list[state.paging_start[0]];
|
||||
grub_relocator_xen_mmu_op[1].cmd = MMUEXT_NEW_BASEPTR;
|
||||
grub_relocator_xen_mmu_op[1].arg1.mfn = mfn_list[state.paging_start];
|
||||
grub_relocator_xen_mmu_op[1].arg1.mfn = mfn_list[state.paging_start[0]];
|
||||
grub_relocator_xen_mmu_op[2].cmd = MMUEXT_UNPIN_TABLE;
|
||||
grub_relocator_xen_mmu_op[2].arg1.mfn =
|
||||
mfn_list[grub_xen_start_page_addr->pt_base >> 12];
|
||||
|
||||
@@ -1044,6 +1044,8 @@ enum xz_ret xz_dec_lzma2_run(
|
||||
|
||||
s->lzma2.sequence = SEQ_LZMA_PREPARE;
|
||||
|
||||
/* Fall through */
|
||||
|
||||
case SEQ_LZMA_PREPARE:
|
||||
if (s->lzma2.compressed < RC_INIT_BYTES)
|
||||
return XZ_DATA_ERROR;
|
||||
@@ -1054,6 +1056,8 @@ enum xz_ret xz_dec_lzma2_run(
|
||||
s->lzma2.compressed -= RC_INIT_BYTES;
|
||||
s->lzma2.sequence = SEQ_LZMA_RUN;
|
||||
|
||||
/* Fall through */
|
||||
|
||||
case SEQ_LZMA_RUN:
|
||||
/*
|
||||
* Set dictionary limit to indicate how much we want
|
||||
|
||||
@@ -750,6 +750,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
||||
|
||||
s->sequence = SEQ_BLOCK_START;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case SEQ_BLOCK_START:
|
||||
/* We need one byte of input to continue. */
|
||||
if (b->in_pos == b->in_size)
|
||||
@@ -773,6 +774,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
||||
s->temp.pos = 0;
|
||||
s->sequence = SEQ_BLOCK_HEADER;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case SEQ_BLOCK_HEADER:
|
||||
if (!fill_temp(s, b))
|
||||
return XZ_OK;
|
||||
@@ -783,6 +785,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
||||
|
||||
s->sequence = SEQ_BLOCK_UNCOMPRESS;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case SEQ_BLOCK_UNCOMPRESS:
|
||||
ret = dec_block(s, b);
|
||||
if (ret != XZ_STREAM_END)
|
||||
@@ -810,6 +813,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
||||
|
||||
s->sequence = SEQ_BLOCK_CHECK;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case SEQ_BLOCK_CHECK:
|
||||
ret = hash_validate(s, b, 0);
|
||||
if (ret != XZ_STREAM_END)
|
||||
@@ -858,6 +862,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
||||
|
||||
s->sequence = SEQ_INDEX_CRC32;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case SEQ_INDEX_CRC32:
|
||||
ret = hash_validate(s, b, 1);
|
||||
if (ret != XZ_STREAM_END)
|
||||
@@ -866,6 +871,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
||||
s->temp.size = STREAM_HEADER_SIZE;
|
||||
s->sequence = SEQ_STREAM_FOOTER;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case SEQ_STREAM_FOOTER:
|
||||
if (!fill_temp(s, b))
|
||||
return XZ_OK;
|
||||
|
||||
@@ -28,28 +28,6 @@
|
||||
static void *loaded_fdt;
|
||||
static void *fdt;
|
||||
|
||||
static void *
|
||||
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;
|
||||
}
|
||||
|
||||
void *
|
||||
grub_fdt_load (grub_size_t additional_size)
|
||||
{
|
||||
@@ -65,7 +43,7 @@ grub_fdt_load (grub_size_t additional_size)
|
||||
if (loaded_fdt)
|
||||
raw_fdt = loaded_fdt;
|
||||
else
|
||||
raw_fdt = get_firmware_fdt();
|
||||
raw_fdt = grub_efi_get_firmware_fdt();
|
||||
|
||||
size =
|
||||
raw_fdt ? grub_fdt_get_totalsize (raw_fdt) : GRUB_FDT_EMPTY_TREE_SZ;
|
||||
|
||||
@@ -37,16 +37,6 @@
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define XEN_HYPERVISOR_NAME "xen_hypervisor"
|
||||
|
||||
#define MODULE_DEFAULT_ALIGN (0x0)
|
||||
#define MODULE_IMAGE_MIN_ALIGN MODULE_DEFAULT_ALIGN
|
||||
#define MODULE_INITRD_MIN_ALIGN MODULE_DEFAULT_ALIGN
|
||||
#define MODULE_XSM_MIN_ALIGN MODULE_DEFAULT_ALIGN
|
||||
#define MODULE_CUSTOM_MIN_ALIGN MODULE_DEFAULT_ALIGN
|
||||
|
||||
#define MODULE_IMAGE_COMPATIBLE "multiboot,kernel\0multiboot,module"
|
||||
#define MODULE_INITRD_COMPATIBLE "multiboot,ramdisk\0multiboot,module"
|
||||
#define MODULE_XSM_COMPATIBLE "xen,xsm-policy\0multiboot,module"
|
||||
#define MODULE_CUSTOM_COMPATIBLE "multiboot,module"
|
||||
|
||||
/* This maximum size is defined in Power.org ePAPR V1.1
|
||||
@@ -74,14 +64,6 @@ enum module_type
|
||||
};
|
||||
typedef enum module_type module_type_t;
|
||||
|
||||
struct fdt_node_info
|
||||
{
|
||||
module_type_t type;
|
||||
|
||||
const char *compat_string;
|
||||
grub_size_t compat_string_size;
|
||||
};
|
||||
|
||||
struct xen_hypervisor_header
|
||||
{
|
||||
struct grub_arm64_linux_kernel_header efi_head;
|
||||
@@ -98,7 +80,7 @@ struct xen_boot_binary
|
||||
{
|
||||
struct xen_boot_binary *next;
|
||||
struct xen_boot_binary **prev;
|
||||
const char *name;
|
||||
int is_hypervisor;
|
||||
|
||||
grub_addr_t start;
|
||||
grub_size_t size;
|
||||
@@ -106,8 +88,6 @@ struct xen_boot_binary
|
||||
|
||||
char *cmdline;
|
||||
int cmdline_size;
|
||||
|
||||
struct fdt_node_info node_info;
|
||||
};
|
||||
|
||||
static grub_dl_t my_mod;
|
||||
@@ -116,19 +96,6 @@ static int loaded;
|
||||
|
||||
static struct xen_boot_binary *xen_hypervisor;
|
||||
static struct xen_boot_binary *module_head;
|
||||
static const grub_size_t module_default_align[] = {
|
||||
MODULE_IMAGE_MIN_ALIGN,
|
||||
MODULE_INITRD_MIN_ALIGN,
|
||||
MODULE_XSM_MIN_ALIGN,
|
||||
MODULE_CUSTOM_MIN_ALIGN
|
||||
};
|
||||
|
||||
static const compat_string_struct_t default_compat_string[] = {
|
||||
FDT_COMPATIBLE (MODULE_IMAGE_COMPATIBLE),
|
||||
FDT_COMPATIBLE (MODULE_INITRD_COMPATIBLE),
|
||||
FDT_COMPATIBLE (MODULE_XSM_COMPATIBLE),
|
||||
FDT_COMPATIBLE (MODULE_CUSTOM_COMPATIBLE)
|
||||
};
|
||||
|
||||
static __inline grub_addr_t
|
||||
xen_boot_address_align (grub_addr_t start, grub_size_t align)
|
||||
@@ -136,20 +103,6 @@ xen_boot_address_align (grub_addr_t start, grub_size_t align)
|
||||
return (align ? (ALIGN_UP (start, align)) : start);
|
||||
}
|
||||
|
||||
/* set module type according to command name. */
|
||||
static grub_err_t
|
||||
set_module_type (grub_command_t cmd, struct xen_boot_binary *module)
|
||||
{
|
||||
if (!grub_strcmp (cmd->name, "xen_linux"))
|
||||
module->node_info.type = MODULE_IMAGE;
|
||||
else if (!grub_strcmp (cmd->name, "xen_initrd"))
|
||||
module->node_info.type = MODULE_INITRD;
|
||||
else if (!grub_strcmp (cmd->name, "xen_xsm"))
|
||||
module->node_info.type = MODULE_XSM;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
prepare_xen_hypervisor_params (void *xen_boot_fdt)
|
||||
{
|
||||
@@ -203,15 +156,11 @@ prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt)
|
||||
grub_fdt_add_subnode (xen_boot_fdt, chosen_node, module_name);
|
||||
|
||||
retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "compatible",
|
||||
module->node_info.compat_string,
|
||||
(grub_uint32_t) module->
|
||||
node_info.compat_string_size);
|
||||
MODULE_CUSTOM_COMPATIBLE, sizeof(MODULE_CUSTOM_COMPATIBLE) - 1);
|
||||
if (retval)
|
||||
return grub_error (GRUB_ERR_IO, "failed to update FDT");
|
||||
|
||||
grub_dprintf ("xen_loader", "Module %s compatible = %s size = 0x%lx\n",
|
||||
module->name, module->node_info.compat_string,
|
||||
module->node_info.compat_string_size);
|
||||
grub_dprintf ("xen_loader", "Module\n");
|
||||
|
||||
retval = grub_fdt_set_reg64 (xen_boot_fdt, module_node,
|
||||
xen_boot_address_align (module->start,
|
||||
@@ -223,7 +172,7 @@ prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt)
|
||||
if (module->cmdline && module->cmdline_size > 0)
|
||||
{
|
||||
grub_dprintf ("xen_loader",
|
||||
"Module %s cmdline : %s @ %p size:%d\n", module->name,
|
||||
"Module cmdline : %s @ %p size:%d\n",
|
||||
module->cmdline, module->cmdline, module->cmdline_size);
|
||||
|
||||
retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "bootargs",
|
||||
@@ -233,8 +182,7 @@ prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt)
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_dprintf ("xen_loader", "Module %s has not bootargs!\n",
|
||||
module->name);
|
||||
grub_dprintf ("xen_loader", "Module has no bootargs!\n");
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -251,8 +199,8 @@ finalize_params_xen_boot (void)
|
||||
additional_size += FDT_NODE_NAME_MAX_SIZE + xen_hypervisor->cmdline_size;
|
||||
FOR_LIST_ELEMENTS (module, module_head)
|
||||
{
|
||||
additional_size += 6 * FDT_NODE_NAME_MAX_SIZE + module->
|
||||
node_info.compat_string_size + module->cmdline_size;
|
||||
additional_size += 6 * FDT_NODE_NAME_MAX_SIZE + sizeof(MODULE_CUSTOM_COMPATIBLE) - 1
|
||||
+ module->cmdline_size;
|
||||
}
|
||||
|
||||
xen_boot_fdt = grub_fdt_load (additional_size);
|
||||
@@ -275,8 +223,7 @@ finalize_params_xen_boot (void)
|
||||
{
|
||||
if (module->start && module->size > 0)
|
||||
{
|
||||
grub_dprintf ("xen_loader", "Module %s @ 0x%lx size:0x%lx\n",
|
||||
module->name,
|
||||
grub_dprintf ("xen_loader", "Module @ 0x%lx size:0x%lx\n",
|
||||
xen_boot_address_align (module->start, module->align),
|
||||
module->size);
|
||||
if (prepare_xen_module_params (module, xen_boot_fdt) != GRUB_ERR_NONE)
|
||||
@@ -284,7 +231,7 @@ finalize_params_xen_boot (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_dprintf ("xen_loader", "Module info error: %s!\n", module->name);
|
||||
grub_dprintf ("xen_loader", "Module info error!\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
@@ -327,19 +274,16 @@ single_binary_unload (struct xen_boot_binary *binary)
|
||||
{
|
||||
grub_free (binary->cmdline);
|
||||
grub_dprintf ("xen_loader",
|
||||
"Module %s cmdline memory free @ %p size: %d\n",
|
||||
binary->name, binary->cmdline, binary->cmdline_size);
|
||||
"Module cmdline memory free @ %p size: %d\n",
|
||||
binary->cmdline, binary->cmdline_size);
|
||||
}
|
||||
|
||||
if (binary->node_info.type == MODULE_CUSTOM)
|
||||
grub_free ((void *) binary->node_info.compat_string);
|
||||
|
||||
if (grub_strcmp (binary->name, XEN_HYPERVISOR_NAME))
|
||||
if (!binary->is_hypervisor)
|
||||
grub_list_remove (GRUB_AS_LIST (binary));
|
||||
|
||||
grub_dprintf ("xen_loader",
|
||||
"Module %s struct memory free @ %p size: 0x%lx\n",
|
||||
binary->name, binary, sizeof (binary));
|
||||
"Module struct memory free @ %p size: 0x%lx\n",
|
||||
binary, sizeof (binary));
|
||||
grub_free (binary);
|
||||
|
||||
return;
|
||||
@@ -377,8 +321,7 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
binary->size = grub_file_size (file);
|
||||
grub_dprintf ("xen_loader", "Xen_boot %s file size: 0x%lx\n",
|
||||
binary->name, binary->size);
|
||||
grub_dprintf ("xen_loader", "Xen_boot file size: 0x%lx\n", binary->size);
|
||||
|
||||
binary->start
|
||||
= (grub_addr_t) grub_efi_allocate_pages (0,
|
||||
@@ -391,8 +334,8 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
|
||||
return;
|
||||
}
|
||||
|
||||
grub_dprintf ("xen_loader", "Xen_boot %s numpages: 0x%lx\n",
|
||||
binary->name, GRUB_EFI_BYTES_TO_PAGES (binary->size + binary->align));
|
||||
grub_dprintf ("xen_loader", "Xen_boot numpages: 0x%lx\n",
|
||||
GRUB_EFI_BYTES_TO_PAGES (binary->size + binary->align));
|
||||
|
||||
if (grub_file_read (file, (void *) xen_boot_address_align (binary->start,
|
||||
binary->align),
|
||||
@@ -416,7 +359,7 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
|
||||
grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline,
|
||||
binary->cmdline_size);
|
||||
grub_dprintf ("xen_loader",
|
||||
"Xen_boot %s cmdline @ %p %s, size: %d\n", binary->name,
|
||||
"Xen_boot cmdline @ %p %s, size: %d\n",
|
||||
binary->cmdline, binary->cmdline, binary->cmdline_size);
|
||||
}
|
||||
else
|
||||
@@ -430,7 +373,8 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[])
|
||||
grub_cmd_xen_module (grub_command_t cmd __attribute__((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
|
||||
struct xen_boot_binary *module = NULL;
|
||||
@@ -454,34 +398,10 @@ grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[])
|
||||
if (!module)
|
||||
return grub_errno;
|
||||
|
||||
/* process all the options and get module type */
|
||||
if (set_module_type (cmd, module) != GRUB_ERR_NONE)
|
||||
goto fail;
|
||||
switch (module->node_info.type)
|
||||
{
|
||||
case MODULE_IMAGE:
|
||||
case MODULE_INITRD:
|
||||
case MODULE_XSM:
|
||||
module->node_info.compat_string =
|
||||
default_compat_string[module->node_info.type].compat_string;
|
||||
module->node_info.compat_string_size =
|
||||
default_compat_string[module->node_info.type].size;
|
||||
break;
|
||||
module->is_hypervisor = 0;
|
||||
module->align = 4096;
|
||||
|
||||
case MODULE_CUSTOM:
|
||||
/* we have set the node_info in set_module_type */
|
||||
break;
|
||||
|
||||
default:
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
|
||||
}
|
||||
module->name = module->node_info.compat_string;
|
||||
module->align = module_default_align[module->node_info.type];
|
||||
|
||||
grub_dprintf ("xen_loader", "Init %s module and node info:\n"
|
||||
"compatible %s\ncompat_string_size 0x%lx\n",
|
||||
module->name, module->node_info.compat_string,
|
||||
module->node_info.compat_string_size);
|
||||
grub_dprintf ("xen_loader", "Init module and node info\n");
|
||||
|
||||
file = grub_file_open (argv[0]);
|
||||
if (!file)
|
||||
@@ -491,7 +411,7 @@ grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[])
|
||||
if (grub_errno == GRUB_ERR_NONE)
|
||||
grub_list_push (GRUB_AS_LIST_P (&module_head), GRUB_AS_LIST (module));
|
||||
|
||||
fail:
|
||||
fail:
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
if (grub_errno != GRUB_ERR_NONE)
|
||||
@@ -535,7 +455,7 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)),
|
||||
if (!xen_hypervisor)
|
||||
return grub_errno;
|
||||
|
||||
xen_hypervisor->name = XEN_HYPERVISOR_NAME;
|
||||
xen_hypervisor->is_hypervisor = 1;
|
||||
xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment;
|
||||
|
||||
xen_boot_binary_load (xen_hypervisor, file, argc, argv);
|
||||
@@ -559,29 +479,21 @@ fail:
|
||||
}
|
||||
|
||||
static grub_command_t cmd_xen_hypervisor;
|
||||
static grub_command_t cmd_xen_linux, cmd_xen_initrd, cmd_xen_xsm;
|
||||
static grub_command_t cmd_xen_module;
|
||||
|
||||
GRUB_MOD_INIT (xen_boot)
|
||||
{
|
||||
cmd_xen_hypervisor =
|
||||
grub_register_command ("xen_hypervisor", grub_cmd_xen_hypervisor, 0,
|
||||
N_("Load a xen hypervisor."));
|
||||
cmd_xen_linux =
|
||||
grub_register_command ("xen_linux", grub_cmd_xen_module, 0,
|
||||
N_("Load a xen linux kernel for dom0."));
|
||||
cmd_xen_initrd =
|
||||
grub_register_command ("xen_initrd", grub_cmd_xen_module, 0,
|
||||
N_("Load a xen initrd for dom0."));
|
||||
cmd_xen_xsm =
|
||||
grub_register_command ("xen_xsm", grub_cmd_xen_module, 0,
|
||||
N_("Load a xen security module."));
|
||||
cmd_xen_module =
|
||||
grub_register_command ("xen_module", grub_cmd_xen_module, 0,
|
||||
N_("Load a xen module."));
|
||||
my_mod = mod;
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (xen_boot)
|
||||
{
|
||||
grub_unregister_command (cmd_xen_hypervisor);
|
||||
grub_unregister_command (cmd_xen_linux);
|
||||
grub_unregister_command (cmd_xen_initrd);
|
||||
grub_unregister_command (cmd_xen_xsm);
|
||||
grub_unregister_command (cmd_xen_module);
|
||||
}
|
||||
|
||||
@@ -122,6 +122,8 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
|
||||
if (*p == '/')
|
||||
*p = '\\';
|
||||
|
||||
/* File Path is NULL terminated */
|
||||
fp->path_name[size++] = '\0';
|
||||
fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
|
||||
}
|
||||
|
||||
@@ -156,8 +158,10 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
|
||||
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
|
||||
}
|
||||
|
||||
/* File Path is NULL terminated. Allocate space for 2 extra characters */
|
||||
/* FIXME why we split path in two components? */
|
||||
file_path = grub_malloc (size
|
||||
+ ((grub_strlen (dir_start) + 1)
|
||||
+ ((grub_strlen (dir_start) + 2)
|
||||
* GRUB_MAX_UTF16_PER_UTF8
|
||||
* sizeof (grub_efi_char16_t))
|
||||
+ sizeof (grub_efi_file_path_device_path_t) * 2);
|
||||
|
||||
@@ -1889,6 +1889,10 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_err_t err;
|
||||
void *src;
|
||||
|
||||
if (! grub_loader_is_loaded ())
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("you need to load the kernel first"));
|
||||
|
||||
if (kernel_type != KERNEL_TYPE_FREEBSD)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no FreeBSD loaded");
|
||||
|
||||
@@ -1992,6 +1996,10 @@ grub_cmd_netbsd_module (grub_command_t cmd,
|
||||
{
|
||||
grub_uint32_t type;
|
||||
|
||||
if (! grub_loader_is_loaded ())
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("you need to load the kernel first"));
|
||||
|
||||
if (kernel_type != KERNEL_TYPE_NETBSD)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no NetBSD loaded");
|
||||
|
||||
@@ -2070,6 +2078,10 @@ grub_cmd_openbsd_ramdisk (grub_command_t cmd __attribute__ ((unused)),
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
if (! grub_loader_is_loaded ())
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("you need to load the kernel first"));
|
||||
|
||||
if (kernel_type != KERNEL_TYPE_OPENBSD)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "no kOpenBSD loaded");
|
||||
|
||||
|
||||
@@ -48,15 +48,15 @@ read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, char **shdr)
|
||||
if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS))
|
||||
return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic"));
|
||||
|
||||
*shdr = grub_malloc (e->e_shnum * e->e_shentsize);
|
||||
*shdr = grub_malloc ((grub_uint32_t) e->e_shnum * e->e_shentsize);
|
||||
if (! *shdr)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_seek (file, e->e_shoff) == (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_read (file, *shdr, e->e_shnum * e->e_shentsize)
|
||||
!= e->e_shnum * e->e_shentsize)
|
||||
if (grub_file_read (file, *shdr, (grub_uint32_t) e->e_shnum * e->e_shentsize)
|
||||
!= (grub_ssize_t) ((grub_uint32_t) e->e_shnum * e->e_shentsize))
|
||||
{
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
@@ -200,8 +200,8 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
||||
|
||||
if (chunk_size < sizeof (e))
|
||||
chunk_size = sizeof (e);
|
||||
chunk_size += e.e_phnum * e.e_phentsize;
|
||||
chunk_size += e.e_shnum * e.e_shentsize;
|
||||
chunk_size += (grub_uint32_t) e.e_phnum * e.e_phentsize;
|
||||
chunk_size += (grub_uint32_t) e.e_shnum * e.e_shentsize;
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
@@ -253,14 +253,14 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
||||
curload = module + sizeof (e);
|
||||
|
||||
load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_shoff,
|
||||
e.e_shnum * e.e_shentsize);
|
||||
(grub_uint32_t) e.e_shnum * e.e_shentsize);
|
||||
e.e_shoff = curload - module;
|
||||
curload += e.e_shnum * e.e_shentsize;
|
||||
curload += (grub_uint32_t) e.e_shnum * e.e_shentsize;
|
||||
|
||||
load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_phoff,
|
||||
e.e_phnum * e.e_phentsize);
|
||||
(grub_uint32_t) e.e_phnum * e.e_phentsize);
|
||||
e.e_phoff = curload - module;
|
||||
curload += e.e_phnum * e.e_phentsize;
|
||||
curload += (grub_uint32_t) e.e_phnum * e.e_phentsize;
|
||||
|
||||
*kern_end = curload;
|
||||
|
||||
@@ -462,7 +462,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||
|
||||
chunk_size = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t))
|
||||
+ ALIGN_UP (strsize, sizeof (grub_freebsd_addr_t))
|
||||
+ sizeof (e) + e.e_shnum * e.e_shentsize;
|
||||
+ sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
|
||||
|
||||
symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
|
||||
{
|
||||
@@ -498,10 +498,10 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
|
||||
s2 = (Elf_Shdr *) curload;
|
||||
grub_memcpy (curload, s, e.e_shentsize);
|
||||
if (s == symsh)
|
||||
s2->sh_offset = sizeof (e) + e.e_shnum * e.e_shentsize;
|
||||
s2->sh_offset = sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
|
||||
else if (s == strsh)
|
||||
s2->sh_offset = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t))
|
||||
+ sizeof (e) + e.e_shnum * e.e_shentsize;
|
||||
+ sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
|
||||
else
|
||||
s2->sh_offset = 0;
|
||||
s2->sh_addr = s2->sh_offset;
|
||||
|
||||
@@ -384,6 +384,7 @@ load_chewed (grub_file_t file, const char *filename)
|
||||
segment.len = 0;
|
||||
segment.offset = 0;
|
||||
segment.len = 0;
|
||||
/* Fallthrough. */
|
||||
case PAYLOAD_SEGMENT_CODE:
|
||||
case PAYLOAD_SEGMENT_DATA:
|
||||
{
|
||||
|
||||
@@ -915,8 +915,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_env_set ("gfxpayload", "text");
|
||||
grub_printf_ (N_("%s is deprecated. "
|
||||
"Use set gfxpayload=%s before "
|
||||
"linux command instead.\n"), "text",
|
||||
argv[i]);
|
||||
"linux command instead.\n"),
|
||||
argv[i], "text");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@@ -925,8 +925,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_env_set ("gfxpayload", "text");
|
||||
grub_printf_ (N_("%s is deprecated. "
|
||||
"Use set gfxpayload=%s before "
|
||||
"linux command instead.\n"), "text",
|
||||
argv[i]);
|
||||
"linux command instead.\n"),
|
||||
argv[i], "text");
|
||||
break;
|
||||
default:
|
||||
/* Ignore invalid values. */
|
||||
@@ -984,10 +984,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
{
|
||||
case 'g':
|
||||
shift += 10;
|
||||
/* FALLTHROUGH */
|
||||
case 'm':
|
||||
shift += 10;
|
||||
/* FALLTHROUGH */
|
||||
case 'k':
|
||||
shift += 10;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -70,9 +70,18 @@ load_kernel (grub_file_t file, const char *filename,
|
||||
char *buffer, struct multiboot_header *header)
|
||||
{
|
||||
grub_err_t err;
|
||||
mbi_load_data_t mld;
|
||||
|
||||
mld.file = file;
|
||||
mld.filename = filename;
|
||||
mld.buffer = buffer;
|
||||
mld.mbi_ver = 1;
|
||||
mld.relocatable = 0;
|
||||
mld.avoid_efi_boot_services = 0;
|
||||
|
||||
if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE)
|
||||
{
|
||||
err = grub_multiboot_load_elf (file, filename, buffer);
|
||||
err = grub_multiboot_load_elf (&mld);
|
||||
if (err == GRUB_ERR_NONE) {
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -121,7 +130,7 @@ load_kernel (grub_file_t file, const char *filename,
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
return grub_multiboot_load_elf (file, filename, buffer);
|
||||
return grub_multiboot_load_elf (&mld);
|
||||
}
|
||||
|
||||
static struct multiboot_header *
|
||||
|
||||
@@ -205,7 +205,7 @@ grub_cmd_truecrypt (grub_command_t cmd __attribute__ ((unused)),
|
||||
fail:
|
||||
|
||||
if (!grub_errno)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "bad truecrypt ISO");
|
||||
grub_error (GRUB_ERR_BAD_OS, "bad truecrypt ISO");
|
||||
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,12 +20,16 @@
|
||||
#include <grub/i386/linux.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
#define XZ_MAGIC "\3757zXZ\0"
|
||||
|
||||
grub_elf_t
|
||||
grub_xen_file (grub_file_t file)
|
||||
{
|
||||
grub_elf_t elf;
|
||||
struct linux_kernel_header lh;
|
||||
grub_file_t off_file;
|
||||
grub_uint32_t payload_offset, payload_length;
|
||||
grub_uint8_t magic[6];
|
||||
|
||||
elf = grub_elf_file (file, file->name);
|
||||
if (elf)
|
||||
@@ -46,20 +50,36 @@ grub_xen_file (grub_file_t file)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lh.payload_length < 4)
|
||||
payload_length = lh.payload_length;
|
||||
payload_offset = (lh.setup_sects + 1) * 512
|
||||
+ lh.payload_offset;
|
||||
|
||||
if (payload_length < sizeof (magic))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, "payload too short");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grub_dprintf ("xen", "found bzimage payload 0x%llx-0x%llx\n",
|
||||
(unsigned long long) (lh.setup_sects + 1) * 512
|
||||
+ lh.payload_offset,
|
||||
(unsigned long long) lh.payload_length - 4);
|
||||
(unsigned long long) payload_offset,
|
||||
(unsigned long long) lh.payload_length);
|
||||
|
||||
off_file = grub_file_offset_open (file, (lh.setup_sects + 1) * 512
|
||||
+ lh.payload_offset,
|
||||
lh.payload_length - 4);
|
||||
grub_file_seek (file, payload_offset);
|
||||
|
||||
if (grub_file_read (file, &magic, sizeof (magic)) != sizeof (magic))
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||
file->name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Kernel suffixes xz payload with their uncompressed size.
|
||||
Trim it. */
|
||||
if (grub_memcmp (magic, XZ_MAGIC, sizeof (XZ_MAGIC) - 1) == 0)
|
||||
payload_length -= 4;
|
||||
off_file = grub_file_offset_open (file, payload_offset,
|
||||
payload_length);
|
||||
if (!off_file)
|
||||
goto fail;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <grub/xen_file.h>
|
||||
#include <grub/misc.h>
|
||||
#include <xen/elfnote.h>
|
||||
|
||||
static grub_err_t
|
||||
parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
@@ -26,6 +27,8 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
char *buf;
|
||||
char *ptr;
|
||||
int has_paddr = 0;
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
if (grub_file_seek (elf->file, off) == (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
buf = grub_malloc (sz);
|
||||
@@ -35,7 +38,8 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
if (grub_file_read (elf->file, buf, sz) != (grub_ssize_t) sz)
|
||||
{
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
grub_free (buf);
|
||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||
elf->file->name);
|
||||
}
|
||||
@@ -123,14 +127,14 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
{
|
||||
xi->virt_base = grub_strtoull (ptr + sizeof ("VIRT_BASE=") - 1, &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
if (grub_strncmp (ptr, "VIRT_ENTRY=", sizeof ("VIRT_ENTRY=") - 1) == 0)
|
||||
{
|
||||
xi->entry_point = grub_strtoull (ptr + sizeof ("VIRT_ENTRY=") - 1, &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
if (grub_strncmp (ptr, "HYPERCALL_PAGE=", sizeof ("HYPERCALL_PAGE=") - 1) == 0)
|
||||
@@ -138,7 +142,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
xi->hypercall_page = grub_strtoull (ptr + sizeof ("HYPERCALL_PAGE=") - 1, &ptr, 16);
|
||||
xi->has_hypercall_page = 1;
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
if (grub_strncmp (ptr, "ELF_PADDR_OFFSET=", sizeof ("ELF_PADDR_OFFSET=") - 1) == 0)
|
||||
@@ -146,7 +150,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
xi->paddr_offset = grub_strtoull (ptr + sizeof ("ELF_PADDR_OFFSET=") - 1, &ptr, 16);
|
||||
has_paddr = 1;
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -154,7 +158,11 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
xi->hypercall_page = (xi->hypercall_page << 12) + xi->virt_base;
|
||||
if (!has_paddr)
|
||||
xi->paddr_offset = xi->virt_base;
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
out:
|
||||
grub_free (buf);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
@@ -196,35 +204,35 @@ parse_note (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
xi->has_note = 1;
|
||||
switch (nh->n_type)
|
||||
{
|
||||
case 1:
|
||||
case XEN_ELFNOTE_ENTRY:
|
||||
xi->entry_point = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
break;
|
||||
case 2:
|
||||
case XEN_ELFNOTE_HYPERCALL_PAGE:
|
||||
xi->hypercall_page = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
xi->has_hypercall_page = 1;
|
||||
break;
|
||||
case 3:
|
||||
case XEN_ELFNOTE_VIRT_BASE:
|
||||
xi->virt_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
break;
|
||||
case 4:
|
||||
case XEN_ELFNOTE_PADDR_OFFSET:
|
||||
xi->paddr_offset = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
break;
|
||||
case 5:
|
||||
case XEN_ELFNOTE_XEN_VERSION:
|
||||
grub_dprintf ("xen", "xenversion = `%s'\n", (char *) desc);
|
||||
break;
|
||||
case 6:
|
||||
case XEN_ELFNOTE_GUEST_OS:
|
||||
grub_dprintf ("xen", "name = `%s'\n", (char *) desc);
|
||||
break;
|
||||
case 7:
|
||||
case XEN_ELFNOTE_GUEST_VERSION:
|
||||
grub_dprintf ("xen", "version = `%s'\n", (char *) desc);
|
||||
break;
|
||||
case 8:
|
||||
case XEN_ELFNOTE_LOADER:
|
||||
if (descsz < 7
|
||||
|| grub_memcmp (desc, "generic", descsz == 7 ? 7 : 8) != 0)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid loader");
|
||||
break;
|
||||
/* PAE */
|
||||
case 9:
|
||||
case XEN_ELFNOTE_PAE_MODE:
|
||||
grub_dprintf ("xen", "pae = `%s', %d, %d\n", (char *) desc,
|
||||
xi->arch, descsz);
|
||||
if (xi->arch != GRUB_XEN_FILE_I386
|
||||
@@ -253,6 +261,13 @@ parse_note (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
descsz == 2 ? 2 : 3) == 0)
|
||||
xi->arch = GRUB_XEN_FILE_I386;
|
||||
break;
|
||||
case XEN_ELFNOTE_INIT_P2M:
|
||||
xi->p2m_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
xi->has_p2m_base = 1;
|
||||
break;
|
||||
case XEN_ELFNOTE_MOD_START_PFN:
|
||||
xi->unmapped_initrd = !!grub_le_to_cpu32(*(grub_uint32_t *) desc);
|
||||
break;
|
||||
default:
|
||||
grub_dprintf ("xen", "unknown note type %d\n", nh->n_type);
|
||||
break;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/bitmap_scale.h>
|
||||
#include <grub/cpu/io.h>
|
||||
#include <grub/random.h>
|
||||
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
@@ -338,7 +339,7 @@ grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *
|
||||
utf8 = grub_malloc (namelen * 4 + 1);
|
||||
if (!utf8)
|
||||
{
|
||||
grub_free (utf8);
|
||||
grub_free (utf16);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
@@ -577,11 +578,31 @@ static grub_err_t
|
||||
grub_cpu_xnu_fill_devicetree (grub_uint64_t *fsbfreq_out)
|
||||
{
|
||||
struct grub_xnu_devtree_key *efikey;
|
||||
struct grub_xnu_devtree_key *chosenkey;
|
||||
struct grub_xnu_devtree_key *cfgtablekey;
|
||||
struct grub_xnu_devtree_key *curval;
|
||||
struct grub_xnu_devtree_key *runtimesrvkey;
|
||||
struct grub_xnu_devtree_key *platformkey;
|
||||
unsigned i, j;
|
||||
grub_err_t err;
|
||||
|
||||
chosenkey = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
|
||||
if (! chosenkey)
|
||||
return grub_errno;
|
||||
|
||||
/* Random seed. */
|
||||
curval = grub_xnu_create_value (&(chosenkey->first_child), "random-seed");
|
||||
if (! curval)
|
||||
return grub_errno;
|
||||
curval->datasize = 64;
|
||||
curval->data = grub_malloc (curval->datasize);
|
||||
if (! curval->data)
|
||||
return grub_errno;
|
||||
/* Our random is not peer-reviewed but xnu uses this seed only for
|
||||
ASLR in kernel. */
|
||||
err = grub_crypto_get_random (curval->data, curval->datasize);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* The value "model". */
|
||||
/* FIXME: may this value be sometimes different? */
|
||||
@@ -897,6 +918,28 @@ grub_xnu_set_video (struct grub_xnu_boot_params_common *params)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
total_ram_hook (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t size,
|
||||
grub_memory_type_t type,
|
||||
void *data)
|
||||
{
|
||||
grub_uint64_t *result = data;
|
||||
|
||||
if (type != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
*result += size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_uint64_t
|
||||
get_total_ram (void)
|
||||
{
|
||||
grub_uint64_t result = 0;
|
||||
|
||||
grub_mmap_iterate (total_ram_hook, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Boot xnu. */
|
||||
grub_err_t
|
||||
grub_xnu_boot (void)
|
||||
@@ -973,6 +1016,7 @@ grub_xnu_boot (void)
|
||||
{
|
||||
bootparams_common = &bootparams->v2.common;
|
||||
bootparams->v2.fsbfreq = fsbfreq;
|
||||
bootparams->v2.ram_size = get_total_ram();
|
||||
}
|
||||
else
|
||||
bootparams_common = &bootparams->v1.common;
|
||||
@@ -1080,7 +1124,7 @@ grub_xnu_boot (void)
|
||||
bootparams_common->efi_mmap = memory_map_target;
|
||||
bootparams_common->efi_mmap_size = memory_map_size;
|
||||
bootparams_common->heap_start = grub_xnu_heap_target_start;
|
||||
bootparams_common->heap_size = grub_xnu_heap_size;
|
||||
bootparams_common->heap_size = curruntimepage * GRUB_XNU_PAGESIZE - grub_xnu_heap_target_start;
|
||||
|
||||
/* Parameters for asm helper. */
|
||||
grub_xnu_stack = bootparams_common->heap_start
|
||||
|
||||
@@ -118,6 +118,48 @@ grub_multiboot_set_video_mode (void)
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
#ifdef __x86_64__
|
||||
#define grub_relocator_efi_boot grub_relocator64_efi_boot
|
||||
#define grub_relocator_efi_state grub_relocator64_efi_state
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef grub_relocator_efi_boot
|
||||
static void
|
||||
efi_boot (struct grub_relocator *rel,
|
||||
grub_uint32_t target)
|
||||
{
|
||||
struct grub_relocator_efi_state state_efi = MULTIBOOT_EFI_INITIAL_STATE;
|
||||
|
||||
state_efi.MULTIBOOT_EFI_ENTRY_REGISTER = grub_multiboot_payload_eip;
|
||||
state_efi.MULTIBOOT_EFI_MBI_REGISTER = target;
|
||||
|
||||
grub_relocator_efi_boot (rel, state_efi);
|
||||
}
|
||||
#else
|
||||
#define grub_efi_is_finished 1
|
||||
static void
|
||||
efi_boot (struct grub_relocator *rel __attribute__ ((unused)),
|
||||
grub_uint32_t target __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
static void
|
||||
normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
|
||||
{
|
||||
grub_relocator32_boot (rel, state, 0);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
|
||||
{
|
||||
grub_relocator32_boot (rel, state);
|
||||
}
|
||||
#endif
|
||||
|
||||
static grub_err_t
|
||||
grub_multiboot_boot (void)
|
||||
{
|
||||
@@ -131,11 +173,10 @@ grub_multiboot_boot (void)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
grub_relocator32_boot (grub_multiboot_relocator, state, 0);
|
||||
#else
|
||||
grub_relocator32_boot (grub_multiboot_relocator, state);
|
||||
#endif
|
||||
if (grub_efi_is_finished)
|
||||
normal_boot (grub_multiboot_relocator, state);
|
||||
else
|
||||
efi_boot (grub_multiboot_relocator, state.MULTIBOOT_MBI_REGISTER);
|
||||
|
||||
/* Not reached. */
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -166,13 +207,12 @@ static grub_uint64_t highest_load;
|
||||
|
||||
/* Load ELF32 or ELF64. */
|
||||
grub_err_t
|
||||
grub_multiboot_load_elf (grub_file_t file, const char *filename,
|
||||
void *buffer)
|
||||
grub_multiboot_load_elf (mbi_load_data_t *mld)
|
||||
{
|
||||
if (grub_multiboot_is_elf32 (buffer))
|
||||
return grub_multiboot_load_elf32 (file, filename, buffer);
|
||||
else if (grub_multiboot_is_elf64 (buffer))
|
||||
return grub_multiboot_load_elf64 (file, filename, buffer);
|
||||
if (grub_multiboot_is_elf32 (mld->buffer))
|
||||
return grub_multiboot_load_elf32 (mld);
|
||||
else if (grub_multiboot_is_elf64 (mld->buffer))
|
||||
return grub_multiboot_load_elf64 (mld);
|
||||
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS, N_("invalid arch-dependent ELF magic"));
|
||||
}
|
||||
|
||||
@@ -51,11 +51,15 @@ CONCAT(grub_multiboot_is_elf, XX) (void *buffer)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, void *buffer)
|
||||
CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
|
||||
{
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *) mld->buffer;
|
||||
char *phdr_base;
|
||||
grub_err_t err;
|
||||
grub_relocator_chunk_t ch;
|
||||
grub_uint32_t load_offset, load_size;
|
||||
int i;
|
||||
void *source;
|
||||
|
||||
if (ehdr->e_ident[EI_MAG0] != ELFMAG0
|
||||
|| ehdr->e_ident[EI_MAG1] != ELFMAG1
|
||||
@@ -72,57 +76,89 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS, N_("this ELF file is not of the right type"));
|
||||
|
||||
/* FIXME: Should we support program headers at strange locations? */
|
||||
if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
|
||||
if (ehdr->e_phoff + (grub_uint32_t) ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
|
||||
|
||||
phdr_base = (char *) buffer + ehdr->e_phoff;
|
||||
phdr_base = (char *) mld->buffer + ehdr->e_phoff;
|
||||
#define phdr(i) ((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
|
||||
|
||||
mld->link_base_addr = ~0;
|
||||
|
||||
/* Calculate lowest and highest load address. */
|
||||
for (i = 0; i < ehdr->e_phnum; i++)
|
||||
if (phdr(i)->p_type == PT_LOAD)
|
||||
{
|
||||
mld->link_base_addr = grub_min (mld->link_base_addr, phdr(i)->p_paddr);
|
||||
highest_load = grub_max (highest_load, phdr(i)->p_paddr + phdr(i)->p_memsz);
|
||||
}
|
||||
|
||||
#ifdef MULTIBOOT_LOAD_ELF64
|
||||
if (highest_load >= 0x100000000)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "segment crosses 4 GiB border");
|
||||
#endif
|
||||
|
||||
load_size = highest_load - mld->link_base_addr;
|
||||
|
||||
if (mld->relocatable)
|
||||
{
|
||||
if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
|
||||
mld->min_addr, mld->max_addr - load_size,
|
||||
load_size, mld->align ? mld->align : 1,
|
||||
mld->preference, mld->avoid_efi_boot_services);
|
||||
}
|
||||
else
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, &ch,
|
||||
mld->link_base_addr, load_size);
|
||||
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
mld->load_base_addr = get_physical_target_address (ch);
|
||||
source = get_virtual_current_address (ch);
|
||||
|
||||
grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
|
||||
"load_size=0x%x, relocatable=%d\n", mld->link_base_addr,
|
||||
mld->load_base_addr, load_size, mld->relocatable);
|
||||
|
||||
if (mld->relocatable)
|
||||
grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
|
||||
(long) mld->align, mld->preference, mld->avoid_efi_boot_services);
|
||||
|
||||
/* Load every loadable segment in memory. */
|
||||
for (i = 0; i < ehdr->e_phnum; i++)
|
||||
{
|
||||
if (phdr(i)->p_type == PT_LOAD)
|
||||
{
|
||||
grub_err_t err;
|
||||
void *source;
|
||||
|
||||
if (phdr(i)->p_paddr + phdr(i)->p_memsz > highest_load)
|
||||
highest_load = phdr(i)->p_paddr + phdr(i)->p_memsz;
|
||||
|
||||
grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n",
|
||||
i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr);
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||
&ch, phdr(i)->p_paddr,
|
||||
phdr(i)->p_memsz);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
|
||||
return err;
|
||||
}
|
||||
source = get_virtual_current_address (ch);
|
||||
}
|
||||
load_offset = phdr(i)->p_paddr - mld->link_base_addr;
|
||||
|
||||
if (phdr(i)->p_filesz != 0)
|
||||
{
|
||||
if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
|
||||
if (grub_file_seek (mld->file, (grub_off_t) phdr(i)->p_offset)
|
||||
== (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_read (file, source, phdr(i)->p_filesz)
|
||||
if (grub_file_read (mld->file, (grub_uint8_t *) source + load_offset, phdr(i)->p_filesz)
|
||||
!= (grub_ssize_t) phdr(i)->p_filesz)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
filename);
|
||||
mld->filename);
|
||||
return grub_errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (phdr(i)->p_filesz < phdr(i)->p_memsz)
|
||||
grub_memset ((grub_uint8_t *) source + phdr(i)->p_filesz, 0,
|
||||
grub_memset ((grub_uint8_t *) source + load_offset + phdr(i)->p_filesz, 0,
|
||||
phdr(i)->p_memsz - phdr(i)->p_filesz);
|
||||
}
|
||||
}
|
||||
@@ -164,22 +200,22 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
||||
{
|
||||
grub_uint8_t *shdr, *shdrptr;
|
||||
|
||||
shdr = grub_malloc (ehdr->e_shnum * ehdr->e_shentsize);
|
||||
shdr = grub_malloc ((grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize);
|
||||
if (!shdr)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_seek (file, ehdr->e_shoff) == (grub_off_t) -1)
|
||||
if (grub_file_seek (mld->file, ehdr->e_shoff) == (grub_off_t) -1)
|
||||
{
|
||||
grub_free (shdr);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (grub_file_read (file, shdr, ehdr->e_shnum * ehdr->e_shentsize)
|
||||
if (grub_file_read (mld->file, shdr, (grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize)
|
||||
!= (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
filename);
|
||||
mld->filename);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
@@ -189,7 +225,9 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
||||
Elf_Shdr *sh = (Elf_Shdr *) shdrptr;
|
||||
void *src;
|
||||
grub_addr_t target;
|
||||
grub_err_t err;
|
||||
|
||||
if (mld->mbi_ver >= 2 && (sh->sh_type == SHT_REL || sh->sh_type == SHT_RELA))
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ELF files with relocs are not supported yet");
|
||||
|
||||
/* This section is a loaded section,
|
||||
so we don't care. */
|
||||
@@ -200,33 +238,28 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
||||
if (sh->sh_size == 0)
|
||||
continue;
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
|
||||
&ch, 0,
|
||||
(0xffffffff - sh->sh_size)
|
||||
+ 1, sh->sh_size,
|
||||
sh->sh_addralign,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||
0);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
|
||||
return err;
|
||||
}
|
||||
src = get_virtual_current_address (ch);
|
||||
target = get_physical_target_address (ch);
|
||||
}
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, 0,
|
||||
(0xffffffff - sh->sh_size) + 1,
|
||||
sh->sh_size, sh->sh_addralign,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||
mld->avoid_efi_boot_services);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
|
||||
return err;
|
||||
}
|
||||
src = get_virtual_current_address (ch);
|
||||
target = get_physical_target_address (ch);
|
||||
|
||||
if (grub_file_seek (file, sh->sh_offset) == (grub_off_t) -1)
|
||||
if (grub_file_seek (mld->file, sh->sh_offset) == (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_read (file, src, sh->sh_size)
|
||||
if (grub_file_read (mld->file, src, sh->sh_size)
|
||||
!= (grub_ssize_t) sh->sh_size)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
filename);
|
||||
mld->filename);
|
||||
return grub_errno;
|
||||
}
|
||||
sh->sh_addr = target;
|
||||
|
||||
@@ -68,6 +68,7 @@ static grub_size_t elf_sec_num, elf_sec_entsize;
|
||||
static unsigned elf_sec_shstrndx;
|
||||
static void *elf_sections;
|
||||
static int keep_bs = 0;
|
||||
static grub_uint32_t load_base_addr;
|
||||
|
||||
void
|
||||
grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
|
||||
@@ -101,36 +102,40 @@ find_header (grub_properly_aligned_t *buffer, grub_ssize_t len)
|
||||
grub_err_t
|
||||
grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
{
|
||||
grub_properly_aligned_t *buffer;
|
||||
grub_ssize_t len;
|
||||
struct multiboot_header *header;
|
||||
grub_err_t err;
|
||||
struct multiboot_header_tag *tag;
|
||||
struct multiboot_header_tag_address *addr_tag = NULL;
|
||||
int entry_specified = 0;
|
||||
grub_addr_t entry = 0;
|
||||
struct multiboot_header_tag_relocatable *rel_tag;
|
||||
int entry_specified = 0, efi_entry_specified = 0;
|
||||
grub_addr_t entry = 0, efi_entry = 0;
|
||||
grub_uint32_t console_required = 0;
|
||||
struct multiboot_header_tag_framebuffer *fbtag = NULL;
|
||||
int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
|
||||
mbi_load_data_t mld;
|
||||
|
||||
buffer = grub_malloc (MULTIBOOT_SEARCH);
|
||||
if (!buffer)
|
||||
mld.mbi_ver = 2;
|
||||
mld.relocatable = 0;
|
||||
|
||||
mld.buffer = grub_malloc (MULTIBOOT_SEARCH);
|
||||
if (!mld.buffer)
|
||||
return grub_errno;
|
||||
|
||||
len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
|
||||
len = grub_file_read (file, mld.buffer, MULTIBOOT_SEARCH);
|
||||
if (len < 32)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), filename);
|
||||
}
|
||||
|
||||
COMPILE_TIME_ASSERT (MULTIBOOT_HEADER_ALIGN % 4 == 0);
|
||||
|
||||
header = find_header (buffer, len);
|
||||
header = find_header (mld.buffer, len);
|
||||
|
||||
if (header == 0)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
|
||||
}
|
||||
|
||||
@@ -172,10 +177,13 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
case MULTIBOOT_TAG_TYPE_NETWORK:
|
||||
case MULTIBOOT_TAG_TYPE_EFI_MMAP:
|
||||
case MULTIBOOT_TAG_TYPE_EFI_BS:
|
||||
case MULTIBOOT_TAG_TYPE_EFI32_IH:
|
||||
case MULTIBOOT_TAG_TYPE_EFI64_IH:
|
||||
case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
|
||||
break;
|
||||
|
||||
default:
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS,
|
||||
"unsupported information tag: 0x%x",
|
||||
request_tag->requests[i]);
|
||||
@@ -192,6 +200,13 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64:
|
||||
#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
|
||||
efi_entry_specified = 1;
|
||||
efi_entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS:
|
||||
if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags
|
||||
& MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED))
|
||||
@@ -206,27 +221,50 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
accepted_consoles |= GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER;
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_RELOCATABLE:
|
||||
mld.relocatable = 1;
|
||||
rel_tag = (struct multiboot_header_tag_relocatable *) tag;
|
||||
mld.min_addr = rel_tag->min_addr;
|
||||
mld.max_addr = rel_tag->max_addr;
|
||||
mld.align = rel_tag->align;
|
||||
switch (rel_tag->preference)
|
||||
{
|
||||
case MULTIBOOT_LOAD_PREFERENCE_LOW:
|
||||
mld.preference = GRUB_RELOCATOR_PREFERENCE_LOW;
|
||||
break;
|
||||
|
||||
case MULTIBOOT_LOAD_PREFERENCE_HIGH:
|
||||
mld.preference = GRUB_RELOCATOR_PREFERENCE_HIGH;
|
||||
break;
|
||||
|
||||
default:
|
||||
mld.preference = GRUB_RELOCATOR_PREFERENCE_NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* GRUB always page-aligns modules. */
|
||||
case MULTIBOOT_HEADER_TAG_MODULE_ALIGN:
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_EFI_BS:
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
keep_bs = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL))
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS,
|
||||
"unsupported tag: 0x%x", tag->type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (addr_tag && !entry_specified)
|
||||
if (addr_tag && !entry_specified && !(keep_bs && efi_entry_specified))
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS,
|
||||
"load address tag without entry address tag");
|
||||
}
|
||||
@@ -235,8 +273,8 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
{
|
||||
grub_uint64_t load_addr = (addr_tag->load_addr + 1)
|
||||
? addr_tag->load_addr : (addr_tag->header_addr
|
||||
- ((char *) header - (char *) buffer));
|
||||
int offset = ((char *) header - (char *) buffer -
|
||||
- ((char *) header - (char *) mld.buffer));
|
||||
int offset = ((char *) header - (char *) mld.buffer -
|
||||
(addr_tag->header_addr - load_addr));
|
||||
int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
|
||||
addr_tag->load_end_addr - addr_tag->load_addr);
|
||||
@@ -249,27 +287,50 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
else
|
||||
code_size = load_size;
|
||||
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||
&ch, load_addr,
|
||||
code_size);
|
||||
if (mld.relocatable)
|
||||
{
|
||||
if (code_size > mld.max_addr || mld.min_addr > mld.max_addr - code_size)
|
||||
{
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
|
||||
}
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
|
||||
mld.min_addr, mld.max_addr - code_size,
|
||||
code_size, mld.align ? mld.align : 1,
|
||||
mld.preference, keep_bs);
|
||||
}
|
||||
else
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||
&ch, load_addr, code_size);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return err;
|
||||
}
|
||||
mld.link_base_addr = load_addr;
|
||||
mld.load_base_addr = get_physical_target_address (ch);
|
||||
source = get_virtual_current_address (ch);
|
||||
|
||||
grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
|
||||
"load_size=0x%lx, relocatable=%d\n", mld.link_base_addr,
|
||||
mld.load_base_addr, (long) code_size, mld.relocatable);
|
||||
|
||||
if (mld.relocatable)
|
||||
grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
|
||||
(long) mld.align, mld.preference, keep_bs);
|
||||
|
||||
if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
grub_file_read (file, source, load_size);
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
@@ -279,17 +340,41 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
}
|
||||
else
|
||||
{
|
||||
err = grub_multiboot_load_elf (file, filename, buffer);
|
||||
mld.file = file;
|
||||
mld.filename = filename;
|
||||
mld.avoid_efi_boot_services = keep_bs;
|
||||
err = grub_multiboot_load_elf (&mld);
|
||||
if (err)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry_specified)
|
||||
load_base_addr = mld.load_base_addr;
|
||||
|
||||
if (keep_bs && efi_entry_specified)
|
||||
grub_multiboot_payload_eip = efi_entry;
|
||||
else if (entry_specified)
|
||||
grub_multiboot_payload_eip = entry;
|
||||
|
||||
if (mld.relocatable)
|
||||
{
|
||||
/*
|
||||
* Both branches are mathematically equivalent. However, it looks
|
||||
* that real life (C?) is more complicated. I am trying to avoid
|
||||
* wrap around here if mld.load_base_addr < mld.link_base_addr.
|
||||
* If you look at C operator precedence then everything should work.
|
||||
* However, I am not 100% sure that a given compiler will not
|
||||
* optimize/break this stuff. So, maybe we should use signed
|
||||
* 64-bit int here.
|
||||
*/
|
||||
if (mld.load_base_addr >= mld.link_base_addr)
|
||||
grub_multiboot_payload_eip += mld.load_base_addr - mld.link_base_addr;
|
||||
else
|
||||
grub_multiboot_payload_eip -= mld.link_base_addr - mld.load_base_addr;
|
||||
}
|
||||
|
||||
if (fbtag)
|
||||
err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
|
||||
accepted_consoles,
|
||||
@@ -377,7 +462,7 @@ static grub_size_t
|
||||
grub_multiboot_get_mbi_size (void)
|
||||
{
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
if (!efi_mmap_size)
|
||||
if (!keep_bs && !efi_mmap_size)
|
||||
find_efi_mmap_size ();
|
||||
#endif
|
||||
return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
|
||||
@@ -396,13 +481,16 @@ grub_multiboot_get_mbi_size (void)
|
||||
+ grub_get_multiboot_mmap_count ()
|
||||
* sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_old_acpi)
|
||||
+ sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_load_base_addr), MULTIBOOT_TAG_ALIGN)
|
||||
+ acpiv2_size ()
|
||||
+ net_size ()
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32_ih), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi_mmap)
|
||||
+ efi_mmap_size, MULTIBOOT_TAG_ALIGN)
|
||||
#endif
|
||||
@@ -420,6 +508,7 @@ grub_fill_multiboot_mmap_iter (grub_uint64_t addr, grub_uint64_t size,
|
||||
(*mmap_entry)->addr = addr;
|
||||
(*mmap_entry)->len = size;
|
||||
(*mmap_entry)->type = type;
|
||||
(*mmap_entry)->zero = 0;
|
||||
(*mmap_entry)++;
|
||||
|
||||
return 0;
|
||||
@@ -677,6 +766,15 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||
% sizeof (grub_properly_aligned_t) == 0);
|
||||
ptrorig += (2 * sizeof (grub_uint32_t)) / sizeof (grub_properly_aligned_t);
|
||||
|
||||
{
|
||||
struct multiboot_tag_load_base_addr *tag = (struct multiboot_tag_load_base_addr *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR;
|
||||
tag->size = sizeof (struct multiboot_tag_load_base_addr);
|
||||
tag->load_base_addr = load_base_addr;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
|
||||
@@ -739,12 +837,13 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
|
||||
grub_fill_multiboot_mmap (tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
if (!keep_bs)
|
||||
{
|
||||
struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
|
||||
grub_fill_multiboot_mmap (tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_elf_sections *tag
|
||||
@@ -760,18 +859,19 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_basic_meminfo *tag
|
||||
= (struct multiboot_tag_basic_meminfo *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
|
||||
tag->size = sizeof (struct multiboot_tag_basic_meminfo);
|
||||
if (!keep_bs)
|
||||
{
|
||||
struct multiboot_tag_basic_meminfo *tag
|
||||
= (struct multiboot_tag_basic_meminfo *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
|
||||
tag->size = sizeof (struct multiboot_tag_basic_meminfo);
|
||||
|
||||
/* Convert from bytes to kilobytes. */
|
||||
tag->mem_lower = grub_mmap_get_lower () / 1024;
|
||||
tag->mem_upper = grub_mmap_get_upper () / 1024;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
/* Convert from bytes to kilobytes. */
|
||||
tag->mem_lower = grub_mmap_get_lower () / 1024;
|
||||
tag->mem_upper = grub_mmap_get_upper () / 1024;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct grub_net_network_level_interface *net;
|
||||
@@ -870,36 +970,57 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||
grub_efi_uintn_t efi_desc_size;
|
||||
grub_efi_uint32_t efi_desc_version;
|
||||
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
|
||||
if (!keep_bs)
|
||||
err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
|
||||
&efi_desc_size, &efi_desc_version);
|
||||
else
|
||||
{
|
||||
if (grub_efi_get_memory_map (&efi_mmap_size, (void *) tag->efi_mmap,
|
||||
NULL,
|
||||
&efi_desc_size, &efi_desc_version) <= 0)
|
||||
err = grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
tag->descr_size = efi_desc_size;
|
||||
tag->descr_vers = efi_desc_version;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
|
||||
&efi_desc_size, &efi_desc_version);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
tag->descr_size = efi_desc_size;
|
||||
tag->descr_vers = efi_desc_version;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
}
|
||||
|
||||
if (keep_bs)
|
||||
{
|
||||
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
|
||||
tag->size = sizeof (struct multiboot_tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
{
|
||||
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
|
||||
tag->size = sizeof (struct multiboot_tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
{
|
||||
struct multiboot_tag_efi32_ih *tag = (struct multiboot_tag_efi32_ih *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI32_IH;
|
||||
tag->size = sizeof (struct multiboot_tag_efi32_ih);
|
||||
tag->pointer = (grub_addr_t) grub_efi_image_handle;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
{
|
||||
struct multiboot_tag_efi64_ih *tag = (struct multiboot_tag_efi64_ih *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI64_IH;
|
||||
tag->size = sizeof (struct multiboot_tag_efi64_ih);
|
||||
tag->pointer = (grub_addr_t) grub_efi_image_handle;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user