Compare commits

...

344 Commits

Author SHA1 Message Date
Vladimir Serbinenko
3bf4907004 indent code coming from depthcharge and add missing acknowledgements 2017-05-08 22:21:31 +02:00
Vladimir Serbinenko
8af937d133 Fix spurious diffs with master 2017-05-08 22:16:47 +02:00
Vladimir Serbinenko
fc4b6e8b19 Merge branch 'master' into arm_coreboot 2017-05-08 22:15:39 +02:00
Vladimir Serbinenko
d11ced1e1f arm_coreboot: Support EHCI. 2017-05-08 22:15:05 +02:00
Vladimir Serbinenko
e824ec487b Merge branch 'master' into arm_coreboot 2017-05-08 22:12:00 +02:00
Vladimir Serbinenko
058df7b5a9 ehci: Split core code from PCI part.
On ARM often EHCI is present without PCI and just declared in device
tree. So splitcore from PCI part.
2017-05-08 22:10:26 +02:00
Vladimir Serbinenko
456f220e6a Merge branch 'master' into arm_coreboot 2017-05-08 22:06:47 +02:00
Vladimir Serbinenko
265292f2b0 arm_coreboot: Support DMA.
This is needed to support USB and some other busses.
2017-05-08 22:06:04 +02:00
Vladimir Serbinenko
187f78ec11 Merge branch 'master' into arm_coreboot 2017-05-08 22:01:33 +02:00
Vladimir Serbinenko
656c3b0d7f arm_coreboot: Support loading linux images. 2017-05-08 22:00:06 +02:00
Vladimir Serbinenko
3edabad8fe arm_coreboot: Support grub-mkstandalone. 2017-05-08 21:59:48 +02:00
Vladimir Serbinenko
848bed9d92 arm_coreboot: Support keyboard for vexpress. 2017-05-08 21:42:37 +02:00
Vladimir Serbinenko
216950a4ee at_keyboard: Split protocol from controller code.
On vexpress controller is different but protocol is the same, so reuse the
code.
2017-05-08 21:41:22 +02:00
Vladimir Serbinenko
0558f4cd9b fix mismerge 2017-05-08 21:31:00 +02:00
Vladimir Serbinenko
ac6b41b89f arm-coreboot: Export FDT routines.
We need to use them from modules as well.
2017-05-08 21:29:48 +02:00
Vladimir Serbinenko
80c274084d Merge branch 'master' into arm_coreboot 2017-05-08 21:27:08 +02:00
Vladimir Serbinenko
5a865b3786 arm-coreboot: Support for vexpress timer. 2017-05-08 21:26:36 +02:00
Vladimir Serbinenko
2fee7bb8de Merge branch 'master' into arm_coreboot 2017-05-08 21:21:28 +02:00
Vladimir Serbinenko
fcbb723d4b Add support for device-tree-based drivers. 2017-05-08 21:19:59 +02:00
Vladimir Serbinenko
642ff2676f fix mismerge 2017-05-08 21:08:02 +02:00
Vladimir Serbinenko
46f08fb93b Merge branch 'master' into arm_coreboot 2017-05-08 21:06:51 +02:00
Vladimir Serbinenko
24e37a8852 arm-coreboot: Start new port. 2017-05-08 20:53:28 +02:00
Vladimir Serbinenko
9808c3ef95 Rename uboot/datetime to dummy/datetime.
It's just a stub and is not UBoot-specific.
2017-05-08 19:40:14 +02:00
Vladimir Serbinenko
1daa716c70 Rename uboot/halt.c to dummy/halt.c.
It's not U-Boot specific and it's a stub.
2017-05-08 19:33:56 +02:00
Vladimir Serbinenko
461bfab7b7 coreboot: Split parts that are platform-independent.
We currently assume that coreboot is always i386, it's no longer the case,
so split i386-coreboot parts from generic coreboot code.
2017-05-08 19:10:24 +02:00
Vladimir Serbinenko
b0300c6048 Merge branch 'master' into arm_coreboot 2017-05-08 17:51:27 +02:00
Vladimir Serbinenko
d08c968514 Refactor arm-uboot code to make it genereic.
arm-coreboot startup code can be very similar to arm-uboot but current code has
U-Boot specific references. So split U-Boot part from generic part.
2017-05-08 17:47:57 +02:00
Vladimir Serbinenko
a35ac85430 mkimage: Pass layout to mkimage_generate_elfXX rather than some fields.
This allows easier extension of this function without having too long of
arguments list.
2017-05-08 17:32:15 +02:00
Vladimir Serbinenko
3e6d59d7cb Remove spurious diff with master 2017-05-08 16:47:51 +02:00
Paulo Flabiano Smorigo
d9f7de0ae3 Add Virtual LAN support.
This patch adds support for virtual LAN (VLAN) tagging. VLAN tagging allows
multiple VLANs in a bridged network to share the same physical network link
but maintain isolation:

http://en.wikipedia.org/wiki/IEEE_802.1Q

* grub-core/net/ethernet.c: Add check, get, and set vlan tag id.
* grub-core/net/drivers/ieee1275/ofnet.c: Get vlan tag id from bootargs.
* grub-core/net/arp.c: Add check.
* grub-core/net/ip.c: Likewise.
* include/grub/net/arp.h: Add vlantag attribute.
* include/grub/net/ip.h: Likewise.
2017-05-03 13:03:50 +02:00
Vladimir Serbinenko
dc6e1b5af8 strtoull: Fix behaviour on chars between '9' and 'a'.
Reported by: Aaron Miller <aaronmiller@fb.com>
2017-05-03 12:59:58 +02:00
Vladimir Serbinenko
ede6c96893 Add strtoull test. 2017-05-03 12:58:15 +02:00
Vladimir Serbinenko
a827807a13 Fix shebang for termux.
Termux doesn't have a /bin/sh. So we needto use $SHELL.
Keep /bin/sh as much as possible.
2017-05-03 12:49:31 +02:00
Vladimir Serbinenko
1073ddb120 Add termux path to dict. 2017-05-03 12:48:00 +02:00
Vladimir Serbinenko
4341f82af0 po: Use @SHELL@ rather than /bin/sh.
/bin/sh might not exist.
2017-05-03 12:46:48 +02:00
Vladimir Serbinenko
c2ea443446 Use $(SHELL) rather than /bin/sh.
/bin/sh doesn't exist under termux.
2017-05-03 12:46:38 +02:00
Vladimir Serbinenko
608bec5112 Support lseek64.
Android doesn't have 64-bit off_t, so use off64_t instead.
2017-05-03 12:24:43 +02:00
Vladimir Serbinenko
6dec3a26b3 Don't retrieve fstime when it's not useful. 2017-05-03 12:23:15 +02:00
Vladimir Serbinenko
b43b8cacc8 support busybox date.
Busybox date doesn't understand weekdays in -d input,
so strip them beforehand.
2017-05-03 12:22:05 +02:00
Vladimir Serbinenko
37865c2c4a fs-tester: make sh-compatible 2017-05-03 12:19:44 +02:00
Vladimir Serbinenko
5a0c548ba3 Remove bashisms from tests.
Those tests don't actually need bash. Just use common shebang.
2017-05-03 12:10:36 +02:00
Vladimir Serbinenko
b0bad6fd94 Bump version to 2.03 2017-05-03 11:55:52 +02:00
Vladimir Serbinenko
e54c99aaff Increase version to 2.02. 2017-04-25 16:23:16 +02:00
Vladimir Serbinenko
d454509bb8 Fix remaining cases of gcc 7 fallthrough warning.
They are all intended, so just add the relevant comment.
2017-04-12 01:42:38 +00:00
Andrei Borzenkov
007f0b407f Add gnulib-fix-gcc7-fallthrough.diff
As long as the code is not upstream, add it as explicit patch for the
case of gnulib refresh.
2017-04-04 19:37:47 +03:00
Andrei Borzenkov
4bd4a88725 i386, x86_64, ppc: fix switch fallthrough cases with GCC7
In util/getroot and efidisk slightly modify exitsing comment to mostly
retain it but still make GCC7 compliant with respect to fall through
annotation.

In grub-core/lib/xzembed/xz_dec_lzma2.c it adds same comments as
upstream.

In grub-core/tests/setjmp_tets.c declare functions as "noreturn" to
suppress GCC7 warning.

In grub-core/gnulib/regexec.c use new __attribute__, because existing
annotation is not recognized by GCC7 parser (which requires that comment
immediately precedes case statement).

Otherwise add FALLTHROUGH comment.

Closes: 50598
2017-04-04 19:23:55 +03:00
Andrei Borzenkov
6cef7f6079 btrfs: avoid "used uninitialized" error with GCC7
sblock was local and so considered new variable on every loop
iteration.

Closes: 50597
2017-04-04 19:22:32 +03:00
Andrei Borzenkov
ec4af117c6 acpi: add missing efi_call wrapper to acpi command
Fixed loading of ACPI tables on EFI (side effect was apparent memory
corruption ranging from unpredictable behavior to system reset).

Reported by Nando Eva <nando4eva@ymail.com>
2017-04-02 14:47:20 +03:00
Vladimir Serbinenko
8014b7b337 Increment version to GRUB 2.02~rc2. 2017-03-15 09:20:29 +01:00
Vladimir Serbinenko
fcea891e17 Use core2duo for bootcheck test on 64-bit EFI.
Obviously pentium2 can't run efi64.
2017-03-15 09:20:14 +01:00
Andrei Borzenkov
c42cb97f08 efi: skip iPXE block device.
iPXE adds Simple File System Protocol to loaded image handle, as side
effect it also adds Block IO protocol (according to comments, to work
around some bugs in EDK2). GRUB assumes that every device with Block IO
is disk and skips network initialization entirely. But iPXE Block IO
implementation is just a stub which always fails for every operation
so cannot be used. Attempt to detect and skip such devices.

We are using media ID which iPXE sets to "iPXE" and block IO size in
hope that no real device would announce 1B block ...

Closes: 50518
2017-03-14 04:14:36 +00:00
phcoder
bcf3c55531 xen: Fix wrong register in relocator.
This fixes chainloading of some GRUB variants.
2017-03-05 10:07:36 +01:00
Vladimir Serbinenko
fb93c75bdd video_fb: Fix blue collor if using unoptimized blitter.
when unmapping the color what matters is the mode of source, not target.
2017-02-27 01:58:50 +00:00
Vladimir Serbinenko
641bb15fa4 legacy_initrd: Strip any additional arguments to initrd. 2017-02-27 00:43:54 +00:00
Andrei Borzenkov
f34ed1f53c grub-fs-tester: improve squash4 tests
1. Make sure files are not multiple of block size. This will ensure tail packing
for squash4 and may also trigger more codes paths in other filesystems.

2. Call mksquashfs with -always-use-fragments to force tail packing.
2017-02-26 14:38:04 +03:00
Andrei Borzenkov
892dfbe113 efi: strip off final NULL from File Path in grub_efi_get_filename
UEFI 2.6 9.3.6.4 File Path Media Device Path says that Path Name is
"A NULL-terminated Path string including directory and file names".

Strip final NULL from Path Name in each File Path node when constructing
full path. To be on safe side, strip all of them.

Fixes failure chainloading grub from grub, when loaded grub truncates
image path and does not find its grub.cfg.

https://bugzilla.opensuse.org/show_bug.cgi?id=1026344

This was triggered by commit ce95549cc54b5d6f494608a7c390dba3aab4fba7;
before it we built Path Name without trailing NULL, and apparently all
other bootloaders use single File Path node, thus not exposing this bug.
2017-02-25 08:39:38 +03:00
Andrei Borzenkov
951306c509 squash4: fix handling of fragments and sparse files
1. Do not assume block list and fragment are mutually exclusive. Squash
can pack file tail as fragment (unless -no-fragments is specified); so
check read offset and read either from block list or from fragments as
appropriate.

2. Support sparse files with zero blocks.

3. Fix fragment read - frag.offset is absolute fragment position,
not offset relative to ino.chunk.

Reported and tested by Carlo Caione <carlo@endlessm.com>
2017-02-24 19:10:43 +03:00
Vladimir Serbinenko
512bb31cbc Whitelist sparc64-ieee1275 as having no video modules.
ieee1275_fb is not built on sparc64 due to virtual address issues.
2017-02-22 09:55:51 +01:00
Andrei Borzenkov
2fb8cd26a9 script: fix double free in lexer
yylex_destroy() already frees scanner.

Found by: Coverity scan.
CID: 176636
2017-02-12 09:23:34 +03:00
Vladimir Serbinenko
529818738f xen: Fix parsing of XZ kernel.
In case of xz, the uncompressed size is appended to xz data which confuses
our xz decompressor. Trim it.
2017-02-07 13:25:38 +01:00
Vladimir Serbinenko
8a96fc4093 xen: Fix handling of GRUB chainloading.
In case of GRUB we put remapper after domain pages and not at 0x0.
In this case we use max_addr to put remapper. Unfortunately we increment
max_addr as well in this case resulting in virt mapping mapping page
at old max_addr and trying to boot using new max_addr.

Closes 46014.
2017-02-07 00:42:43 +01:00
Vladimir Serbinenko
f3df8f961f linguas: Don't skip ko.po.
Translation project doesn't require copyright disclaimers. They're independant
from us. They're responsible for their copyright story.
2017-02-04 00:06:57 +01:00
Vladimir Serbinenko
ec4aca088a Fix truncated checksum.h. 2017-02-03 20:17:48 +01:00
Vladimir Serbinenko
fcb1528d93 Regenerate checksums.h
Screenshots contain version, so we need new checksums.
2017-02-03 13:44:56 +01:00
Vladimir Serbinenko
c36c0e05f1 Release 2.02-rc1. 2017-02-03 13:01:34 +01:00
Vladimir Serbinenko
c96cfac167 Fix mingw compilation. 2017-02-03 13:01:34 +01:00
Daniel Kahn Gillmor
bf94ef7fbd documentation: Clarify documentation for special environment variable "default".
The current documentation for the special environment variable
"default" is confusing and unclear.  This patch attempts to clean it
up.

In particular, the current documentation refers to the "number or
title", but then in the example it gives, the menu entries and
submenus all have numbers *in* their title; furthermore, there is no
example given about how to choose the number, or any indication about
whether counting is zero-indexed or 1-indexed.

Having a cleaner example and presenting all variants (numeric, title,
and id) should make it clearer to the user.

Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
2017-02-03 12:32:25 +01:00
Vladimir Serbinenko
5412028d19 Avoid causing kernel oops in nilfs2 test.
1024-byte and 2048-byte blocks don't really work with some kernels, skip
them as we don't want any oops'es.
2017-02-03 00:34:07 +01:00
Vladimir Serbinenko
c65d35b08b btrfs: Shorten label by one character.
mkfs.btrfs imposes a slightly lower limit than would be possible in btrfs.
2017-02-03 00:30:29 +01:00
Vladimir Serbinenko
a5bd52990e grub-fs-tester: Fix mkudffs invocation.
With current invocation order of arguments is wrong and path is hardcoded.
2017-02-02 23:32:38 +01:00
Vladimir Serbinenko
1d4e3db907 grub-fs-tester: Fix fat test.
mkfs.vfat ignores -S when invoked on a disk, including loopback device,
so do an mkfs on underlying image.
2017-02-02 23:19:00 +01:00
Daniel Kiper
4e5414b2a1 i386/relocator: Align stack in grub_relocator64_efi relocator
Unified Extensible Firmware Interface Specification, Version 2.6,
section 2.3.4, x64 Platforms, boot services, says among others:
The stack must be 16-byte aligned. So, do it. Otherwise OS may
boot only by chance as it happens right now.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
2017-02-02 22:24:47 +01:00
Vladimir Serbinenko
1402cdd96a i386-ieee1275: Add missing bootcheck target. 2017-02-02 21:41:33 +01:00
Vladimir Serbinenko
31932a267c bootcheck-linux-i386: Use -cpu pentium2.
Most modern kernels are compiled for i686, so use -cpu pentium2
to avoid spurious failures.
2017-02-02 21:41:18 +01:00
Vladimir Serbinenko
393cc59195 Use -fPIC with arm64 with clang.
Currently it doesn't work either way but with -fPIC it should work once
clang bug is fixed.
2017-02-02 01:24:11 +01:00
Vladimir Serbinenko
dac87d6032 INSTALL: Fix mention of thumb-clang. 2017-02-02 01:11:52 +01:00
Vladimir Serbinenko
42e24b6006 Fix thumb compilation with clang.
According to EABI only STT_FUNC has convention of lowest bit indicating
execution mode. R_THM_{JUMP,CALL}* relocations are assumed to be pointing
to thumb mode unless they use STT_FUNC.
2017-02-02 00:59:49 +01:00
Vladimir Serbinenko
08438d783f Add missing strtoull_test.c
It was forgotten in my local directory.
2017-02-01 21:50:17 +01:00
Vladimir Serbinenko
34fe0b5901 arm64: Add support for GOT and PCREL32 relocations. 2017-02-01 21:46:19 +01:00
Vladimir Serbinenko
377c121170 mkimage: Fix memory leak. 2017-02-01 21:21:17 +01:00
Vladimir Serbinenko
43b444e593 arm/arm64: Fix improper use of start address.
It was used instead of loading address of current section or of entire buffer.
2017-02-01 20:12:07 +01:00
Vladimir Serbinenko
ea20dd2b22 ia64: Fix iterator for relocation entries.
Don't assume relocation entry size and use sh_entsize properly.
2017-02-01 20:10:26 +01:00
Vladimir Serbinenko
3d173955f0 arm: Fix trampoline generation.
We used the wrong pointer in this case. It worked only by accident.
2017-02-01 15:58:36 +01:00
Vladimir Serbinenko
68c6cec061 Fix bootcheck-related files compilation.
We need -static as otherwise linker will set interpreter field and ld.so
is not available on our initrd's.
Strip all sections we don't need on binary tests.
2017-02-01 15:57:08 +01:00
Vladimir Serbinenko
0704e83a1b Regenerate checksum.h.
Screenshots checked.
Using unifont from http://ftp.us.debian.org/debian/pool/main/u/unifont/xfonts-unifont_7.0.06-1_all.deb.
2017-01-31 22:36:11 +01:00
Vladimir Serbinenko
f14c77f501 grub-mkfont: Remove leftover debug statement. 2017-01-31 22:32:21 +01:00
Vladimir Serbinenko
0fd9fa565b charset: Trim away RLM and LRM.
They are not visible but would otherwise end up as [LRM] or [RLM] squares
with some fonts.
2017-01-31 19:29:31 +01:00
Vladimir Serbinenko
6f5aa28bc2 gfxterm: Fix clearing of cursor.
If ascent is bigger than height - 2, then we draw over character box but then
to clear cursor we only draw over character box. So trim ascent if necessarry.
2017-01-31 18:49:37 +01:00
Vladimir Serbinenko
a134ef1ab9 ia64: Add support for R_IA64_GPREL64I.
Recent GCC generates those relocations, so we need to support them.
2017-01-31 12:39:01 +01:00
Vladimir Serbinenko
255b9e0bea grub-module-verifier: Add mips to all_video whitelist.
On MIPS video is compiled-in. So all_video is empty. Whitelist it.
2017-01-30 19:52:58 +01:00
Vladimir Serbinenko
b53f595b3e Fix -nopie/-nopie check.
We don't use lgcc_s but missing lgcc_s or another library cause test to fail.
So use -nostdlib.
We need to use -Werror to avoid warning-generated case to be accepted.
Clang uses -nopie rather than -no-pie. Check both and use whichever one works.
Additionally android clang passes -pie to the linker even though it doesn't
define __PIE__. So if compilation without no-pie logic fails add -nopie/-no-pie
even if __PIE__ is not defined.
2017-01-30 19:38:55 +01:00
Vladimir Serbinenko
6371e9c104 grub-module-verifier: Ignore all_video emptiness on xen.
It's intentional that it's empty when no video modules
are available.
2017-01-30 00:13:41 +00:00
Vladimir Serbinenko
d15f17b2a0 Support arm clang 3.8 amd later.
clang 3.8 and later doesn't support -mllvm -use-arm-movt=0
whereas older clang doesn't know -mno-movt. So use
-mno-movt whenever possible and fallback to mllvm variant.
2017-01-28 14:41:23 +00:00
Carlo Caione
a0413e2677 exfat: Support files over 4GiB
file size in grub_fat_data was 32-bit on exfat.
2017-01-27 22:10:21 +00:00
Vladimir Serbinenko
43dbf83aa2 Ensure that grub_reboot doesn't return on emu.
Use grub_fatal if longjmp fails.

grub_reboot is marked as noreturn so return would cause
a crash.
2017-01-27 20:10:23 +00:00
Vladimir Serbinenko
bec592aa87 grub-shell: skip font copying when no font is available. 2017-01-27 20:09:06 +00:00
Vladimir Serbinenko
79fc008935 Don't use -mlong-calls on arm.
We don't really need it and it's flaky and creates
bogus symbols with clang.
2017-01-27 18:48:25 +00:00
Vladimir Serbinenko
bf9c561670 configure: Disable movw/movt with clang.
Those relocations are not compatible with PE and also
not compatible with custom uboot relocator.
Disable them.
2017-01-27 18:48:23 +00:00
Vladimir Serbinenko
afa9dda37e grub-fs-tester: Delete directory once we're done. 2017-01-27 18:00:40 +00:00
Vladimir Serbinenko
cde63a3bb0 grub-fs-tester: Accomodate for slower systems.
fstime can be more different with xz squashfs.
Allow difference up to 3 seconds.
This code is ugly now but rewriting it now is not on the
table.
2017-01-27 17:58:15 +00:00
Vladimir Serbinenko
bf0e59cebf grub-fs-tester: Accomodate for testing in proot containers.
proot creates hidden files with .proot prefix and name
derived from real file name. So decrease file name length
and path depth. For some reason depth 85 also results in
undeleteable directory, so use 84 instead of 85.
2017-01-27 17:46:47 +00:00
Andrei Borzenkov
a2932fbe8a osdep/linux: handle autofs entries in /proc/self/mountinfo
These entries have placeholder for device name and so are useless for our
purpose. grub failed with something like

grub-install: error: failed to get canonical path of `systemd-1'.

When we see autofs entry, record it (to keep parent-child relationship) but
continue to look for real mount. If it is found, we process it as usual. If
only autofs entry exists, attempt to trigger mount by opening mount point
and retry. Mount point itself is then kept open to avoid timeout.

Recent systemd is by default using automount for /boot/efi so this should
become more popular problem on EFI systems.

Closes: 49942
2017-01-24 20:05:19 +03:00
Andrei Borzenkov
972765fe82 linux: fix "vga=XX deprecated" warning for text mode
Arguments were in reverse order which resulted in

text is deprecated. Use set gfxpayload=vga=0 before linux command instead.
2017-01-08 15:52:49 +03:00
Andrei Borzenkov
07662af7ae configure: fix check for sys/sysmacros.h under glibc 2.25+
glibc 2.25 still includes sys/sysmacros.h in sys/types.h but also emits
deprecation warning. So test for sys/types.h succeeds in configure but later
compilation fails because we use -Werror by default.

While this is fixed in current autoconf GIT, we really cannot force everyone
to use bleeding edge (that is not even released right now). So run test under
-Werror as well to force proper detection.

This should have no impact on autoconf 2.70+ as AC_HEADER_MAJOR in this version
simply checks for header existence.

Reported and tested by Khem Raj <raj.khem@gmail.com>
2016-12-22 22:48:25 +03:00
Michael Chang
562c406763 Fix fwpath in efi netboot
The path returned by grub_efi_net_config has already been stripped for the
directory part extracted from cached bootp packet. We should just return the
result to avoild it be stripped again.

It fixed the problem that grub.efi as NBP image always looking for grub.cfg and
platform directory in upper folder rather than current one it gets loaded while
$prefix is empty. The behavior is inconsistent with other architecture and how
we would expect empty $prefix going to be in general.

The only exception to the general rule of empty $prefix is that when loaded
from platform directory itself, the platform part is stripped thus upper folder
is used for looking up files. It meets the case for how grub-mknetdir lay out
the files under tftp root directory, but also hide away this issue to be
identified as it appears to be just works.

Also fix possible memory leak by moving grub_efi_get_filename() call after
grub_efi_net_config().
2016-12-22 22:37:32 +03:00
Andrei Borzenkov
ce95549cc5 efi: properly terminate filepath with NULL in chainloader
EFI File Path Media Device Path is defined as NULL terminated string;
but chainloader built file paths without final NULL. This caused error
with Secure Boot and Linux Foundation PreLoader on Acer with InsydeH20 BIOS.
Apparently firmware failed verification with EFI_INVALID_PARAMETER which is
considered fatal error by PreLoader.

Reported and tested by Giovanni Santini <itachi.sama.amaterasu@gmail.com>
2016-12-15 16:07:00 +03:00
Magnus Granberg
a3e9da054d configure: add check for -no-pie if the compiler default to -fPIE
When Grub is compile with gcc 6.1 that have --enable-defult-pie set.
It fail with.
-ffreestanding   -m32 -Wl,-melf_i386 -Wl,--build-id=none  -nostdlib -Wl,-N -Wl,-r,-d   -
o trig.module  trig_module-trigtables.o
grep 'MARKER' gcry_whirlpool.marker.new > gcry_whirlpool.marker; rm -f
gcry_whirlpool.marker.new
/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.0/../../../../x86_64-pc-linux-gnu/bin/ld: -r and -
shared may not be used together
collect2: error: ld returned 1 exit status
Makefile:26993: recipe for target 'trig.module' failed

Check that compiler supports -no-pie and add it to linker flags.
2016-12-14 20:44:41 +03:00
Stanislav Kholmanskikh
130234bc78 ofnet: implement the receive buffer
get_card_packet() from ofnet.c allocates a netbuff based on the device's MTU:

 nb = grub_netbuff_alloc (dev->mtu + 64 + 2);

In the case when the MTU is large, and the received packet is
relatively small, this leads to allocation of significantly more memory,
than it's required. An example could be transmission of TFTP packets
with 0x400 blksize via a network card with 0x10000 MTU.

This patch implements a per-card receive buffer in a way similar to efinet.c,
and makes get_card_packet() allocate a netbuff of the received data size.

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-12-14 14:13:34 +01:00
Stanislav Kholmanskikh
7b4c54c4ad ofnet: move the allocation of the transmit buffer into a function
In the current code search_net_devices() uses the "alloc-mem" command
from the IEEE1275 User Interface for allocation of the transmit buffer
for the case when GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN is set.

I don't have hardware where this flag is set to verify if this
workaround is still needed. However, further changes to ofnet will
require to execute this workaround one more time. Therefore, to
avoid possible duplication of code I'm moving this piece of
code into a function.

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-12-14 14:13:34 +01:00
Alexander Graf
0d2345774d efi: Move fdt helper into own file
We only support FDT files with EFI on arm and arm64 systems, not
on x86. So move the helper that finds a prepopulated FDT UUID
into its own file and only build it for architectures where it
also gets called.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-11-24 10:09:24 +01:00
Andrei Borzenkov
c9a8d037a8 NEWS updates 2016-11-22 20:51:54 +03:00
Andrei Borzenkov
f8c3af3b61 bootp: export next server IP as environment variable
Network boot autoconfiguration sets default server to next server IP
(siaddr) from BOOTP/DHCP reply, but manual configuration using net_bootp
exports only server name. Unfortunately semantic of server name is not
clearly defined. BOOTP RFC 951 defines it only for client request, and
DHCP RFC 1541 only mentions it, without any implied usage. It looks like
this field is mostly empty in server replies.

Export next server IP as net_<interface>_next_server variable. This allows
grub configuration script to set $root/$prefix based on information obtained
by net_bootp.

Reported and tested by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Cc: nikunj@linux.vnet.ibm.com

v2: change variable name to net_<interface>_next_server as discussed on the list
2016-11-22 20:43:04 +03:00
Aaro Koskinen
0af7539bd2 configure.ac: don't require build time grub-mkfont on powerpc-ieee1275
Don't require build time grub-mkfont on powerpc-ieee1275.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
2016-11-22 20:41:34 +03:00
Dirk Mueller
0d663b50b9 grub-mknetdir: Add support for ARM64 EFI 2016-11-14 19:27:13 +03:00
Joonas Lahtinen
28511b0da9 .gitignore: Add grub-core/build-grub-module-verifier
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
2016-11-12 12:07:31 +03:00
Alexander Graf
e1b099fb69 arm efi: Use fdt from firmware when available
If EFI is nice enough to pass us an FDT using configuration tables on 32bit
ARM, we should really try and make use of it.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-11-10 13:21:00 +01:00
Alexander Graf
fbca374105 arm64: Move firmware fdt search into global function
Searching for a device tree that EFI passes to us via configuration tables
is nothing architecture specific. Move it into generic code.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-11-10 13:20:56 +01:00
Corey Hickey
5f311e86d2 fix detection of non-LUKS CRYPT
grub_util_get_dm_abstraction() does a string comparison of insufficient
length. When using a UUID such as "CRYPT-PLAIN-sda6_crypt", the function
returns GRUB_DEV_ABSTRACTION_LUKS.

This results in the error:
    ./grub-probe: error: disk `cryptouuid/sda6_crypt' not found.

This appears to be a copy/paste error introduced in:
a10e7a5a89

The bug was (apparently) latent until revealed by:
3bca85b418

Signed-off-by: Corey Hickey <bugfood-c@fatooh.org>
2016-11-05 15:28:50 +03:00
Juergen Gross
0de3eeb623 xen: add capability to load p2m list outside of kernel mapping
Modern pvops linux kernels support a p2m list not covered by the
kernel mapping. This capability is flagged by an elf-note specifying
the virtual address the kernel is expecting the p2m list to be mapped
to.

In case the elf-note is set by the kernel don't place the p2m list
into the kernel mapping, but map it to the given address. This will
allow to support domains with larger memory, as the kernel mapping is
limited to 2GB and a domain with huge memory in the TB range will have
a p2m list larger than this.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:22:06 +02:00
Juergen Gross
b67a95ecad xen: modify page table construction
Modify the page table construction to allow multiple virtual regions
to be mapped. This is done as preparation for removing the p2m list
from the initial kernel mapping in order to support huge pv domains.

This allows a cleaner approach for mapping the relocator page by
using this capability.

The interface to the assembler level of the relocator has to be changed
in order to be able to process multiple page table areas.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:22:06 +02:00
Juergen Gross
5500cefccd xen: add capability to load initrd outside of initial mapping
Modern pvops linux kernels support an initrd not covered by the initial
mapping. This capability is flagged by an elf-note.

In case the elf-note is set by the kernel don't place the initrd into
the initial mapping. This will allow to load larger initrds and/or
support domains with larger memory, as the initial mapping is limited
to 2GB and it is containing the p2m list.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:22:06 +02:00
Juergen Gross
d73976fdff xen: factor out allocation of page tables into separate function
Do the allocation of page tables in a separate function. This will
allow to do the allocation at different times of the boot preparations
depending on the features the kernel is supporting.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:22:06 +02:00
Juergen Gross
1fbb2b4b39 xen: factor out allocation of special pages into separate function
Do the allocation of special pages (start info, console and xenbus
ring buffers) in a separate function. This will allow to do the
allocation at different times of the boot preparations depending on
the features the kernel is supporting.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:22:06 +02:00
Juergen Gross
c221ea06b5 xen: factor out p2m list allocation into separate function
Do the p2m list allocation of the to be loaded kernel in a separate
function. This will allow doing the p2m list allocation at different
times of the boot preparations depending on the features the kernel
is supporting.

While at this remove superfluous setting of first_p2m_pfn and
nr_p2m_frames as those are needed only in case of the p2m list not
being mapped by the initial kernel mapping.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:22:06 +02:00
Juergen Gross
72c28509fa xen: synchronize xen header
Get actual version of include/xen/xen.h from the Xen repository in
order to be able to use constants defined there.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:22:06 +02:00
Juergen Gross
7e5fcb0b34 xen: add elfnote.h to avoid using numbers instead of constants
Various features and parameters of a pv-kernel are specified via
elf notes in the kernel image. Those notes are part of the interface
between the Xen hypervisor and the kernel.

Instead of using num,bers in the code when interpreting the elf notes
make use of the header supplied by Xen for that purpose.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:21:25 +02:00
Juergen Gross
6ae55ce103 xen: reduce number of global variables in xen loader
The loader for xen paravirtualized environment is using lots of global
variables. Reduce the number by making them either local or by putting
them into a single state structure.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:17:15 +02:00
Juergen Gross
c69d1858f1 xen: avoid memleaks on error
When loading a Xen pv-kernel avoid memory leaks in case of errors.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:17:15 +02:00
Juergen Gross
4231927e44 xen: make xen loader callable multiple times
The loader for xen paravirtualized environment isn't callable multiple
times as it won't free any memory in case of failure.

Call grub_relocator_unload() as other modules do it before allocating
a new relocator or when unloading the module.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2016-10-27 16:16:54 +02:00
Daniel Kiper
a620876e3b multiboot2: Add support for relocatable images
Currently multiboot2 protocol loads image exactly at address specified in
ELF or multiboot2 header. This solution works quite well on legacy BIOS
platforms. It is possible because memory regions are placed at predictable
addresses (though I was not able to find any spec which says that it is
strong requirement, so, it looks that it is just a goodwill of hardware
designers). However, EFI platforms are more volatile. Even if required
memory regions live at specific addresses then they are sometimes simply
not free (e.g. used by boot/runtime services on Dell PowerEdge R820 and
OVMF). This means that you are not able to just set up final image
destination on build time. You have to provide method to relocate image
contents to real load address which is usually different than load address
specified in ELF and multiboot2 headers.

This patch provides all needed machinery to do self relocation in image code.
First of all GRUB2 reads min_addr (min. load addr), max_addr (max. load addr),
align (required image alignment), preference (it says which memory regions are
preferred by image, e.g. none, low, high) from multiboot_header_tag_relocatable
header tag contained in binary (at this stage load addresses from multiboot2
and/or ELF headers are ignored). Later loader tries to fulfill request (not only
that one) and if it succeeds then it informs image about real load address via
multiboot_tag_load_base_addr tag. At this stage GRUB2 role is finished. Starting
from now executable must cope with relocations itself using whole static and
dynamic knowledge provided by boot loader.

This patch does not provide functionality which could do relocations using
ELF relocation data. However, I was asked by Konrad Rzeszutek Wilk and Vladimir
'phcoder' Serbinenko to investigate that thing. It looks that relevant machinery
could be added to existing code (including this patch) without huge effort.
Additionally, ELF relocation could live in parallel with self relocation provided
by this patch. However, during research I realized that first of all we should
establish the details how ELF relocatable image should look like and how it should
be build. At least to build proper test/example files.

So, this patch just provides support for self relocatable images. If ELF file
with relocs is loaded then GRUB2 complains loudly and ignores it. Support for
such files will be added later.

This patch was tested with Xen image which uses that functionality. However, this Xen
feature is still under development and new patchset will be released in about 2-3 weeks.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
2016-10-27 15:55:16 +02:00
Daniel Kiper
f2b6c20a25 multiboot2: Do not pass memory maps to image if EFI boot services are enabled
If image requested EFI boot services then skip multiboot2 memory maps.
Main reason for not providing maps is because they will likely be
invalid. We do a few allocations after filling them, e.g. for relocator
needs. Usually we do not care as we would have finished boot services.
If we keep boot services then it is easier/safer to not provide maps.
However, if image needs memory maps and they are not provided by bootloader
then it should get itself just before ExitBootServices() call.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
2016-10-27 15:55:00 +02:00
Daniel Kiper
ba89c19f49 multiboot2: Add tags used to pass ImageHandle to loaded image
Add tags used to pass ImageHandle to loaded image if requested.
It is used by at least ExitBootServices() function.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
2016-10-27 15:54:46 +02:00
Daniel Kiper
9862b24121 i386/relocator: Add grub_relocator64_efi relocator
Add grub_relocator64_efi relocator. It will be used on EFI 64-bit platforms
when multiboot2 compatible image requests MULTIBOOT_TAG_TYPE_EFI_BS. Relocator
will set lower parts of %rax and %rbx accordingly to multiboot2 specification.
On the other hand processor mode, just before jumping into loaded image, will
be set accordingly to Unified Extensible Firmware Interface Specification,
Version 2.4 Errata B, section 2.3.4, x64 Platforms, boot services. This way
loaded image will be able to use EFI boot services without any issues.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
2016-10-27 15:53:43 +02:00
Sakar Arora
e563928ba4 net/ip: Fix limit_time calculation in freeing old fragments
limit_time underflows when current time is less than 90000ms.
This causes packet fragments received during this time, i.e.,
till 90000ms pass since timer init, to be rejected.

Hence, set it to 0 if its less than 90000.

Signed-off-by: Sakar Arora <Sakar.Arora@nxp.com>
2016-10-18 20:26:42 +03:00
Andrei Borzenkov
a0bf403f66 asm-tests/i386-pc: Check that movl is 5 bytes.
LLVM 3.9 now emits short form of jump instructions, but it is still using
32 bit addresses for some movl instructions. Fortunately it was caught early:

clang ... boot/i386/pc/boot.S
clang -cc1as: fatal error: error in backend: invalid .org offset '440' (at offset '441')

Add additional check to catch it during configure run and force -no-integrated-as.

Closes: 49200

More details in
  https://lists.gnu.org/archive/html/grub-devel/2015-02/msg00099.html
  https://llvm.org/bugs/show_bug.cgi?id=22662
2016-09-28 20:31:04 +03:00
Pete Batard
4e0f8f66e3 Add missing va_end() to xasprintf() in grub-emu. 2016-08-13 16:36:01 +03:00
Andrei Borzenkov
c831d2073b at_keyboard: fix numpad "0" and "." mapping
Reported for set 1 by fgndevelop <fgndevelop@posteo.org>. Apparently
set 2 was reversed too.
2016-07-27 08:33:12 +03:00
Andrei Borzenkov
52408aa946 dns: fix buffer overflow for data->addresses in recv_hook
We may get more than one response before exiting out of loop in
grub_net_dns_lookup, but buffer was allocated for the first response only,
so storing answers from subsequent replies wrote past allocated size.
We never really use more than the very first address during lookup so there
is little point in collecting all of them. Just quit early if we already have
some reply.

Code needs serious redesign to actually collect multiple answers
and select the best fit according to requested type (IPv4 or IPv6).

Reported and tested by Michael Chang <mchang@suse.com>
2016-07-26 20:38:58 +03:00
Andrei Borzenkov
58590cb2ef xfs: accept filesystem with meta_uuid
XFS V5 stores UUID in metadata and compares them with superblock UUID.
To allow changing of user-visible UUID it stores original value in new
superblock field (meta_uuid) and sets incompatible flag to indicate that
new field must be used to verify metadata. Our driver currently does not
check metadata UUID so simply accept such filesystem.

Reported-By: Marcos Mello <marcosfrm@outlook.com>
Reviewd by Jan Kara <jack@suse.cz>
2016-07-26 20:29:26 +03:00
Andrei Borzenkov
b524fa27f5 net: translate pxe prefix to tftp when checking for self-load
Commit ba218c1 missed legacy pxe and pxe: prefixes which are
translated to tftp, so comparison failed.
2016-05-03 19:23:31 +03:00
Andrei Borzenkov
e045af148a net: reset net->stall in grub_net_seek_real
If we open new connection, we need to reset stall indication, otherwise
nothing will ever be polled (low level code rely on this field being
zero when establishing connection).
2016-04-30 09:15:36 +03:00
Stefan Fritsch
13f7ead3a1 http: reset EOF indication in http_seek
Otherwise next read will stop polling too early due to stale EOF
indicator, returning incomplete data to caller.
2016-04-30 09:13:34 +03:00
Mike Gilbert
7a5b301e3a build: Use AC_HEADER_MAJOR to find device macros
Depending on the OS/libc, device macros are defined in different
headers. This change ensures we include the right one.

sys/types.h - BSD
sys/mkdev.h - Sun
sys/sysmacros.h - glibc (Linux)

glibc currently pulls sys/sysmacros.h into sys/types.h, but this may
change in a future release.

https://sourceware.org/ml/libc-alpha/2015-11/msg00253.html
2016-04-24 08:12:42 +03:00
Michael Chang
abf9beb7d6 http: fix superfluous null line in range request header
At least the apache sever is very unhappy with that extra null line and will
take more than ten seconds in responding to each range request, which slows
down a lot the entire http file transfer process or even time out.
2016-04-09 07:08:13 +03:00
Andrei Borzenkov
f4d35d49e3 configure: set -fno-pie together with -fno-PIE
OpenBSD 5.9 apparently defaults to -fpie. We use -fno-PIE when appropriate
already, but that is not enough - it does not turn off -fpie.

Actually check for -fPIE is not precise enough. __PIE__ is set for both
-fpie and -fPIE but with different values. As far as I can tell, both
options were introduced at the same time, so both should always be supported.

This fixes compilation on OpenBSD 5.9 which otherwise created insanely big
lzma_decompress.img.

Reported, suggested and tested by: Jiri B <jirib@devio.us>
2016-03-22 20:12:22 +03:00
Andrei Borzenkov
6714d7ecff bootp: check that interface is not NULL in configure_by_dhcp_ack
grub_net_add_addr may fail with OOM and we use returned interface
later without any checks.
2016-03-20 10:32:33 +03:00
Andrei Borzenkov
5b8ddf6e03 bootp: fix memory leak in grub_cmd_dhcpopt 2016-03-19 09:39:30 +03:00
Aaron Luft
76eac44af3 Remove the variable oldname which is attempting to free stack space.
Historically this variable hold previous value of filename that
had to be freed if allocated previously. Currently this branch
is entered only if filename was not allocated previously so it
became redundant. It did not cause real problems because grub_free
was not called, but code is confusing and causes compilation error
in some cases.
2016-03-15 22:04:38 +03:00
Andrei Borzenkov
ee83919e93 Makefile.util.def: add $LIBINTL to grub-macbless flags
Fixes compilation on OpenBSD 5.9.

Reported by Jiri B <jirib@devio.us>
2016-03-13 08:11:58 +03:00
Robert Marshall
3c3e96d044 Failed config now returns exit code (#1252311)
Grub would notify the user if the new config was invalid, however, it
did not exit properly with exit code 1. Added the proper exit code.

Resolves: rhbz#1252311
2016-03-11 17:24:56 +01:00
Michael Chang
15aee573d2 xen_file: Fix invalid payload size 2016-03-11 10:26:51 +01:00
Vladimir Serbinenko
7f2a856fae multiboot2: Remove useless GRUB_PACKED
Reported by: Daniel Kiper
2016-03-10 21:16:10 +01:00
Andrei Borzenkov
9545a8fd04 20_linux_xen: fix test for GRUB_DEVICE
Same fix as in 082bc9f.
2016-03-06 08:54:19 +03:00
Mike Gilbert
082bc9f77b 10_linux: Fix grouping of tests for GRUB_DEVICE
Commit 7290bb562 causes GRUB_DISABLE_LINUX_UUID to be ignored due to
mixing of || and && operators. Add some parens to help with that.
2016-03-06 08:51:07 +03:00
Andrei Borzenkov
d017ea8ede NEWS update 2016-02-28 21:52:08 +03:00
Vladimir Serbinenko
8207874e5d Release 2.02~beta3 2016-02-28 03:07:41 +01:00
Vladimir Serbinenko
102e435d81 grub_arch_sync_dma_caches: Accept volatile address 2016-02-28 03:07:27 +01:00
Leif Lindholm
51f375d688 efidisk: Respect block_io_protocol buffer alignment
Returned from the OpenProtocol operation, the grub_efi_block_io_media
structure contains the io_align field, specifying the minimum alignment
required for buffers used in any data transfers with the device.

Make grub_efidisk_readwrite() allocate a temporary buffer, aligned to
this boundary, if the buffer passed to it does not already meet the
requirements.

Also sanity check the io_align field in grub_efidisk_open() for
power-of-two-ness and bail if invalid.
2016-02-27 13:44:59 +01:00
Vladimir Serbinenko
ca028db3d4 usbtrans: Fix memory coherence and use-after-free. 2016-02-27 13:40:52 +01:00
Vladimir Serbinenko
0f076d75d0 ehci: Fix memory coherence
This is a no-op on x86 but necessarry on ARM and may be necessarry on MIPS.
2016-02-27 13:40:52 +01:00
Vladimir Serbinenko
86ef66d977 arm-uboot: Make self-relocatable to allow loading at any address 2016-02-27 13:40:52 +01:00
Vladimir Serbinenko
5bcb7d394c Allow _start == 0 with relocatable images 2016-02-27 13:35:36 +01:00
Vladimir Serbinenko
df21fff504 Provide __bss_start and _end symbols in grub-mkimage.
For this ensure that all bss sections are merged.

We need this to correctly prelink non-PE relocatable images.
2016-02-27 13:35:36 +01:00
Vladimir Serbinenko
73a9c742fe Encapsulate image layout into a separate structure.
Currently we pass around a lot of pointer. Instead put all relevant data
into one structure.
2016-02-27 13:35:36 +01:00
Vladimir Serbinenko
dd3969e7ec mkimagexx: Split PE and generic part for relocations.
As a preparation for U-Boot relocations, split emitting PE-relocations
from parsing source ELF-relocations.
2016-02-27 13:35:36 +01:00
Vladimir Serbinenko
36212460d3 mkimage.c: Split into separate files.
util/grub-mkimagexx.c is included in a special way into mkimage.c.
Interoperation between defines makes this very tricky. Instead
just have a clean interface and compile util/grub-mkimage*.c separately
from mkimage.c
2016-02-27 13:35:36 +01:00
Vladimir Serbinenko
2ebef43cf6 bsd: Ensure that kernel is loaded before loading module.
kernel_type may be set to the type of failed kernel. This patching-up is
easier than to reflow kernel loading routines.
2016-02-27 13:35:36 +01:00
Vladimir Serbinenko
8c26dace6f cat: Don't switch terminal mode when there is nothing to highlight.
This just pollutes serial console.
2016-02-27 13:35:36 +01:00
Vladimir Serbinenko
070e190305 Use console rather than serial_efi0 on arm64-efi in tests 2016-02-27 13:35:36 +01:00
Andrei Borzenkov
109189ce01 efidisk: fix misplaced parenthesis in b00e4c2 2016-02-27 15:16:48 +03:00
Andrei Borzenkov
b00e4c2bd9 efidisk: prevent errors from diskfilter scan of removable drives
Map EFI_NO_MEDIA to GRUB_ERR_OUT_OF_RANGE that is ignored by diskfilter. This
actually matches pretty close (we obviously attempt to read outside of media)
and avoids adding more error codes.

This affects only internally initiated scans. If read/write from removable is
explicitly requested, we still return an error and text explanation is more
clear for user than generic error.

Reported and tested by Andreas Loew <Andreas.Loew@gmx.net>
2016-02-26 21:44:37 +03:00
Vladimir Serbinenko
06a3b0b214 Regenerate checksums 2016-02-26 11:37:47 +01:00
Vladimir Serbinenko
5486a4e12b Makefile: Don't delete default_payload.elf if it doesn't exist. 2016-02-26 11:14:46 +01:00
Josef Bacik
eb9f401fc1 net: fix ipv6 routing
ipv6 routing in grub2 is broken, we cannot talk to anything outside our local
network or anything that doesn't route in our global namespace.  This patch
fixes this by doing a couple of things

1) Read the router information off of the router advertisement.  If we have a
router lifetime we need to take the source address and create a route from it.

2) Changes the routing stuff slightly to allow you to specify a gateway _and_ an
interface.  Since the router advertisements come in on the link local address we
need to associate it with the global address on the card.  So when we are
processing the router advertisement, either use the SLAAC interface we create
and add the route to that interface, or loop through the global addresses we
currently have on our interface and associate it with one of those addresses.
We need to have a special case here for the default route so that it gets used,
we do this by setting the masksize to 0 to mean it encompasses all networks.
The routing code will automatically select the best route so if there is a
closer match we will use that.

With this patch I can now talk to ipv6 addresses outside of my local network.
Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
2016-02-25 22:38:52 +03:00
Vladimir Serbinenko
94c56a4c65 ieee1275: fix signed comparison 2016-02-24 18:37:22 +01:00
Andrei Borzenkov
1b782e902e search: actually skip floppy with --no-floppy
grub_device_iterate() ignores device when iterator returns 1, not 0.

Reported by Carlos E. R. <robin.listas@telefonica.net>
2016-02-23 23:17:24 +03:00
Vladimir Serbinenko
9f8f747605 usbtrans: Fix memory coherence 2016-02-23 12:07:01 +01:00
Vladimir Serbinenko
102016960d ehci: Fix memory coherence 2016-02-23 12:06:48 +01:00
Vladimir Serbinenko
07cd46627b arm: implement grub_arch_sync_dma_caches 2016-02-23 12:06:00 +01:00
Vladimir Serbinenko
9e161d1302 Make dma_caches accept volatile 2016-02-23 11:45:29 +01:00
Vladimir Serbinenko
06c92907c1 cros fix 2016-02-23 11:26:35 +01:00
Vladimir Serbinenko
74cef4ab78 cleaner 2016-02-23 10:19:26 +01:00
Vladimir Serbinenko
f4116c3a42 Decrease frame timeout 2016-02-23 10:15:05 +01:00
Vladimir Serbinenko
2d56c1b117 cleaner 2016-02-23 09:52:08 +01:00
Vladimir Serbinenko
1f72ca020d cleaner 2016-02-23 09:50:43 +01:00
Vladimir Serbinenko
3d300d7247 cleaner 2016-02-23 09:43:57 +01:00
Vladimir Serbinenko
03104c2d98 always use older cros protocol. We don't realy need new one 2016-02-23 09:42:09 +01:00
Andrei Borzenkov
15dfea842c multiboot2: zero reserved field in memory map
Documentation says, bootloader should set reserved field to zero.

Reported by Wink Saville <wink@saville.com>
2016-02-23 09:12:14 +03:00
Vladimir Serbinenko
40562ddf1e cros e0 fix 2016-02-22 21:12:50 +01:00
Vladimir Serbinenko
1ea06af1ae EHCI FDT missing file 2016-02-22 20:40:16 +01:00
Vladimir Serbinenko
054d1325e9 Improve EHCI logging
Add dprintf's on common error paths and remove some entries which are too
noisy.
2016-02-22 20:07:10 +01:00
Vladimir Serbinenko
0678b5d629 usb_keyboard: Remove useless include
This prevents non-PCI machines from having USB.
2016-02-22 20:05:54 +01:00
Vladimir Serbinenko
be4e9d20a5 Refresh before abort
This ensures that abort message is actually visible to the user.
2016-02-22 19:46:55 +01:00
Vladimir Serbinenko
df21b9363d cleaner 2016-02-22 19:44:39 +01:00
Vladimir Serbinenko
8efde40d0c cleaner 2016-02-22 19:44:09 +01:00
Vladimir Serbinenko
d624e04af1 cleaner 2016-02-22 19:39:30 +01:00
Vladimir Serbinenko
bbd85a0292 cleaner 2016-02-22 19:38:26 +01:00
Vladimir Serbinenko
4f06545767 cleaner 2016-02-22 19:37:37 +01:00
Vladimir Serbinenko
66d0e16425 cleaner 2016-02-22 19:35:46 +01:00
Vladimir Serbinenko
a98c706755 cleaner 2016-02-22 19:35:16 +01:00
Vladimir Serbinenko
95f663ec1d cleaner 2016-02-22 19:34:30 +01:00
Vladimir Serbinenko
2b2a338ad6 cleaner 2016-02-22 19:33:34 +01:00
Vladimir Serbinenko
6c9512b610 cleaner 2016-02-22 19:33:13 +01:00
Vladimir Serbinenko
f447b3d2bb Dirty cros keyboard import 2016-02-22 19:29:47 +01:00
Vladimir Serbinenko
295fe6c548 Dirty cros keyboard 2016-02-22 19:29:08 +01:00
Eric Snowberg
bc220962e3 ieee1275: prevent buffer over-read
Prevent buffer over-read in grub_machine_mmap_iterate. This was
causing phys_base from being calculated properly. This then
caused the wrong value to be placed in ramdisk_image within
struct linux_hdrs. Which prevented the ramdisk from loading on
boot.

Newer SPARC systems contain more than 8 available memory entries.

For example on a T5-8 with 2TB of memory, the memory layout could
look like this:

T5-8 Memory
reg                      00000000 30000000 0000003f b0000000
                         00000800 00000000 00000040 00000000
                         00001000 00000000 00000040 00000000
                         00001800 00000000 00000040 00000000
                         00002000 00000000 00000040 00000000
                         00002800 00000000 00000040 00000000
                         00003000 00000000 00000040 00000000
                         00003800 00000000 00000040 00000000
available                00003800 00000000 0000003f ffcae000
                         00003000 00000000 00000040 00000000
                         00002800 00000000 00000040 00000000
                         00002000 00000000 00000040 00000000
                         00001800 00000000 00000040 00000000
                         00001000 00000000 00000040 00000000
                         00000800 00000000 00000040 00000000
                         00000000 70000000 0000003f 70000000
                         00000000 6eef8000 00000000 00002000
                         00000000 30400000 00000000 3eaf6000
name                     memory

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
2016-02-22 10:01:31 +03:00
Thomas Huth
625934ec0f menu_entry: Disable cursor during update_screen()
When running grub in a VGA console of a KVM pseries guest on PowerPC,
you can see the cursor sweeping over the whole line when entering a
character in editor mode. This is visible because grub always refreshes
the whole line when entering a character in editor mode, and drawing
characters is quite a slow operation with the firmware used for the
powerpc pseries guests (SLOF).
To avoid this ugliness, the cursor should be disabled when refreshing
the screen contents during update_screen().

Signed-off-by: Thomas Huth <thuth@redhat.com>
2016-02-22 09:59:27 +03:00
Vladimir Serbinenko
9cd85f276f frequency 2016-02-22 03:34:35 +01:00
Vladimir Serbinenko
502a7c48e9 ARM caches 2016-02-22 03:34:16 +01:00
Vladimir Serbinenko
418b32f8e9 EHCI reset fix 2016-02-22 03:33:59 +01:00
Vladimir Serbinenko
98490fc328 DMA split 2016-02-22 03:33:18 +01:00
Vladimir Serbinenko
3625fdc0b9 Improve EHCI logging 2016-02-22 03:32:50 +01:00
Vladimir Serbinenko
1ec2b7758b ehci split fixup 2016-02-22 03:28:10 +01:00
Vladimir Serbinenko
f51e8d0dda coreboot 2016-02-22 03:27:39 +01:00
Vladimir Serbinenko
ee52ea80d6 Remove useless include 2016-02-22 03:25:50 +01:00
Vladimir Serbinenko
c55f74a5c5 ehci split 2016-02-22 01:08:27 +01:00
Vladimir Serbinenko
3b1bb7f3eb DTB overrides 2016-02-22 00:05:40 +01:00
Vladimir Serbinenko
0b71582111 coreboot 2016-02-21 20:28:10 +01:00
Vladimir Serbinenko
dc491ff04a fdtbus 2016-02-21 20:27:50 +01:00
Vladimir Serbinenko
192243b13e Out-of-place FDT handling 2016-02-21 20:27:28 +01:00
Vladimir Serbinenko
0f3ae7324a fdt 2016-02-21 19:48:57 +01:00
Vladimir Serbinenko
ab8770a314 pre-located image for veyron 2016-02-21 19:28:56 +01:00
Vladimir Serbinenko
f2df41cffa coreboot 2016-02-21 19:28:40 +01:00
Vladimir Serbinenko
b0227ce4b9 fdt: relax align requirement 2016-02-21 19:28:23 +01:00
Vladimir Serbinenko
f900bea454 coreboot 2016-02-21 18:59:14 +01:00
Vladimir Serbinenko
dc51ac70ee switch to layout 2016-02-21 18:47:29 +01:00
Vladimir Serbinenko
869a0bc476 coreboot 2016-02-21 18:44:55 +01:00
Vladimir Serbinenko
f9ee0c3e5d Simplify reloc 2016-02-21 18:44:18 +01:00
Vladimir Serbinenko
8af26e386c coreboot reloc 2016-02-21 18:42:35 +01:00
Vladimir Serbinenko
78e9b82d2c coreboot memory before _start 2016-02-21 18:41:39 +01:00
Vladimir Serbinenko
86139504b7 pl050 2016-02-21 01:53:44 +01:00
Vladimir Serbinenko
35c1d629f9 fdtbus 2016-02-21 01:53:07 +01:00
Vladimir Serbinenko
bacb8f911f coreboot 2016-02-21 00:05:38 +01:00
Vladimir Serbinenko
fbda565356 fdt 2016-02-21 00:05:21 +01:00
Vladimir Serbinenko
598185f806 fdtbus 2016-02-21 00:04:18 +01:00
Vladimir Serbinenko
ca2fd6c93f ps2 split 2016-02-20 18:45:42 +01:00
Vladimir Serbinenko
a29fb4722c coreboot 2016-02-20 16:26:23 +01:00
Vladimir Serbinenko
7562f4ab53 bus fdt improvements 2016-02-20 16:25:39 +01:00
Vladimir Serbinenko
c7d0aa5450 fdtbus 2016-02-20 14:30:43 +01:00
Vladimir Serbinenko
ceb68c6648 missing files 2016-02-20 14:29:01 +01:00
Vladimir Serbinenko
99291427d2 fdtlib 2016-02-20 14:28:37 +01:00
Vladimir Serbinenko
6ffee98e1b Useless fdt.lst 2016-02-20 14:22:34 +01:00
Vladimir Serbinenko
a6649f5b8e FDT lib improvements 2016-02-20 12:30:06 +01:00
Vladimir Serbinenko
c3c14cffef refresh before abort 2016-02-20 09:12:15 +01:00
Vladimir Serbinenko
84939af253 generic timer safeguard 2016-02-20 09:12:02 +01:00
Vladimir Serbinenko
ba6d40e8bb WIP2 2016-02-19 16:47:36 +01:00
Vladimir Serbinenko
2c3a054f4f WIP 2016-02-19 12:41:50 +01:00
Vladimir Serbinenko
b8eda96422 rename 2016-02-19 12:17:56 +01:00
Vladimir Serbinenko
ca3962ca7b fix relocate 2016-02-19 12:17:20 +01:00
Vladimir Serbinenko
a4f7d77f7d fs 2016-02-19 04:48:50 +01:00
Vladimir Serbinenko
5099975ace fd 2016-02-19 04:48:17 +01:00
Vladimir Serbinenko
2f98d7648e Move cbfb 2016-02-19 04:47:02 +01:00
Vladimir Serbinenko
018e382144 decouple 2016-02-19 04:31:59 +01:00
Vladimir Serbinenko
f5cba79512 Declare arm-coreboot 2016-02-19 03:24:49 +01:00
Vladimir Serbinenko
46569db585 arm-uboot: Make self-relocatable to allow loading at any address 2016-02-19 03:22:10 +01:00
Vladimir Serbinenko
575c7a6e3c Allow _start == 0 with relocatable images 2016-02-19 02:03:28 +01:00
Vladimir Serbinenko
fc489a889d Provide __bss_start and _end symbols in grub-mkimage.
For this ensure that all bss sections are merged.
2016-02-19 02:02:50 +01:00
Vladimir Serbinenko
bfb517bc3b encapsulate 2016-02-19 01:58:11 +01:00
Vladimir Serbinenko
437dba573f Remove useless ifdef 2016-02-19 01:28:16 +01:00
Vladimir Serbinenko
974ba94330 mkimagexx: Split PE and generic part. 2016-02-19 01:14:12 +01:00
Vladimir Serbinenko
963d21b76c file split 2016-02-19 01:14:12 +01:00
Vladimir Serbinenko
e3745f9087 default_payload.elf: Always rebuild and remove before build.
It's difficult to know all dependencies. Since it's manual and cheap
target anyway, simply always rebuild it.
2016-02-17 18:19:18 +01:00
Vladimir Serbinenko
01d50c2539 default_payload.elf: Include password_pbkdf2.
Withoout this module we may end up in a system where no password is
accepted.
2016-02-17 18:11:51 +01:00
Vladimir Serbinenko
8d69065f52 default_payload.elf: Add modules from $(EXTRA_PAYLOAD_MODULES).
This allows coreboot building system to add extra modules depending
on user config.
2016-02-17 18:10:31 +01:00
Vladimir Serbinenko
59ec05bcf8 mm: Avoid integer overflow. 2016-02-17 18:09:44 +01:00
Vladimir Serbinenko
fabde8324d Remove -Wno-maybe-uninitialized as it may not be present. 2016-02-17 17:58:05 +01:00
Vladimir Serbinenko
5cae910665 Fix warnings when compiling with -O3 2016-02-17 17:56:41 +01:00
Vladimir Serbinenko
25492a0f04 Add wbinvd around bios call.
Via C3 has problems with cache coherency when transitioning between the modes,
so flush it around bios calls.
2016-02-14 08:34:10 +01:00
Eric Snowberg
080a20861c OBP available region contains grub. Start at grub_phys_end.
This prevents a problem where grub was being overwritten since
grub_phys_start does not start at a zero offset within the memory
map.
2016-02-12 23:16:03 +01:00
Andreas Freimuth
f96b34224e Add Thinkpad T410s button cmos address. 2016-02-12 19:19:11 +01:00
Vladimir Serbinenko
a2ab8c2172 TODO: Remove obsolete link 2016-02-12 17:51:52 +01:00
Toomas Soome
ce01054ec3 lz4: Fix pointer overflow 2016-02-12 17:26:32 +01:00
Vladimir Serbinenko
feef882f98 grub-shell: Update 32-bit OVMF binary name. 2016-02-12 16:08:04 +01:00
Daniel Kiper
eba6db6323 relocator: Fix integer underflow. 2016-02-12 16:07:57 +01:00
Vladimir Serbinenko
6e1ace590a Change -v to -V for version of shell utils. 2016-02-12 15:46:05 +01:00
Vladimir Serbinenko
7c35f65aac xnu: Add new kernel path to autoconfig. 2016-02-12 15:42:26 +01:00
Vladimir Serbinenko
4598cafa7d arm64: Use cpu timer for timekeeping. 2016-02-12 12:43:02 +01:00
Vladimir Serbinenko
6f4189ffc1 powerpc: Trim header in tests. 2016-02-12 12:42:04 +01:00
Vladimir Serbinenko
127cfea8be default_payload: Include syslinuxcfg, all filesystems and xnu. 2016-02-12 12:41:28 +01:00
Vladimir Serbinenko
22aa31bcc3 xnu: Supply random seed.
Now we're able to load kernels up to El Capitan.
2016-02-12 12:40:10 +01:00
Vladimir Serbinenko
e72de13b9e Add RNG module. 2016-02-12 12:39:38 +01:00
Vladimir Serbinenko
342d6edb97 yylex: use grub_fatal for exit.
lexer calls yylex_fatal on fatal internal errors. yylex_fatal itself is
declared as noreturn and calls exit. Returning from noreturn function has
unpredictable consequences.
2016-02-12 12:34:54 +01:00
Vladimir Serbinenko
e5c9300191 printf: Fix and test %% behaviour in presence of subsequenbt args. 2016-02-12 12:33:41 +01:00
Vladimir Serbinenko
d9a3bfead8 Split pmtimer wait and tsc measurement from pmtimer tsc calibration. 2016-02-12 11:40:51 +01:00
Vladimir Serbinenko
1933d37371 Make grub_cpu_is_tsc_supported generally available. 2016-02-12 11:38:51 +01:00
Vladimir Serbinenko
b29638222e Make grub_acpi_find_fadt accessible generically 2016-02-12 11:35:48 +01:00
Vladimir Serbinenko
8ad190cac2 Make unaligned types public.
This simplifies code which has to handle those types.
2016-02-12 09:11:06 +01:00
Vladimir Serbinenko
281baeecd3 Fix emu compilation error on arm. 2016-02-12 09:10:08 +01:00
Vladimir Serbinenko
df4df4d887 xnu: Include relocated EFI in heap size. 2016-02-11 12:30:45 +01:00
Vladimir Serbinenko
2d425ffdd5 xnu: supply ramsize to the kernel.
Without this info recent kernels crash as they allocate no heap.
2016-02-11 11:58:28 +01:00
Andrei Borzenkov
67dba97e45 support modules without symbol table
all_video module does not have any code or data and exists solely for
.moddeps section to pull in dependencies. This makes all symbols unneeded.

While in current binutils (last released version as of this commit is 2.26)
``strip --strip-unneeded'' unintentionally adds section symbols for each
existing section, this behavior was considered a bug and changed in commit
14f2c699ddca1e2f706342dffc59a6c7e23e844c to completely strip symbol table
in this case.

Older binutils (verified with 2.17) and some other toolchains (at least
elftoolchain r3223M), both used in FreeBSD, remove symbol table in all_video
as well.

Relax run-time check and do not return error for modules without symbol table.
Add additional checks to module verifier to make sure such modules

a) have non-empty .moddeps section. Without either externally visible symbols
or .moddeps modules are completely useless and should not be built.

b) do not have any relocations.

Closes: 46986

v2: add run-time check for empty symbol table if relocations are present as
    suggested by Vladimir.
2016-02-03 20:34:55 +03:00
Andrei Borzenkov
7290bb5623 10_linux: avoid multi-device root= kernel argument
If root filesystem is multidev btrfs, do not attempt to pass all devices as
kernel root= argument. This results in splitting command line in GRUB due to
embedded newline and even if we managed to quote it, kernel does not know how
to interpret it anyway. Multidev btrfs requires user space device scanning,
so passing single device would not work too.

This still respects user settings GRUB_DISABLE_LINUX_UUID. Not sure what we
should do in this case.

Closes: 45709
2016-02-01 20:13:48 +03:00
Vladimir Serbinenko
ff84a9b868 Error out if mtools invocation fails. 2016-01-22 19:28:08 +01:00
Vladimir Serbinenko
605eecc985 arm64: Add support for relocations needed for linaro gcc 2016-01-22 19:09:37 +01:00
Vladimir Serbinenko
b6a03dfd32 efiemu: Fix compilation failure 2016-01-22 14:10:30 +01:00
Vladimir Serbinenko
5f2b285bf8 Document cpuid -p 2016-01-22 13:50:53 +01:00
Robert Elliott
ae3b83a4d4 efiemu: Handle persistent RAM and unknown possible future additions. 2016-01-22 13:32:30 +01:00
Vladimir Serbinenko
dab148891e Document expr1 expr2 syntax for test command 2016-01-22 13:27:36 +01:00
Michael Chang
64e2d139fe Restore terminal settings on grub-emu exit. 2016-01-22 11:05:32 +01:00
Vladimir Serbinenko
0edd750e50 xen_boot: Remove obsolete module type distinctions. 2016-01-22 10:18:47 +01:00
Vladimir Serbinenko
cc2ed41039 arm: Ignore qemu clock bug 2016-01-22 10:12:43 +01:00
Vladimir Serbinenko
7c6c2ad42c i386-ieee1275: Increase maximum heap size to accomodate highres graphi tests 2016-01-22 10:12:43 +01:00
Colin Watson
47e67d809c Remove pragmas related to -Wunreachable-code
-Wunreachable-code has been a no-op since GCC 4.5; GRUB hasn't been
compiled with it since 2012; and GCC 6 produces "error:
'-Wunreachable-code' is not an option that controls warnings" for these.

Fixes Debian bug #812047.
2016-01-20 15:56:55 +00:00
Colin Watson
92bbf25714 loader/bsd: Fix signed/unsigned comparison 2016-01-16 20:40:55 +00:00
Colin Watson
95440b41d3 ahci, ehci: Fix typos 2016-01-16 20:37:15 +00:00
Andrei Borzenkov
f826d914e2 grub-probe: fix memory leak
Found by: Coverity scan.
CID: 73783
2016-01-16 21:47:28 +03:00
Andrei Borzenkov
77002c65d3 tftp: fix memory leaks in open
If protocol open fails, file is immediately freed, so data was leaked.

Found by: Coverity scan.
CID: 96659
2016-01-16 21:27:57 +03:00
Andrei Borzenkov
d4561cd080 tcp: fix memory leaks
Found by: Coverity scan.
CID: 96639, 96647
2016-01-16 20:59:50 +03:00
Andrei Borzenkov
9b4256bf05 net: fix memory leaks
Found by: Coverity scan.
CID: 96638, 96648
2016-01-16 20:48:33 +03:00
Andrei Borzenkov
eefa3239c2 legacycfg: fix memory leaks and add NULL check
Memory leaks found by Coverity scan.
CID: 96642, 96645
2016-01-16 20:34:02 +03:00
Andrei Borzenkov
4f8fe948b9 loader: Unintended sign extension
CID: 96707, 96699, 96693, 96691, 96711, 96709, 96708, 96703, 96702,
96700, 96698, 96696, 96695, 96692, 96710, 96705
2016-01-15 19:18:05 +03:00
Andrei Borzenkov
b95e926788 script: fix memory leak
Found by: Coverity scan.
CID: 96637
2016-01-12 22:50:30 +03:00
Andrei Borzenkov
26533fe6bc normal: fix memory leak
Found by: Coverity scan.
CID: 96641, 96670, 96667
2016-01-12 22:40:03 +03:00
Andrei Borzenkov
29862fdc3a xnu: fix memory leak
Found by: Coverity scan.
CID: 96663
2016-01-12 21:52:51 +03:00
Andrei Borzenkov
9daf7aae8b truecrypt: fix memory leak
Found by: Coverity scan.
CID: 156611
2016-01-12 21:52:51 +03:00
Andrei Borzenkov
a4b1326f0d gfxmenu: fix memory leak
Found by: Coverity scan.
CID: 96657
2016-01-12 21:52:50 +03:00
Andrei Borzenkov
dbb0f9fa4f efiemu: fix memory leak
Found by: Coverity scan.
CID: 156610
2016-01-12 21:52:50 +03:00
Andrei Borzenkov
e9d71db53a efidisk: fix memory leak
Found by: Coverity scan.
CID: 96644
2016-01-12 21:52:50 +03:00
Andrei Borzenkov
6c35ce72ba verify: fix memory leak
Found by: Coverity scan.
CID: 96643
2016-01-12 21:52:42 +03:00
Andrei Borzenkov
f3c84fa798 password_pbkdf2: fix memory leak
Found by: Coverity scan.
CID: 96656
2016-01-12 20:53:26 +03:00
Andrei Borzenkov
5db2190f2c parttool: fix memory leak
Found by: Coverity scan.
CID: 96652
2016-01-12 20:41:44 +03:00
Andrei Borzenkov
1bff60e5aa nativedisk: fix memory leak
Based on Coverity scan.
CID: 96660

Extended to also cover other error return places.
2016-01-12 20:37:43 +03:00
Andrei Borzenkov
8fe17d91af acpi: fix memory leak
Found by: Coverity scan.
CID: 96673
2016-01-12 20:26:30 +03:00
Andrei Borzenkov
66768b99f1 grub-install: include ehci in list of native modules
This matches behavior of "nativedisk" command.

Reported and tested by Smith Henry <sh37092@gmail.com>
2016-01-10 16:08:06 +03:00
Andrei Borzenkov
962b69d950 grub-mkimage: remove redundant NULL check
Found by: Coverity scan.
CID: 73737
2016-01-10 11:51:34 +03:00
Andrei Borzenkov
528256932b net: remove dead and redundant code
server cannot be NULL at this point (we return error earlier if it is).
Also structure is zalloc'ed, so no need to explicitly initialize
members to 0.

Found by: Coverity scan.
CID: 73837
2016-01-10 11:33:13 +03:00
Andrei Borzenkov
269a522c7d hostdisk: fix device detection
Condition was apparently reversed so GRUB assumed all devices were
files. This later made it skip BLKFLSBUF ioctl on Linux which caused
various page cache coherency issues. Observed were

- failure to validate blocklist install (read content did not match
  just written)

- failure to detect Linux MD on disk after online hot addition
  (GRUB got stale superblock)

Closes: 46691
2016-01-10 10:41:04 +03:00
Andrei Borzenkov
5a5a3c6963 setup: fix NULL pointer dereference
Check return value of grub_guess_root_devices

Found by: Coverity scan.
CID: 73638, 73751
2016-01-09 21:25:22 +03:00
Andrei Borzenkov
670c43af27 mkimage: fix unintended sign extension
Found by: Coverity scan.
CID: 73691, 73717
2016-01-09 21:05:44 +03:00
Andrei Borzenkov
dc27d254f2 util/getroot: delete dead code
is_part cannot be non-zero at this point.

Found by: Coveruty scan.
CID: 73838
2016-01-09 20:54:54 +03:00
Andrei Borzenkov
31f6506c57 loader/multiboot: fix unintended sign extension
Found by: Coveruty scan.
CID: 73700, 73763
2016-01-09 19:58:51 +03:00
Andrei Borzenkov
9fecb0588e kern/elf: fix unintended sign extension
Found by: Coverity scan.
CID: 73729, 73735, 73758, 73760
2016-01-09 19:41:26 +03:00
Andrei Borzenkov
aafd205c92 xfs: fix possible inode corruption in directory scan
grub_xfs_iterate_dir did not restore first character after inline
name when match was found. Dependning on XFS format this character
could be inode number and we could return to the same node later in
find_file if processing cycled symlinks.

CID: 86724
2016-01-09 18:55:55 +03:00
Andrei Borzenkov
bd60f5a207 rescue_parser: restructure code to avoid Coverity false positive
If line contains single word, line and argv[0] are aliases, so
no NULL dereference is possible, but Coverity does not know it.
Change code to avoid ambiguity and also remove redundant call to
grub_strchr.

CID: 86725
2016-01-09 18:15:27 +03:00
Andrei Borzenkov
725548a285 grub-mklayout: check subscript bounds
Found by: Coverity scan.
CID: 73686
2016-01-09 14:13:36 +03:00
Andrei Borzenkov
d5cc487d39 grub-probe: fix memory leak
Found by: Coverity scan.
CID: 73783
2016-01-09 13:55:28 +03:00
Andrei Borzenkov
fa2af21ec8 gfxmenu: fix memory leak
Found by: Coverity scan.
CID: 73766
2016-01-09 13:55:28 +03:00
Andrei Borzenkov
0e075ac385 util/setup: fix grub_util_path_list leak
Add helper grub_util_free_path_list and use it where appropriate.

Found by: Coverity scan.
CID: 73727
2016-01-09 13:55:18 +03:00
Andrei Borzenkov
57e7f1b775 setup: fix memory leak
Found by: Coverity scan.
CID: 73680, 73715
2016-01-09 13:10:10 +03:00
Andrei Borzenkov
67d9ce82ac efiemu: check return value of grub_efiemu_write_value
Found by: Coverity scan.
CID: 73590
2016-01-09 11:36:42 +03:00
Andrei Borzenkov
12bf87466f efiemu: change code to avoid Coverity false positive
CID: 73623
2016-01-09 11:36:42 +03:00
Andrei Borzenkov
97c41e1216 efiemu: fix unintended sign extension
Found by: Coverity scan.
CID: 73883, 73637
2016-01-09 11:36:42 +03:00
Andrei Borzenkov
8ab2675ede hfs: fix memory leak
Found by: Coverity scan.
CID: 156531
2016-01-09 11:36:42 +03:00
Andrei Borzenkov
efc04d65c7 grub-module-verifier: fix unintended sign extension
Found by: Coverity scan.
CID: 156533, 156532
2016-01-09 11:36:42 +03:00
301 changed files with 8754 additions and 3411 deletions

1
.gitignore vendored
View File

@@ -246,3 +246,4 @@ build-aux/test-driver
/garbage-gen
/garbage-gen.exe
/grub-fs-tester
grub-core/build-grub-module-verifier

View File

@@ -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.

View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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/

View File

@@ -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.

View File

@@ -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

View File

@@ -86,9 +86,11 @@ CPPFLAGS_TERMINAL_LIST += '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST
CPPFLAGS_COMMAND_LIST = '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_FDT_LIST := '-Dgrub_fdtbus_register(...)=FDT_DRIVER_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \
$(CPPFLAGS_PARTTOOL_LIST) $(CPPFLAGS_PARTMAP_LIST) \
$(CPPFLAGS_TERMINAL_LIST) $(CPPFLAGS_COMMAND_LIST)
$(CPPFLAGS_TERMINAL_LIST) $(CPPFLAGS_COMMAND_LIST) \
$(CPPFLAGS_FDT_LIST)
# Define these variables to calm down automake

View File

@@ -31,7 +31,7 @@ dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables
dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are
dnl used for the target type. See INSTALL for full list of variables.
AC_INIT([GRUB],[2.02~beta2],[bug-grub@gnu.org])
AC_INIT([GRUB],[2.03],[bug-grub@gnu.org])
AC_CONFIG_AUX_DIR([build-aux])
@@ -167,6 +167,7 @@ case "$target_cpu"-"$platform" in
mipsel-fuloong) platform=loongson ;;
mipsel-loongson) ;;
arm-uboot) ;;
arm-coreboot) ;;
arm-efi) ;;
arm64-efi) ;;
*-emu) ;;
@@ -373,7 +374,10 @@ case "$host_os" in
;;
*)
AC_CHECK_SIZEOF(off_t)
test x"$ac_cv_sizeof_off_t" = x8 || AC_MSG_ERROR([Large file support is required]);;
if test x"$ac_cv_sizeof_off_t" != x8 ; then
AC_CHECK_SIZEOF(off64_t)
test x"$ac_cv_sizeof_off64_t" = x8 || AC_MSG_ERROR([Large file support is required])
fi;;
esac
if test x$USE_NLS = xno; then
@@ -388,7 +392,15 @@ fi
# Check for functions and headers.
AC_CHECK_FUNCS(posix_memalign memalign getextmntent)
AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h sys/mkdev.h limits.h)
AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h)
# glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits deprecation
# warning which causes compilation failure later with -Werror. So use -Werror here
# as well to force proper sys/sysmacros.h detection.
SAVED_CFLAGS="$CFLAGS"
CFLAGS="$HOST_CFLAGS -Werror"
AC_HEADER_MAJOR
CFLAGS="$SAVED_CFLAGS"
AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$ac_includes_default
#include <sys/param.h>
@@ -448,6 +460,16 @@ case "$build_os" in
esac
AC_SUBST(BUILD_EXEEXT)
# In some build environments like termux /bin/sh is not a valid
# shebang. Use $SHELL instead if it's executable and /bin/sh isn't
BUILD_SHEBANG=/bin/sh
for she in /bin/sh "$SHELL"; do
if test -x "$she" ; then
BUILD_SHEBANG="$she"
fi
done
AC_SUBST(BUILD_SHEBANG)
# For gnulib.
gl_INIT
@@ -1144,14 +1166,23 @@ if test "$target_cpu"-"$platform" = x86_64-efi; then
fi
if test "x$target_cpu" = xarm; then
AC_CACHE_CHECK([whether option -mlong-calls works], grub_cv_cc_mlong_calls, [
CFLAGS="$TARGET_CFLAGS -mlong-calls -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_mlong_calls=yes],
[grub_cv_cc_mlong_calls=no])
AC_CACHE_CHECK([for options to disable movt and movw], grub_cv_target_cc_mno_movt, [
grub_cv_target_cc_mno_movt=no
for cand in "-mno-movt" \
"-mllvm -arm-use-movt=0"; do
if test x"$grub_cv_target_cc_mno_movt" != xno ; then
break
fi
CFLAGS="$TARGET_CFLAGS $cand -Werror"
CPPFLAGS="$TARGET_CPPFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_target_cc_mno_movt="$cand"], [])
done
])
if test "x$grub_cv_cc_mlong_calls" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -mlong-calls"
if test x"$grub_cv_target_cc_mno_movt" != xno ; then
# A trick so that clang doesn't see it on link stage
TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_movt"
fi
AC_CACHE_CHECK([whether option -mthumb-interwork works], grub_cv_cc_mthumb_interwork, [
CFLAGS="$TARGET_CFLAGS -mthumb-interwork -Werror"
@@ -1184,13 +1215,26 @@ CFLAGS="$TARGET_CFLAGS"
# Position independent executable.
grub_CHECK_PIE
grub_CHECK_NO_PIE
grub_CHECK_NO_PIE_ONEWORD
grub_CHECK_LINK_PIE
[# Need that, because some distributions ship compilers that include
# `-fPIE' in the default specs.
# `-fPIE' or '-fpie' and '-pie' in the default specs.
if [ x"$pie_possible" = xyes ]; then
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE"
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie"
fi
if [ x"$link_nopie_needed" = xyes ] || [ x"$pie_possible" = xyes ]; then
if [ x"$nopie_possible" = xyes ]; then
TARGET_LDFLAGS="$TARGET_LDFLAGS -no-pie"
fi
if [ x"$nopie_oneword_possible" = xyes ]; then
TARGET_LDFLAGS="$TARGET_LDFLAGS -nopie"
fi
fi]
CFLAGS="$TARGET_CFLAGS"
LDFLAGS="$TARGET_LDFLAGS"
# Position independent executable.
grub_CHECK_PIC
@@ -1199,9 +1243,12 @@ grub_CHECK_PIC
# and reload $gp in every function.
# GCC implements it using symbol __gnu_local_gp in non-PIC as well.
# However with clang we need PIC for this reloading to happen.
# With arm64 we need relocations that are in some way representable in
# PE as we need to support arm64-efi. Without -fPIC clang generates
# movk's which aren't representable.
# Since default varies across dictributions use either -fPIC or -fno-PIC
# explicitly.
if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel ) && test "x$grub_cv_cc_target_clang" = xyes ; then
if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel || test x$target_cpu = xarm64 ) && test "x$grub_cv_cc_target_clang" = xyes ; then
TARGET_CFLAGS="$TARGET_CFLAGS -fPIC"
elif [ x"$pic_possible" = xyes ]; then
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC"
@@ -1554,11 +1601,11 @@ if test x"$grub_build_mkfont_excuse" = x ; then
else
enable_build_grub_mkfont=no
fi
if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then
if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then
if test x"$grub_build_mkfont_excuse" = x ; then
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports needs build-time grub-mkfont])
AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont])
else
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports needs build-time grub-mkfont ($grub_build_mkfont_excuse)])
AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont ($grub_build_mkfont_excuse)])
fi
fi
@@ -1628,11 +1675,11 @@ if test x"$enable_build_grub_mkfont" = xno ; then
FONT_SOURCE=
fi
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then
if test x"$grub_build_mkfont_excuse" = x ; then
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports need unifont])
AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont])
else
AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)])
AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)])
fi
fi
@@ -1872,6 +1919,7 @@ AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel])
AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips])
AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ])
AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot])
AM_CONDITIONAL([COND_arm_coreboot], [test x$target_cpu = xarm -a x$platform = xcoreboot])
AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi])
AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ])
AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi])

View File

@@ -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

View File

@@ -31,7 +31,8 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
"i386_xen", "x86_64_xen",
"mips_loongson", "sparc64_ieee1275",
"powerpc_ieee1275", "mips_arc", "ia64_efi",
"mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi" ]
"mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi",
"arm_coreboot"]
GROUPS = {}
@@ -44,7 +45,7 @@ GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"]
GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
GROUPS["arm"] = [ "arm_uboot", "arm_efi" ]
GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ]
GROUPS["arm64"] = [ "arm64_efi" ]
# Groups based on firmware
@@ -52,6 +53,7 @@ GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi"
GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
GROUPS["uboot"] = [ "arm_uboot" ]
GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ]
GROUPS["coreboot"] = [ "i386_coreboot", "arm_coreboot" ]
# emu is a special case so many core functionality isn't needed on this platform
GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu")
@@ -61,10 +63,10 @@ GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips",
"sparc64_ieee1275", "powerpc_ieee1275"]
GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi");
GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"]
GROUPS["usb"] = GROUPS["pci"]
GROUPS["usb"] = GROUPS["pci"] + ["arm_coreboot"]
# If gfxterm is main output console integrate it into kernel
GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot" ]
GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ]
GROUPS["videomodules"] = GRUB_PLATFORMS[:];
for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)

View File

@@ -107,11 +107,12 @@ 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
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/coreboot/lbio.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/coreboot/lbio.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
@@ -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
@@ -237,6 +239,20 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
endif
if COND_arm_coreboot
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dma.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/coreboot/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdtbus.h
endif
if COND_arm_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/efi/loader.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
@@ -276,7 +292,7 @@ BUILT_SOURCES += symlist.h
symlist.c: symlist.h gensymlist.sh
$(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) -DGRUB_SYMBOL_GENERATOR=1 symlist.h > symlist.p || (rm -f symlist.p; exit 1)
cat symlist.p | /bin/sh $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1)
cat symlist.p | $(SHELL) $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1)
rm -f symlist.p
CLEANFILES += symlist.c
BUILT_SOURCES += symlist.c
@@ -356,6 +372,16 @@ terminal.lst: $(MARKER_FILES)
platform_DATA += terminal.lst
CLEANFILES += terminal.lst
fdt.lst: $(MARKER_FILES)
(for pp in $^; do \
b=`basename $$pp .marker`; \
sed -n \
-e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \
-e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \
done) | sort -u > $@
platform_DATA += fdt.lst
CLEANFILES += fdt.lst
parttool.lst: $(MARKER_FILES)
(for pp in $^; do \
b=`basename $$pp .marker`; \

View File

@@ -90,8 +90,10 @@ 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';
arm_coreboot_ldflags = '-Wl,-r,-d';
arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
i386_pc_startup = kern/i386/pc/startup.S;
i386_efi_startup = kern/i386/efi/startup.S;
@@ -105,7 +107,8 @@ kernel = {
mips_startup = kern/mips/startup.S;
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
arm_uboot_startup = kern/arm/uboot/startup.S;
arm_uboot_startup = kern/arm/startup.S;
arm_coreboot_startup = kern/arm/startup.S;
arm_efi_startup = kern/arm/efi/startup.S;
arm64_efi_startup = kern/arm64/efi/startup.S;
@@ -149,6 +152,20 @@ kernel = {
uboot = kern/uboot/init.c;
uboot = kern/uboot/hw.c;
uboot = term/uboot/console.c;
arm_uboot = kern/arm/uboot/init.c;
arm_uboot = kern/arm/uboot/uboot.S;
arm_coreboot = kern/arm/coreboot/init.c;
arm_coreboot = kern/arm/coreboot/timer.c;
arm_coreboot = kern/arm/coreboot/coreboot.S;
arm_coreboot = lib/fdt.c;
arm_coreboot = bus/fdt.c;
arm_coreboot = term/ps2.c;
arm_coreboot = term/arm/pl050.c;
arm_coreboot = term/arm/cros.c;
arm_coreboot = term/arm/cros_ec.c;
arm_coreboot = commands/keylayouts.c;
arm_coreboot = kern/arm/coreboot/dma.c;
terminfoinkernel = term/terminfo.c;
terminfoinkernel = term/tparm.c;
@@ -164,7 +181,7 @@ kernel = {
i386_multiboot = kern/i386/coreboot/init.c;
i386_qemu = kern/i386/qemu/init.c;
i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c;
i386_coreboot = video/i386/coreboot/cbfb.c;
coreboot = video/coreboot/cbfb.c;
efi = disk/efi/efidisk.c;
efi = kern/efi/efi.c;
@@ -212,8 +229,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;
@@ -223,8 +242,10 @@ kernel = {
i386_qemu = kern/vga_init.c;
i386_qemu = kern/i386/qemu/mmap.c;
i386_coreboot = kern/i386/coreboot/mmap.c;
coreboot = kern/coreboot/mmap.c;
i386_coreboot = kern/i386/coreboot/cbtable.c;
coreboot = kern/coreboot/cbtable.c;
arm_coreboot = kern/arm/coreboot/cbtable.c;
i386_multiboot = kern/i386/multiboot_mmap.c;
@@ -236,6 +257,7 @@ kernel = {
mips_qemu_mips = term/ns8250.c;
mips_qemu_mips = term/serial.c;
mips_qemu_mips = term/at_keyboard.c;
mips_qemu_mips = term/ps2.c;
mips_qemu_mips = commands/boot.c;
mips_qemu_mips = commands/keylayouts.c;
mips_qemu_mips = term/i386/pc/vga_text.c;
@@ -251,6 +273,7 @@ kernel = {
mips_loongson = bus/pci.c;
mips_loongson = kern/mips/loongson/init.c;
mips_loongson = term/at_keyboard.c;
mips_loongson = term/ps2.c;
mips_loongson = commands/boot.c;
mips_loongson = term/serial.c;
mips_loongson = video/sm712.c;
@@ -572,7 +595,10 @@ module = {
module = {
name = ehci;
common = bus/usb/ehci.c;
arm_coreboot = bus/usb/ehci-fdt.c;
pci = bus/usb/ehci-pci.c;
enable = pci;
enable = arm_coreboot;
};
module = {
@@ -639,6 +665,7 @@ module = {
module = {
name = cbtable;
common = kern/i386/coreboot/cbtable.c;
common = kern/coreboot/cbtable.c;
enable = i386_pc;
enable = i386_efi;
enable = i386_qemu;
@@ -752,6 +779,7 @@ module = {
enable = arm_efi;
enable = arm64_efi;
enable = arm_uboot;
enable = arm_coreboot;
};
module = {
@@ -835,7 +863,8 @@ module = {
efi = lib/efi/halt.c;
ieee1275 = lib/ieee1275/halt.c;
emu = lib/emu/halt.c;
uboot = lib/uboot/halt.c;
uboot = lib/dummy/halt.c;
arm_coreboot = lib/dummy/halt.c;
};
module = {
@@ -853,6 +882,7 @@ module = {
mips_qemu_mips = lib/mips/qemu_mips/reboot.c;
xen = lib/xen/reboot.c;
uboot = lib/uboot/reboot.c;
arm_coreboot = lib/dummy/reboot.c;
common = commands/reboot.c;
};
@@ -1531,6 +1561,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;
@@ -1545,7 +1576,8 @@ module = {
name = datetime;
cmos = lib/cmos_datetime.c;
efi = lib/efi/datetime.c;
uboot = lib/uboot/datetime.c;
uboot = lib/dummy/datetime.c;
arm_coreboot = lib/dummy/datetime.c;
sparc64_ieee1275 = lib/ieee1275/datetime.c;
powerpc_ieee1275 = lib/ieee1275/datetime.c;
sparc64_ieee1275 = lib/ieee1275/cmos.c;
@@ -1685,7 +1717,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 = {
@@ -1841,6 +1898,7 @@ module = {
module = {
name = at_keyboard;
common = term/at_keyboard.c;
common = term/ps2.c;
enable = x86;
};
@@ -1933,6 +1991,11 @@ module = {
common = tests/example_functional_test.c;
};
module = {
name = strtoull_test;
common = tests/strtoull_test.c;
};
module = {
name = setjmp_test;
common = tests/setjmp_test.c;

255
grub-core/bus/fdt.c Normal file
View File

@@ -0,0 +1,255 @@
/*
* 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/fdtbus.h>
#include <grub/fdt.h>
#include <grub/term.h>
static const void *dtb;
static grub_size_t root_address_cells, root_size_cells;
/* Pointer to this symbol signals invalid mapping. */
char grub_fdtbus_invalid_mapping[1];
struct grub_fdtbus_dev
{
struct grub_fdtbus_dev *next;
struct grub_fdtbus_dev *parent;
int node;
struct grub_fdtbus_driver *driver;
};
struct grub_fdtbus_dev *devs;
struct grub_fdtbus_driver *drivers;
static int
is_compatible (struct grub_fdtbus_driver *driver,
int node)
{
grub_size_t compatible_size;
const char *compatible = grub_fdt_get_prop (dtb, node, "compatible",
&compatible_size);
const char *compatible_end = compatible + compatible_size;
while (compatible < compatible_end)
{
if (grub_strcmp (driver->compatible, compatible) == 0)
return 1;
compatible += grub_strlen (compatible) + 1;
}
return 0;
}
static void
fdtbus_scan (struct grub_fdtbus_dev *parent)
{
int node;
for (node = grub_fdt_first_node (dtb, parent ? parent->node : 0); node >= 0;
node = grub_fdt_next_node (dtb, node))
{
struct grub_fdtbus_dev *dev;
struct grub_fdtbus_driver *driver;
dev = grub_zalloc (sizeof (*dev));
if (!dev)
{
grub_print_error ();
return;
}
dev->node = node;
dev->next = devs;
dev->parent = parent;
devs = dev;
FOR_LIST_ELEMENTS(driver, drivers)
if (!dev->driver && is_compatible (driver, node))
{
if (driver->attach(dev) == GRUB_ERR_NONE)
{
dev->driver = driver;
break;
}
grub_print_error ();
}
fdtbus_scan (dev);
}
}
void
grub_fdtbus_register (struct grub_fdtbus_driver *driver)
{
struct grub_fdtbus_dev *dev;
grub_list_push (GRUB_AS_LIST_P (&drivers),
GRUB_AS_LIST (driver));
for (dev = devs; dev; dev = dev->next)
if (!dev->driver && is_compatible (driver, dev->node))
{
if (driver->attach(dev) == GRUB_ERR_NONE)
dev->driver = driver;
grub_print_error ();
}
}
void
grub_fdtbus_unregister (struct grub_fdtbus_driver *driver)
{
grub_list_remove (GRUB_AS_LIST (driver));
struct grub_fdtbus_dev *dev;
for (dev = devs; dev; dev = dev->next)
if (dev->driver == driver)
{
if (driver->detach)
driver->detach(dev);
dev->driver = 0;
}
}
void
grub_fdtbus_init (const void *dtb_in, grub_size_t size)
{
if (!dtb_in || grub_fdt_check_header (dtb_in, size) < 0)
grub_fatal ("invalid FDT");
dtb = dtb_in;
const grub_uint32_t *prop = grub_fdt_get_prop (dtb, 0, "#address-cells", 0);
if (prop)
root_address_cells = grub_be_to_cpu32 (*prop);
else
root_address_cells = 1;
prop = grub_fdt_get_prop (dtb, 0, "#size-cells", 0);
if (prop)
root_size_cells = grub_be_to_cpu32 (*prop);
else
root_size_cells = 1;
fdtbus_scan (0);
}
static int
get_address_cells (const struct grub_fdtbus_dev *dev)
{
const grub_uint32_t *prop;
if (!dev)
return root_address_cells;
prop = grub_fdt_get_prop (dtb, dev->node, "#address-cells", 0);
if (prop)
return grub_be_to_cpu32 (*prop);
return 1;
}
static int
get_size_cells (const struct grub_fdtbus_dev *dev)
{
const grub_uint32_t *prop;
if (!dev)
return root_size_cells;
prop = grub_fdt_get_prop (dtb, dev->node, "#size-cells", 0);
if (prop)
return grub_be_to_cpu32 (*prop);
return 1;
}
static grub_uint64_t
get64 (const grub_uint32_t *reg, grub_size_t cells)
{
grub_uint64_t val = 0;
if (cells >= 1)
val = grub_be_to_cpu32 (reg[cells - 1]);
if (cells >= 2)
val |= ((grub_uint64_t) grub_be_to_cpu32 (reg[cells - 2])) << 32;
return val;
}
static volatile void *
translate (const struct grub_fdtbus_dev *dev, const grub_uint32_t *reg)
{
volatile void *ret;
const grub_uint32_t *ranges;
grub_size_t ranges_size, cells_per_mapping;
grub_size_t parent_address_cells, child_address_cells, child_size_cells;
grub_size_t nmappings, i;
if (dev == 0)
{
grub_uint64_t val;
val = get64 (reg, root_address_cells);
if (sizeof (void *) == 4 && (val >> 32))
return grub_fdtbus_invalid_mapping;
return (void *) (grub_addr_t) val;
}
ranges = grub_fdt_get_prop (dtb, dev->node, "ranges", &ranges_size);
if (!ranges)
return grub_fdtbus_invalid_mapping;
if (ranges_size == 0)
return translate (dev->parent, reg);
parent_address_cells = get_address_cells (dev->parent);
child_address_cells = get_address_cells (dev);
child_size_cells = get_size_cells (dev);
cells_per_mapping = parent_address_cells + child_address_cells + child_size_cells;
nmappings = ranges_size / 4 / cells_per_mapping;
for (i = 0; i < nmappings; i++)
{
const grub_uint32_t *child_addr = &ranges[i * cells_per_mapping];
const grub_uint32_t *parent_addr = child_addr + child_address_cells;
grub_uint64_t child_size = get64 (parent_addr + parent_address_cells, child_size_cells);
if (child_address_cells > 2 && grub_memcmp (reg, child_addr, (child_address_cells - 2) * 4) != 0)
continue;
if (get64 (reg, child_address_cells) < get64 (child_addr, child_address_cells))
continue;
grub_uint64_t offset = get64 (reg, child_address_cells) - get64 (child_addr, child_address_cells);
if (offset >= child_size)
continue;
ret = translate (dev->parent, parent_addr);
if (grub_fdtbus_is_mapping_valid (ret))
ret = (volatile char *) ret + offset;
return ret;
}
return grub_fdtbus_invalid_mapping;
}
volatile void *
grub_fdtbus_map_reg (const struct grub_fdtbus_dev *dev, int regno, grub_size_t *size)
{
grub_size_t address_cells, size_cells;
address_cells = get_address_cells (dev->parent);
size_cells = get_size_cells (dev->parent);
const grub_uint32_t *reg = grub_fdt_get_prop (dtb, dev->node, "reg", 0);
if (size && size_cells)
*size = reg[(address_cells + size_cells) * regno + address_cells];
if (size && !size_cells)
*size = 0;
return translate (dev->parent, reg + (address_cells + size_cells) * regno);
}
const char *
grub_fdtbus_get_name (const struct grub_fdtbus_dev *dev)
{
return grub_fdt_get_nodename (dtb, dev->node);
}
const void *
grub_fdtbus_get_prop (const struct grub_fdtbus_dev *dev,
const char *name,
grub_uint32_t *len)
{
return grub_fdt_get_prop (dtb, dev->node, name, len);
}
const void *
grub_fdtbus_get_fdt (void)
{
return dtb;
}

View File

@@ -0,0 +1,45 @@
/* ehci.c - EHCI Support. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 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/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/usb.h>
#include <grub/fdtbus.h>
static grub_err_t
ehci_attach(const struct grub_fdtbus_dev *dev)
{
grub_dprintf ("ehci", "Found generic-ehci\n");
grub_ehci_init_device (grub_fdtbus_map_reg (dev, 0, 0));
return 0;
}
struct grub_fdtbus_driver ehci =
{
.compatible = "generic-ehci",
.attach = ehci_attach
};
void
grub_ehci_pci_scan (void)
{
grub_fdtbus_register (&ehci);
}

View File

@@ -0,0 +1,208 @@
/* ehci.c - EHCI Support. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 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/pci.h>
#include <grub/cpu/pci.h>
#include <grub/cs5536.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/usb.h>
#define GRUB_EHCI_PCI_SBRN_REG 0x60
#define GRUB_EHCI_ADDR_MEM_MASK (~0xff)
/* USBLEGSUP bits and related OS OWNED byte offset */
enum
{
GRUB_EHCI_BIOS_OWNED = (1 << 16),
GRUB_EHCI_OS_OWNED = (1 << 24)
};
/* PCI iteration function... */
static int
grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
void *data __attribute__ ((unused)))
{
volatile grub_uint32_t *regs;
grub_uint32_t base, base_h;
grub_uint32_t eecp_offset;
grub_uint32_t usblegsup = 0;
grub_uint64_t maxtime;
grub_uint32_t interf;
grub_uint32_t subclass;
grub_uint32_t class;
grub_uint8_t release;
grub_uint32_t class_code;
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: begin\n");
if (pciid == GRUB_CS5536_PCIID)
{
grub_uint64_t basereg;
basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE);
if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE))
{
/* Shouldn't happen. */
grub_dprintf ("ehci", "No EHCI address is assigned\n");
return 0;
}
base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK);
basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE;
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, basereg);
}
else
{
grub_pci_address_t addr;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
class_code = grub_pci_read (addr) >> 8;
interf = class_code & 0xFF;
subclass = (class_code >> 8) & 0xFF;
class = class_code >> 16;
/* If this is not an EHCI controller, just return. */
if (class != 0x0c || subclass != 0x03 || interf != 0x20)
return 0;
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: class OK\n");
/* Check Serial Bus Release Number */
addr = grub_pci_make_address (dev, GRUB_EHCI_PCI_SBRN_REG);
release = grub_pci_read_byte (addr);
if (release != 0x20)
{
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: Wrong SBRN: %0x\n",
release);
return 0;
}
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: bus rev. num. OK\n");
/* Determine EHCI EHCC registers base address. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
base = grub_pci_read (addr);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
base_h = grub_pci_read (addr);
/* Stop if registers are mapped above 4G - GRUB does not currently
* work with registers mapped above 4G */
if (((base & GRUB_PCI_ADDR_MEM_TYPE_MASK) != GRUB_PCI_ADDR_MEM_TYPE_32)
&& (base_h != 0))
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: registers above 4G are not supported\n");
return 0;
}
base &= GRUB_PCI_ADDR_MEM_MASK;
if (!base)
{
grub_dprintf ("ehci",
"EHCI: EHCI is not mapped\n");
return 0;
}
/* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word(addr,
GRUB_PCI_COMMAND_MEM_ENABLED
| GRUB_PCI_COMMAND_BUS_MASTER
| grub_pci_read_word(addr));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n");
}
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: iobase of EHCC: %08x\n",
(base & GRUB_EHCI_ADDR_MEM_MASK));
regs = grub_pci_device_map_range (dev,
(base & GRUB_EHCI_ADDR_MEM_MASK),
0x100);
/* Is there EECP ? */
eecp_offset = (grub_le_to_cpu32 (regs[2]) >> 8) & 0xff;
/* Determine and change ownership. */
/* EECP offset valid in HCCPARAMS */
/* Ownership can be changed via EECP only */
if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40)
{
grub_pci_address_t pciaddr_eecp;
pciaddr_eecp = grub_pci_make_address (dev, eecp_offset);
usblegsup = grub_pci_read (pciaddr_eecp);
if (usblegsup & GRUB_EHCI_BIOS_OWNED)
{
grub_boot_time ("Taking ownership of EHCI controller");
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n");
/* Ownership change - set OS_OWNED bit */
grub_pci_write (pciaddr_eecp, usblegsup | GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
/* Wait for finish of ownership change, EHCI specification
* doesn't say how long it can take... */
maxtime = grub_get_time_ms () + 1000;
while ((grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
&& (grub_get_time_ms () < maxtime));
if (grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI change ownership timeout");
/* Change ownership in "hard way" - reset BIOS ownership */
grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
}
else if (usblegsup & GRUB_EHCI_OS_OWNED)
/* XXX: What to do in this case - nothing ? Can it happen ? */
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: EHCI owned by: OS\n");
else
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI owned by: NONE\n");
/* XXX: What to do in this case ? Can it happen ?
* Is code below correct ? */
/* Ownership change - set OS_OWNED bit */
grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
/* Disable SMI, just to be sure. */
pciaddr_eecp = grub_pci_make_address (dev, eecp_offset + 4);
grub_pci_write (pciaddr_eecp, 0);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
grub_dprintf ("ehci", "inithw: EHCI grub_ehci_pci_iter: ownership OK\n");
grub_ehci_init_device (regs);
return 0;
}
void
grub_ehci_pci_scan (void)
{
grub_pci_iterate (grub_ehci_pci_iter, NULL);
}

View File

@@ -22,13 +22,11 @@
#include <grub/usb.h>
#include <grub/usbtrans.h>
#include <grub/misc.h>
#include <grub/pci.h>
#include <grub/cpu/pci.h>
#include <grub/cpu/io.h>
#include <grub/time.h>
#include <grub/loader.h>
#include <grub/cs5536.h>
#include <grub/disk.h>
#include <grub/dma.h>
#include <grub/cache.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -38,8 +36,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
* - is not supporting interrupt transfers
*/
#define GRUB_EHCI_PCI_SBRN_REG 0x60
/* Capability registers offsets */
enum
{
@@ -53,7 +49,6 @@ enum
#define GRUB_EHCI_EECP_MASK (0xff << 8)
#define GRUB_EHCI_EECP_SHIFT 8
#define GRUB_EHCI_ADDR_MEM_MASK (~0xff)
#define GRUB_EHCI_POINTER_MASK (~0x1f)
/* Capability register SPARAMS bits */
@@ -84,13 +79,6 @@ enum
#define GRUB_EHCI_QH_EMPTY 1
/* USBLEGSUP bits and related OS OWNED byte offset */
enum
{
GRUB_EHCI_BIOS_OWNED = (1 << 16),
GRUB_EHCI_OS_OWNED = (1 << 24)
};
/* Operational registers offsets */
enum
{
@@ -337,6 +325,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,9 +440,12 @@ grub_ehci_reset (struct grub_ehci *e)
{
grub_uint64_t maxtime;
sync_all_caches (e);
grub_dprintf ("ehci", "reset\n");
grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
GRUB_EHCI_CMD_HC_RESET
| grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
GRUB_EHCI_CMD_HC_RESET);
/* Ensure command is written */
grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND);
/* XXX: How long time could take reset of HC ? */
@@ -455,116 +461,24 @@ grub_ehci_reset (struct grub_ehci *e)
}
/* PCI iteration function... */
static int
grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
void *data __attribute__ ((unused)))
void
grub_ehci_init_device (volatile void *regs)
{
grub_uint8_t release;
grub_uint32_t class_code;
grub_uint32_t interf;
grub_uint32_t subclass;
grub_uint32_t class;
grub_uint32_t base, base_h;
struct grub_ehci *e;
grub_uint32_t eecp_offset;
grub_uint32_t fp;
int i;
grub_uint32_t usblegsup = 0;
grub_uint64_t maxtime;
grub_uint32_t n_ports;
grub_uint8_t caplen;
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: begin\n");
if (pciid == GRUB_CS5536_PCIID)
{
grub_uint64_t basereg;
basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE);
if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE))
{
/* Shouldn't happen. */
grub_dprintf ("ehci", "No EHCI address is assigned\n");
return 0;
}
base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK);
basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE;
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, basereg);
}
else
{
grub_pci_address_t addr;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
class_code = grub_pci_read (addr) >> 8;
interf = class_code & 0xFF;
subclass = (class_code >> 8) & 0xFF;
class = class_code >> 16;
/* If this is not an EHCI controller, just return. */
if (class != 0x0c || subclass != 0x03 || interf != 0x20)
return 0;
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: class OK\n");
/* Check Serial Bus Release Number */
addr = grub_pci_make_address (dev, GRUB_EHCI_PCI_SBRN_REG);
release = grub_pci_read_byte (addr);
if (release != 0x20)
{
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: Wrong SBRN: %0x\n",
release);
return 0;
}
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: bus rev. num. OK\n");
/* Determine EHCI EHCC registers base address. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
base = grub_pci_read (addr);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
base_h = grub_pci_read (addr);
/* Stop if registers are mapped above 4G - GRUB does not currently
* work with registers mapped above 4G */
if (((base & GRUB_PCI_ADDR_MEM_TYPE_MASK) != GRUB_PCI_ADDR_MEM_TYPE_32)
&& (base_h != 0))
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: registers above 4G are not supported\n");
return 0;
}
base &= GRUB_PCI_ADDR_MEM_MASK;
if (!base)
{
grub_dprintf ("ehci",
"EHCI: EHCI is not mapped\n");
return 0;
}
/* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
grub_pci_write_word(addr,
GRUB_PCI_COMMAND_MEM_ENABLED
| GRUB_PCI_COMMAND_BUS_MASTER
| grub_pci_read_word(addr));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n");
}
/* Allocate memory for the controller and fill basic values. */
e = grub_zalloc (sizeof (*e));
if (!e)
return 1;
return;
e->framelist_chunk = NULL;
e->td_chunk = NULL;
e->qh_chunk = NULL;
e->iobase_ehcc = grub_pci_device_map_range (dev,
(base & GRUB_EHCI_ADDR_MEM_MASK),
0x100);
e->iobase_ehcc = regs;
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: iobase of EHCC: %08x\n",
(base & GRUB_EHCI_ADDR_MEM_MASK));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CAPLEN: %02x\n",
grub_ehci_ehcc_read8 (e, GRUB_EHCI_EHCC_CAPLEN));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: VERSION: %04x\n",
@@ -580,7 +494,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
if (caplen & (sizeof (grub_uint32_t) - 1))
{
grub_dprintf ("ehci", "Unaligned caplen\n");
return 0;
return;
}
e->iobase = ((volatile grub_uint32_t *) e->iobase_ehcc
+ (caplen / sizeof (grub_uint32_t)));
@@ -591,7 +505,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: iobase of oper. regs: %08x\n",
(base & GRUB_EHCI_ADDR_MEM_MASK) + caplen);
(grub_addr_t) e->iobase_ehcc + caplen);
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n",
@@ -607,10 +521,6 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG));
/* Is there EECP ? */
eecp_offset = (grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_CPARAMS)
& GRUB_EHCI_EECP_MASK) >> GRUB_EHCI_EECP_SHIFT;
/* Check format of data structures requested by EHCI */
/* XXX: In fact it is not used at any place, it is prepared for future
* This implementation uses 32-bits pointers only */
@@ -714,65 +624,6 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: QH/TD init. OK\n");
/* Determine and change ownership. */
/* EECP offset valid in HCCPARAMS */
/* Ownership can be changed via EECP only */
if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40)
{
grub_pci_address_t pciaddr_eecp;
pciaddr_eecp = grub_pci_make_address (dev, eecp_offset);
usblegsup = grub_pci_read (pciaddr_eecp);
if (usblegsup & GRUB_EHCI_BIOS_OWNED)
{
grub_boot_time ("Taking ownership of EHCI controller");
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n");
/* Ownership change - set OS_OWNED bit */
grub_pci_write (pciaddr_eecp, usblegsup | GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
/* Wait for finish of ownership change, EHCI specification
* doesn't say how long it can take... */
maxtime = grub_get_time_ms () + 1000;
while ((grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
&& (grub_get_time_ms () < maxtime));
if (grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED)
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI change ownership timeout");
/* Change ownership in "hard way" - reset BIOS ownership */
grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
}
else if (usblegsup & GRUB_EHCI_OS_OWNED)
/* XXX: What to do in this case - nothing ? Can it happen ? */
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: EHCI owned by: OS\n");
else
{
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI owned by: NONE\n");
/* XXX: What to do in this case ? Can it happen ?
* Is code below correct ? */
/* Ownership change - set OS_OWNED bit */
grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
/* Disable SMI, just to be sure. */
pciaddr_eecp = grub_pci_make_address (dev, eecp_offset + 4);
grub_pci_write (pciaddr_eecp, 0);
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
grub_dprintf ("ehci", "inithw: EHCI grub_ehci_pci_iter: ownership OK\n");
/* Now we can setup EHCI (maybe...) */
/* Check if EHCI is halted and halt it if not */
@@ -840,11 +691,13 @@ 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",
"EHCI grub_ehci_pci_iter: iobase of oper. regs: %08x\n",
(base & GRUB_EHCI_ADDR_MEM_MASK));
(grub_addr_t) regs);
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND));
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n",
@@ -860,7 +713,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG));
return 0;
return;
fail:
if (e)
@@ -874,7 +727,7 @@ fail:
}
grub_free (e);
return 0;
return;
}
static int
@@ -1020,6 +873,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 +975,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 +1143,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 +1176,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 +1186,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 +1213,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 +1255,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 +1305,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 +1342,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 +1377,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 +1392,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 +1460,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 +1482,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 +1505,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 +1561,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 +1664,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)
{
@@ -1842,12 +1724,6 @@ grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
}
}
static void
grub_ehci_inithw (void)
{
grub_pci_iterate (grub_ehci_pci_iter, NULL);
}
static grub_err_t
grub_ehci_restore_hw (void)
{
@@ -1948,7 +1824,7 @@ GRUB_MOD_INIT (ehci)
grub_stop_disk_firmware ();
grub_boot_time ("Initing EHCI hardware");
grub_ehci_inithw ();
grub_ehci_pci_scan ();
grub_boot_time ("Registering EHCI driver");
grub_usb_controller_dev_register (&usb_controller);
grub_boot_time ("EHCI driver registered");

View File

@@ -18,12 +18,13 @@
*/
#include <grub/dl.h>
#include <grub/pci.h>
#include <grub/dma.h>
#include <grub/mm.h>
#include <grub/misc.h>
#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);

View File

@@ -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

View File

@@ -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 ();

View File

@@ -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");

View File

@@ -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;

View File

@@ -20,7 +20,7 @@
#include <grub/misc.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/i386/coreboot/lbio.h>
#include <grub/coreboot/lbio.h>
#include <grub/i386/tsc.h>
GRUB_MOD_LICENSE ("GPLv3+");

View File

@@ -20,7 +20,7 @@
#include <grub/misc.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/i386/coreboot/lbio.h>
#include <grub/coreboot/lbio.h>
#include <grub/i386/tsc.h>
GRUB_MOD_LICENSE ("GPLv3+");

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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]);

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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]);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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");

View File

@@ -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;

View File

@@ -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 */

View File

@@ -227,11 +227,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
static grub_err_t
read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb)
{
struct grub_btrfs_superblock sblock;
unsigned i;
grub_err_t err = GRUB_ERR_NONE;
for (i = 0; i < ARRAY_SIZE (superblock_sectors); i++)
{
struct grub_btrfs_superblock sblock;
/* Don't try additional superblocks beyond device size. */
if (i && (grub_le_to_cpu64 (sblock.this_device.size)
>> GRUB_DISK_SECTOR_BITS) <= superblock_sectors[i])

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)) {

View File

@@ -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':

View File

@@ -1,4 +1,4 @@
#! /bin/sh
#! @BUILD_SHEBANG@
set -e
# Copyright (C) 2010 Free Software Foundation, Inc.
@@ -94,6 +94,6 @@ else
rm -f $tmpfile.bin
fi
if test x@platform@ != xemu; then
./build-grub-module-verifier@BUILD_EXEEXT@ $tmpfile @target_cpu@
./build-grub-module-verifier@BUILD_EXEEXT@ $tmpfile @target_cpu@ @platform@
fi
mv $tmpfile $outfile

View File

@@ -1,4 +1,4 @@
#! /bin/sh
#! @BUILD_SHEBANG@
set -e
# Copyright (C) 2010 Free Software Foundation, Inc.

View File

@@ -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

View File

@@ -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;

View 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:

View File

@@ -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:

View File

@@ -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;
}

View File

@@ -29,6 +29,8 @@ void grub_arm_clean_dcache_range_armv6 (grub_addr_t start, grub_addr_t end,
grub_addr_t dlinesz);
void grub_arm_clean_dcache_range_armv7 (grub_addr_t start, grub_addr_t end,
grub_addr_t dlinesz);
void grub_arm_clean_dcache_range_poc_armv7 (grub_addr_t start, grub_addr_t end,
grub_addr_t dlinesz);
void grub_arm_invalidate_icache_range_armv6 (grub_addr_t start, grub_addr_t end,
grub_addr_t dlinesz);
void grub_arm_invalidate_icache_range_armv7 (grub_addr_t start, grub_addr_t end,
@@ -252,6 +254,38 @@ grub_arch_sync_caches (void *address, grub_size_t len)
}
}
void
grub_arch_sync_dma_caches (volatile void *address, grub_size_t len)
{
grub_addr_t start = (grub_addr_t) address;
grub_addr_t end = start + len;
if (type == ARCH_UNKNOWN)
probe_caches ();
start = ALIGN_DOWN (start, grub_arch_cache_max_linesz);
end = ALIGN_UP (end, grub_arch_cache_max_linesz);
switch (type)
{
case ARCH_ARMV6:
grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz);
grub_arm_invalidate_icache_range_armv6 (start, end,
grub_arch_cache_ilinesz);
break;
case ARCH_ARMV5_WRITE_THROUGH:
case ARCH_ARMV6_UNIFIED:
grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz);
break;
case ARCH_ARMV7:
grub_arm_clean_dcache_range_poc_armv7 (start, end, grub_arch_cache_dlinesz);
grub_arm_invalidate_icache_range_armv7 (start, end,
grub_arch_cache_ilinesz);
break;
/* Pacify GCC. */
case ARCH_UNKNOWN:
break;
}
}
void
grub_arm_disable_caches_mmu (void)
{

View File

@@ -33,6 +33,18 @@
# define ISB isb
#define ARMV7 1
FUNCTION(grub_arm_clean_dcache_range_poc_armv7)
DSB
@ Clean data cache for range to point-of-coherence
1: cmp r0, r1
bge 2f
mcr p15, 0, r0, c7, c14, 1 @ DCCMVAC
add r0, r0, r2 @ Next line
b 1b
2: DSB
bx lr
@ r0 - CLIDR
@ r1 - LoC
@ r2 - current level

View File

@@ -0,0 +1,40 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007,2008,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/coreboot/lbio.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/dl.h>
#include <grub/arm/startup.h>
GRUB_MOD_LICENSE ("GPLv3+");
#pragma GCC diagnostic ignored "-Wcast-align"
grub_linuxbios_table_header_t
grub_linuxbios_get_tables (void)
{
grub_linuxbios_table_header_t table_header
= (grub_linuxbios_table_header_t) grub_arm_saved_registers.r[0];
if (!grub_linuxbios_check_signature (table_header))
return 0;
return table_header;
}

View File

@@ -0,0 +1,44 @@
/*
* 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/symbol.h>
.file "coreboot.S"
.text
.syntax unified
#if !defined (__thumb2__)
.arch armv7a
.arm
#else
.arch armv7
.thumb
#endif
FUNCTION(grub_arm_pfr1)
mrc p15, 0, r0, c0, c1, 1
bx lr
FUNCTION(grub_armv7_get_timer_value)
isb
mrrc p15, 1, r0, r1, c14
bx lr
FUNCTION(grub_armv7_get_timer_frequency)
mrc p15, 0, r0, c14, c0, 0
bx lr

View File

@@ -0,0 +1,59 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007,2009 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/dl.h>
#include <grub/dma.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/mm_private.h>
#include <grub/cache.h>
struct grub_pci_dma_chunk *
grub_memalign_dma32 (grub_size_t align, grub_size_t size)
{
void *ret;
if (align < 64)
align = 64;
size = ALIGN_UP (size, align);
ret = grub_memalign (align, size);
if (!ret)
return 0;
grub_arch_sync_dma_caches (ret, size);
return ret;
}
void
grub_dma_free (struct grub_pci_dma_chunk *ch)
{
grub_size_t size = (((struct grub_mm_header *) ch) - 1)->size * GRUB_MM_ALIGN;
grub_arch_sync_dma_caches (ch, size);
grub_free (ch);
}
volatile void *
grub_dma_get_virt (struct grub_pci_dma_chunk *ch)
{
return (void *) ch;
}
grub_uint32_t
grub_dma_get_phys (struct grub_pci_dma_chunk *ch)
{
return (grub_uint32_t) (grub_addr_t) ch;
}

View File

@@ -0,0 +1,169 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,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/kernel.h>
#include <grub/mm.h>
#include <grub/memory.h>
#include <grub/machine/console.h>
#include <grub/machine/kernel.h>
#include <grub/offsets.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/loader.h>
#include <grub/env.h>
#include <grub/cache.h>
#include <grub/time.h>
#include <grub/symbol.h>
#include <grub/video.h>
#include <grub/coreboot/lbio.h>
#include <grub/fdtbus.h>
extern grub_uint8_t _start[];
extern grub_uint8_t _end[];
extern grub_uint8_t _edata[];
grub_addr_t start_of_ram = ~(grub_addr_t)0;
void __attribute__ ((noreturn))
grub_exit (void)
{
/* We can't use grub_fatal() in this function. This would create an infinite
loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit(). */
while (1)
grub_cpu_idle ();
}
static grub_uint64_t modend;
static int have_memory = 0;
/* Helper for grub_machine_init. */
static int
heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
void *data __attribute__ ((unused)))
{
grub_uint64_t begin = addr, end = addr + size;
#if GRUB_CPU_SIZEOF_VOID_P == 4
/* Restrict ourselves to 32-bit memory space. */
if (begin > GRUB_ULONG_MAX)
return 0;
if (end > GRUB_ULONG_MAX)
end = GRUB_ULONG_MAX;
#endif
if (start_of_ram > begin)
start_of_ram = begin;
if (type != GRUB_MEMORY_AVAILABLE)
return 0;
if (modend && begin < modend)
{
if (begin < (grub_addr_t)_start)
{
grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) ((grub_addr_t)_start - begin));
have_memory = 1;
}
begin = modend;
}
/* Avoid DMA problems. */
if (end >= 0xfe000000)
end = 0xfe000000;
if (end <= begin)
return 0;
grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) (end - begin));
have_memory = 1;
return 0;
}
static const void *dtb;
static grub_size_t dtb_size;
static int
iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data __attribute__ ((unused)))
{
if (table_item->tag != GRUB_LINUXBIOS_MEMBER_DTB)
return 0;
if (grub_fdt_check_header (table_item + 1, table_item->size) >= 0)
{
dtb = table_item + 1;
dtb_size = table_item->size;
}
else
grub_printf ("Invalid DTB supplied by coreboot\n");
return 0;
}
void
grub_machine_init (void)
{
struct grub_module_header *header;
modend = grub_modules_get_end ();
grub_video_coreboot_fb_early_init ();
grub_machine_mmap_iterate (heap_init, NULL);
if (!have_memory)
grub_fatal ("No memory found");
grub_video_coreboot_fb_late_init ();
grub_font_init ();
grub_gfxterm_init ();
FOR_MODULES (header)
if (header->type == OBJ_TYPE_DTB)
{
char *dtb_orig_addr, *dtb_copy;
dtb_orig_addr = (char *) header + sizeof (struct grub_module_header);
dtb_size = header->size - sizeof (struct grub_module_header);
dtb = dtb_copy = grub_malloc (dtb_size);
grub_memmove (dtb_copy, dtb_orig_addr, dtb_size);
break;
}
if (!dtb)
grub_linuxbios_table_iterate (iterate_linuxbios_table, 0);
if (!dtb)
grub_fatal ("No DTB found");
grub_fdtbus_init (dtb, dtb_size);
grub_machine_timer_init ();
grub_cros_init ();
grub_pl050_init ();
}
void
grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
char **path __attribute__ ((unused)))
{
}
void
grub_machine_fini (int flags __attribute__ ((unused)))
{
}

View File

@@ -0,0 +1,101 @@
/*
* 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/mm.h>
#include <grub/machine/kernel.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/time.h>
#include <grub/fdtbus.h>
#include <grub/misc.h>
grub_uint64_t
grub_armv7_get_timer_value(void);
grub_uint32_t
grub_armv7_get_timer_frequency(void);
grub_uint32_t
grub_arm_pfr1(void);
static int have_timer = 0;
static volatile grub_uint32_t *sp804_regs;
static grub_uint64_t
sp804_get_time_ms (void)
{
static grub_uint32_t high, last_low;
grub_uint32_t low = ~sp804_regs[1];
if (last_low > low)
high++;
last_low = low;
return grub_divmod64 ((((grub_uint64_t) high) << 32) | low,
1000, 0);
}
static grub_err_t
sp804_attach(const struct grub_fdtbus_dev *dev)
{
if (have_timer)
return GRUB_ERR_NONE;
sp804_regs = grub_fdtbus_map_reg (dev, 0, 0);
if (!grub_fdtbus_is_mapping_valid (sp804_regs))
return grub_error (GRUB_ERR_IO, "could not map sp804: %p", sp804_regs);
grub_install_get_time_ms (sp804_get_time_ms);
have_timer = 1;
return GRUB_ERR_NONE;
}
struct grub_fdtbus_driver sp804 =
{
.compatible = "arm,sp804",
.attach = sp804_attach
};
static grub_uint32_t timer_frequency_in_khz;
static grub_uint64_t
generic_get_time_ms (void)
{
return grub_divmod64 (grub_armv7_get_timer_value(), timer_frequency_in_khz, 0);
}
static int
try_generic_timer (void)
{
if (((grub_arm_pfr1 () >> 16) & 0xf) != 1)
return 0;
grub_printf ("freq = %x\n", grub_armv7_get_timer_frequency());
timer_frequency_in_khz = 0x016e3600 / 1000; //grub_armv7_get_timer_frequency() / 1000;
if (timer_frequency_in_khz == 0)
return 0;
grub_install_get_time_ms (generic_get_time_ms);
have_timer = 1;
return 1;
}
void
grub_machine_timer_init (void)
{
grub_fdtbus_register (&sp804);
if (!have_timer)
try_generic_timer ();
if (!have_timer)
grub_fatal ("No timer found");
}

View File

@@ -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;

View File

@@ -24,6 +24,7 @@
* GRUB is called from U-Boot as a Linux Kernel type image, which
* means among other things that it always enters in ARM state.
*
* coreboot starts in ARM mode as well.
*
* Overview of GRUB image layout:
*
@@ -55,10 +56,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,34 +63,73 @@ 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 {r0-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
str r1, EXT_C(grub_modbase)
/* Coreboot already places modules at right place. */
#ifndef GRUB_MACHINE_COREBOOT
add r1, r1, r2
add r0, r0, r2
sub r1, r1, #4
@@ -103,6 +139,7 @@ FUNCTION(codestart)
str r3, [r1], #-4 @ *dst-- = r3
subs r2, #4 @ remaining -= 4
bne 1b @ while remaining != 0
#endif
@ Since we _are_ the C run-time, we need to manually zero the BSS
@ region before continuing
@@ -120,64 +157,21 @@ FUNCTION(codestart)
b EXT_C(grub_main)
/*
* uboot_syscall():
* This function is effectively a veneer, so it cannot
* modify the stack or corrupt any registers other than
* r12 (ip). Furthermore it needs to restore r8 for
* U-Boot (Global Data Pointer) and preserve it for Grub.
*/
FUNCTION(grub_uboot_syscall)
str r8, transition_space
str lr, transition_space + 4
str r9, transition_space + 8
ldr r8, gd_backup
ldr r9, gd_backup + 4
bl do_syscall
ldr r8, transition_space
ldr lr, transition_space + 4
ldr r9, transition_space + 8
bx lr
do_syscall:
ldr ip, grub_uboot_syscall_ptr
bx ip
FUNCTION(grub_uboot_return)
adr sp, entry_state_end
pop {r4-r12, lr}
mov sp, r12
bx lr
.align 3
@ U-boot context stack space
entry_state_end:
@ U-boot/coreboot context stack space
VARIABLE(grub_arm_saved_registers)
.long 0 @ r0
.long 0 @ r1
.long 0 @ r2
.long 0 @ r3
.long 0 @ r4
.long 0 @ r5
.long 0 @ r6
.long 0 @ r7
gd_backup:
.long 0 @ r8 - U-Boot global data pointer up to 2013-09-21
.long 0 @ r9 - U-Boot global data pointer 2013-09-21 onwards
.long 0 @ r8
.long 0 @ r9
.long 0 @ r10
.long 0 @ r11
VARIABLE(grub_uboot_search_hint)@ U-Boot stack pointer -
.long 0 @ also API signature address hint.
.long 0 @ sp
.long 0 @ lr
entry_state: @ backup for U-Boot context
@ GRUB context stack space
transition_space:
.long 0 @ r8
.long 0 @ lr
.long 0 @ r9
VARIABLE(grub_uboot_syscall_ptr)
.long 0 @
END
entry_state:

View File

@@ -0,0 +1,70 @@
/* init.c - generic U-Boot initialization and finalization */
/*
* 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/uboot/uboot.h>
#include <grub/arm/startup.h>
#include <grub/uboot/api_public.h>
extern int (*grub_uboot_syscall_ptr) (int, int *, ...);
grub_uint32_t
grub_uboot_get_machine_type (void)
{
return grub_arm_saved_registers.r[1];
}
grub_addr_t
grub_uboot_get_boot_data (void)
{
return grub_arm_saved_registers.r[2];
}
int
grub_uboot_api_init (void)
{
struct api_signature *start, *end;
struct api_signature *p;
grub_addr_t grub_uboot_search_hint = grub_arm_saved_registers.sp;
if (grub_uboot_search_hint)
{
/* Extended search range to work around Trim Slice U-Boot issue */
start = (struct api_signature *) ((grub_uboot_search_hint & ~0x000fffff)
- 0x00500000);
end =
(struct api_signature *) ((grub_addr_t) start + UBOOT_API_SEARCH_LEN -
API_SIG_MAGLEN + 0x00500000);
}
else
{
start = 0;
end = (struct api_signature *) (256 * 1024 * 1024);
}
/* Structure alignment is (at least) 8 bytes */
for (p = start; p < end; p = (void *) ((grub_addr_t) p + 8))
{
if (grub_memcmp (&(p->magic), API_SIG_MAGIC, API_SIG_MAGLEN) == 0)
{
grub_uboot_syscall_ptr = p->syscall;
return p->version;
}
}
return 0;
}

View File

@@ -0,0 +1,73 @@
/*
* 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/offsets.h>
#include <grub/symbol.h>
#include <grub/machine/kernel.h>
/*
* uboot_syscall():
* This function is effectively a veneer, so it cannot
* modify the stack or corrupt any registers other than
* r12 (ip). Furthermore it needs to restore r8 for
* U-Boot (Global Data Pointer) and preserve it for Grub.
*/
FUNCTION(grub_uboot_syscall)
str r8, transition_space
str lr, transition_space + 4
str r9, transition_space + 8
ldr ip, saved_registers_ptr
ldr r8, [ip, #4 * 8]
ldr r9, [ip, #4 * 9]
bl do_syscall
ldr r8, transition_space
ldr lr, transition_space + 4
ldr r9, transition_space + 8
bx lr
do_syscall:
ldr ip, grub_uboot_syscall_ptr
bx ip
FUNCTION(grub_uboot_return)
ldr ip, saved_registers_ptr
ldr sp, [ip, #4 * 4]
pop {r4-r12, lr}
mov sp, r12
bx lr
.align 3
@ GRUB context stack space
transition_space:
.long 0 @ r8
.long 0 @ lr
.long 0 @ r9
saved_registers_ptr:
.long EXT_C(grub_arm_saved_registers)
VARIABLE(grub_uboot_syscall_ptr)
.long 0 @
END

View File

@@ -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"),

View File

@@ -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;
}

View 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 ();
}

View File

@@ -0,0 +1,72 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007,2008,2013 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/i386/coreboot/memory.h>
#include <grub/coreboot/lbio.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/dl.h>
#pragma GCC diagnostic ignored "-Wcast-align"
/* Helper for grub_linuxbios_table_iterate. */
int
grub_linuxbios_check_signature (grub_linuxbios_table_header_t tbl_header)
{
if (! grub_memcmp (tbl_header->signature, "LBIO", 4))
return 1;
return 0;
}
grub_err_t
grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t,
void *),
void *hook_data)
{
grub_linuxbios_table_header_t table_header = grub_linuxbios_get_tables ();
grub_linuxbios_table_item_t table_item;
if (!table_header)
return 0;
signature_found:
table_item =
(grub_linuxbios_table_item_t) ((char *) table_header +
table_header->header_size);
for (; table_item < (grub_linuxbios_table_item_t) ((char *) table_header
+ table_header->header_size
+ table_header->table_size);
table_item = (grub_linuxbios_table_item_t) ((char *) table_item + table_item->size))
{
if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK
&& grub_linuxbios_check_signature ((grub_linuxbios_table_header_t) (grub_addr_t)
*(grub_uint64_t *) (table_item + 1)))
{
table_header = (grub_linuxbios_table_header_t) (grub_addr_t)
*(grub_uint64_t *) (table_item + 1);
goto signature_found;
}
if (hook (table_item, hook_data))
return 1;
}
return 0;
}

View File

@@ -16,8 +16,8 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/machine/memory.h>
#include <grub/machine/lbio.h>
#include <grub/memory.h>
#include <grub/coreboot/lbio.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/misc.h>
@@ -49,6 +49,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
{
grub_uint64_t start = mem_region->addr;
grub_uint64_t end = mem_region->addr + mem_region->size;
#ifdef __i386__
/* Mark region 0xa0000 - 0x100000 as reserved. */
if (start < 0x100000 && end >= 0xa0000
&& mem_region->type == GRUB_MACHINE_MEMORY_AVAILABLE)
@@ -75,6 +76,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
if (end <= start)
continue;
}
#endif
if (ctx->hook (start, end - start,
/* Multiboot mmaps match with the coreboot mmap
definition. Therefore, we can just pass type

View File

@@ -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;

View File

@@ -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
View 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;
}

View File

@@ -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. */

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -17,7 +17,7 @@
*/
#include <grub/i386/coreboot/memory.h>
#include <grub/i386/coreboot/lbio.h>
#include <grub/coreboot/lbio.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/misc.h>
@@ -25,59 +25,20 @@
GRUB_MOD_LICENSE ("GPLv3+");
/* Helper for grub_linuxbios_table_iterate. */
static int
check_signature (grub_linuxbios_table_header_t tbl_header)
{
if (! grub_memcmp (tbl_header->signature, "LBIO", 4))
return 1;
return 0;
}
grub_err_t
grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t,
void *),
void *hook_data)
grub_linuxbios_table_header_t
grub_linuxbios_get_tables (void)
{
grub_linuxbios_table_header_t table_header;
grub_linuxbios_table_item_t table_item;
/* Assuming table_header is aligned to its size (8 bytes). */
for (table_header = (grub_linuxbios_table_header_t) 0x500;
table_header < (grub_linuxbios_table_header_t) 0x1000; table_header++)
if (check_signature (table_header))
goto signature_found;
if (grub_linuxbios_check_signature (table_header))
return table_header;
for (table_header = (grub_linuxbios_table_header_t) 0xf0000;
table_header < (grub_linuxbios_table_header_t) 0x100000; table_header++)
if (check_signature (table_header))
goto signature_found;
return 0;
signature_found:
table_item =
(grub_linuxbios_table_item_t) ((char *) table_header +
table_header->header_size);
for (; table_item < (grub_linuxbios_table_item_t) ((char *) table_header
+ table_header->header_size
+ table_header->table_size);
table_item = (grub_linuxbios_table_item_t) ((char *) table_item + table_item->size))
{
if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK
&& check_signature ((grub_linuxbios_table_header_t) (grub_addr_t)
*(grub_uint64_t *) (table_item + 1)))
{
table_header = (grub_linuxbios_table_header_t) (grub_addr_t)
*(grub_uint64_t *) (table_item + 1);
goto signature_found;
}
if (hook (table_item, hook_data))
return 1;
}
if (grub_linuxbios_check_signature (table_header))
return table_header;
return 0;
}

View File

@@ -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

View File

@@ -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. */

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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:

View File

@@ -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[];

View File

@@ -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))
{

View File

@@ -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;

View File

@@ -391,12 +391,13 @@ grub_strtoull (const char *str, char **end, int base)
unsigned long digit;
digit = grub_tolower (*str) - '0';
if (digit > 9)
{
digit += '0' - 'a' + 10;
if (digit >= (unsigned long) base)
break;
}
if (digit >= 'a' - '0')
digit += '0' - 'a' + 10;
else if (digit > 9)
break;
if (digit >= (unsigned long) base)
break;
found = 1;
@@ -740,6 +741,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 +883,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 +1107,8 @@ grub_fatal (const char *fmt, ...)
grub_vprintf (_(fmt), ap);
va_end (ap);
grub_refresh ();
grub_abort ();
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -36,30 +36,14 @@
extern char __bss_start[];
extern char _end[];
extern grub_size_t grub_total_module_size;
extern int (*grub_uboot_syscall_ptr) (int, int *, ...);
static unsigned long timer_start;
extern grub_uint32_t grub_uboot_machine_type;
extern grub_addr_t grub_uboot_boot_data;
void
grub_exit (void)
{
grub_uboot_return (0);
}
grub_uint32_t
grub_uboot_get_machine_type (void)
{
return grub_uboot_machine_type;
}
grub_addr_t
grub_uboot_get_boot_data (void)
{
return grub_uboot_boot_data;
}
static grub_uint64_t
uboot_timer_ms (void)
{

View File

@@ -39,48 +39,13 @@
* returns: 0 if the call not found, 1 if serviced
*/
extern int (*grub_uboot_syscall_ptr) (int, int *, ...);
extern int grub_uboot_syscall (int, int *, ...);
extern grub_addr_t grub_uboot_search_hint;
static struct sys_info uboot_sys_info;
static struct mem_region uboot_mem_info[5];
static struct device_info * devices;
static int num_devices;
int
grub_uboot_api_init (void)
{
struct api_signature *start, *end;
struct api_signature *p;
if (grub_uboot_search_hint)
{
/* Extended search range to work around Trim Slice U-Boot issue */
start = (struct api_signature *) ((grub_uboot_search_hint & ~0x000fffff)
- 0x00500000);
end =
(struct api_signature *) ((grub_addr_t) start + UBOOT_API_SEARCH_LEN -
API_SIG_MAGLEN + 0x00500000);
}
else
{
start = 0;
end = (struct api_signature *) (256 * 1024 * 1024);
}
/* Structure alignment is (at least) 8 bytes */
for (p = start; p < end; p = (void *) ((grub_addr_t) p + 8))
{
if (grub_memcmp (&(p->magic), API_SIG_MAGIC, API_SIG_MAGLEN) == 0)
{
grub_uboot_syscall_ptr = p->syscall;
return p->version;
}
}
return 0;
}
/*
* All functions below are wrappers around the grub_uboot_syscall() function

View File

@@ -18,7 +18,6 @@
#include <grub/types.h>
#include <grub/symbol.h>
#include <grub/uboot/uboot.h>
#include <grub/datetime.h>
#include <grub/dl.h>
@@ -30,12 +29,12 @@ grub_err_t
grub_get_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
{
return grub_error (GRUB_ERR_INVALID_COMMAND,
"can\'t get datetime using U-Boot");
"can\'t get datetime on this machine");
}
grub_err_t
grub_set_datetime (struct grub_datetime * datetime __attribute__ ((unused)))
{
return grub_error (GRUB_ERR_INVALID_COMMAND,
"can\'t set datetime using U-Boot");
"can\'t set datetime on this machine");
}

View File

@@ -0,0 +1,32 @@
/*
* 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/misc.h>
#include <grub/mm.h>
#include <grub/kernel.h>
#include <grub/loader.h>
void
grub_reboot (void)
{
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
/* Just stop here */
while (1);
}

View File

@@ -102,13 +102,13 @@ static grub_uint32_t *get_next_node (const void *fdt, char *node_name)
static int get_mem_rsvmap_size (const void *fdt)
{
int size = 0;
grub_uint64_t *ptr = (void *) ((grub_addr_t) fdt
+ grub_fdt_get_off_mem_rsvmap (fdt));
grub_unaligned_uint64_t *ptr = (void *) ((grub_addr_t) fdt
+ grub_fdt_get_off_mem_rsvmap (fdt));
do
{
size += 2 * sizeof(*ptr);
if (!*ptr && !*(ptr + 1))
if (!ptr[0].val && !ptr[1].val)
return size;
ptr += 2;
} while ((grub_addr_t) ptr <= (grub_addr_t) fdt + grub_fdt_get_totalsize (fdt)
@@ -229,7 +229,7 @@ static int rearrange_blocks (void *fdt, unsigned int clearance)
return 0;
}
static grub_uint32_t *find_prop (void *fdt, unsigned int nodeoffset,
static grub_uint32_t *find_prop (const void *fdt, unsigned int nodeoffset,
const char *name)
{
grub_uint32_t *prop = (void *) ((grub_addr_t) fdt
@@ -268,9 +268,9 @@ static grub_uint32_t *find_prop (void *fdt, unsigned int nodeoffset,
the size allocated for the FDT; if this function is called before the other
functions in this file and returns success, the other functions are
guaranteed not to access memory locations outside the allocated memory. */
int grub_fdt_check_header_nosize (void *fdt)
int grub_fdt_check_header_nosize (const void *fdt)
{
if (((grub_addr_t) fdt & 0x7) || (grub_fdt_get_magic (fdt) != FDT_MAGIC)
if (((grub_addr_t) fdt & 0x3) || (grub_fdt_get_magic (fdt) != FDT_MAGIC)
|| (grub_fdt_get_version (fdt) < FDT_SUPPORTED_VERSION)
|| (grub_fdt_get_last_comp_version (fdt) > FDT_SUPPORTED_VERSION)
|| (grub_fdt_get_off_dt_struct (fdt) & 0x00000003)
@@ -286,7 +286,7 @@ int grub_fdt_check_header_nosize (void *fdt)
return 0;
}
int grub_fdt_check_header (void *fdt, unsigned int size)
int grub_fdt_check_header (const void *fdt, unsigned int size)
{
if (size < sizeof (grub_fdt_header_t)
|| (grub_fdt_get_totalsize (fdt) > size)
@@ -295,41 +295,29 @@ int grub_fdt_check_header (void *fdt, unsigned int size)
return 0;
}
/* Find a direct sub-node of a given parent node. */
int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset,
const char *name)
static const grub_uint32_t *
advance_token (const void *fdt, const grub_uint32_t *token, const grub_uint32_t *end, int skip_current)
{
grub_uint32_t *token, *end;
char *node_name;
if (parentoffset & 0x3)
return -1;
token = (void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt)
+ parentoffset);
end = (void *) struct_end (fdt);
if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE))
return -1;
SKIP_NODE_NAME(node_name, token, end);
while (token < end)
for (; token < end; skip_current = 0)
{
switch (grub_be_to_cpu32(*token))
switch (grub_be_to_cpu32 (*token))
{
case FDT_BEGIN_NODE:
node_name = (char *) (token + 1);
if (node_name + grub_strlen (name) >= (char *) end)
return -1;
if (!grub_strcmp (node_name, name))
return (int) ((grub_addr_t) token - (grub_addr_t) fdt
- grub_fdt_get_off_dt_struct (fdt));
token = get_next_node (fdt, node_name);
if (!token)
return -1;
break;
if (skip_current)
{
token = get_next_node (fdt, (char *) (token + 1));
continue;
}
char *ptr;
for (ptr = (char *) (token + 1); *ptr && ptr < (char *) end; ptr++);
if (ptr >= (char *) end)
return 0;
return token;
case FDT_PROP:
/* Skip property token and following data (len, nameoff and property
value). */
if (token >= end - 1)
return -1;
return 0;
token += prop_entry_size(grub_be_to_cpu32(*(token + 1)))
/ sizeof(*token);
break;
@@ -337,10 +325,74 @@ int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset,
token++;
break;
default:
return -1;
return 0;
}
}
return -1;
return 0;
}
int grub_fdt_next_node (const void *fdt, unsigned int currentoffset)
{
const grub_uint32_t *token = (const grub_uint32_t *) fdt + (currentoffset + grub_fdt_get_off_dt_struct (fdt)) / 4;
token = advance_token (fdt, token, (const void *) struct_end (fdt), 1);
if (!token)
return -1;
return (int) ((grub_addr_t) token - (grub_addr_t) fdt
- grub_fdt_get_off_dt_struct (fdt));
}
int grub_fdt_first_node (const void *fdt, unsigned int parentoffset)
{
const grub_uint32_t *token, *end;
char *node_name;
if (parentoffset & 0x3)
return -1;
token = (const void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt)
+ parentoffset);
end = (const void *) struct_end (fdt);
if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE))
return -1;
SKIP_NODE_NAME(node_name, token, end);
token = advance_token (fdt, token, end, 0);
if (!token)
return -1;
return (int) ((grub_addr_t) token - (grub_addr_t) fdt
- grub_fdt_get_off_dt_struct (fdt));
}
/* Find a direct sub-node of a given parent node. */
int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset,
const char *name)
{
const grub_uint32_t *token, *end;
const char *node_name;
int skip_current = 0;
if (parentoffset & 0x3)
return -1;
token = (const void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt)
+ parentoffset);
end = (const void *) struct_end (fdt);
if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE))
return -1;
SKIP_NODE_NAME(node_name, token, end);
while (1) {
token = advance_token (fdt, token, end, skip_current);
if (!token)
return -1;
skip_current = 1;
node_name = (const char *) token + 4;
if (grub_strcmp (node_name, name) == 0)
return (int) ((grub_addr_t) token - (grub_addr_t) fdt
- grub_fdt_get_off_dt_struct (fdt));
}
}
const char *
grub_fdt_get_nodename (const void *fdt, unsigned int nodeoffset)
{
return (const char *) fdt + grub_fdt_get_off_dt_struct(fdt) + nodeoffset + 4;
}
int grub_fdt_add_subnode (void *fdt, unsigned int parentoffset,
@@ -359,6 +411,24 @@ int grub_fdt_add_subnode (void *fdt, unsigned int parentoffset,
return add_subnode (fdt, parentoffset, name);
}
const void *
grub_fdt_get_prop (const void *fdt, unsigned int nodeoffset, const char *name,
grub_uint32_t *len)
{
grub_uint32_t *prop;
if ((nodeoffset >= grub_fdt_get_size_dt_struct (fdt)) || (nodeoffset & 0x3)
|| (grub_be_to_cpu32(*(grub_uint32_t *) ((grub_addr_t) fdt
+ grub_fdt_get_off_dt_struct (fdt) + nodeoffset))
!= FDT_BEGIN_NODE))
return 0;
prop = find_prop (fdt, nodeoffset, name);
if (!prop)
return 0;
if (len)
*len = grub_be_to_cpu32 (*(prop + 1));
return prop + 3;
}
int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name,
const void *val, grub_uint32_t len)
{

103
grub-core/lib/i386/random.c Normal file
View 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);
}

Some files were not shown because too many files have changed in this diff Show More