diff --git a/fvp.mk b/fvp.mk
index b890f984a7d66df2d93195f5bdb172e86b6124f1..5d12d1989868c777c708b3b29492045809e23450 100644
--- a/fvp.mk
+++ b/fvp.mk
@@ -23,17 +23,27 @@ FOUNDATION_PATH		?= $(ROOT)/Foundation_Platformpkg
 ifeq ($(wildcard $(FOUNDATION_PATH)),)
 $(error $(FOUNDATION_PATH) does not exist)
 endif
+GRUB_PATH		?= $(ROOT)/grub
+GRUB_CONFIG_PATH	?= $(BUILD_PATH)/fvp/grub
+OUT_PATH		?= $(ROOT)/out
+GRUB_BIN		?= $(OUT_PATH)/bootaa64.efi
 
 ################################################################################
 # Targets
 ################################################################################
-all: arm-tf edk2 linux optee-os optee-client xtest optee-examples
-clean: arm-tf-clean busybox-clean edk2-clean optee-os-clean \
+all: arm-tf edk2 grub linux optee-os optee-client xtest optee-examples
+clean: arm-tf-clean busybox-clean edk2-clean grub-clean optee-os-clean \
 	optee-client-clean optee-examples-clean
 
 
 include toolchain.mk
 
+################################################################################
+# Folders
+################################################################################
+$(OUT_PATH):
+	mkdir -p $@
+
 ################################################################################
 # ARM Trusted Firmware
 ################################################################################
@@ -145,6 +155,45 @@ filelist-tee: filelist-tee-common
 
 update_rootfs: update_rootfs-common
 
+################################################################################
+# grub
+################################################################################
+grub-flags := CC="$(CCACHE)gcc" \
+	TARGET_CC="$(AARCH64_CROSS_COMPILE)gcc" \
+	TARGET_OBJCOPY="$(AARCH64_CROSS_COMPILE)objcopy" \
+	TARGET_NM="$(AARCH64_CROSS_COMPILE)nm" \
+	TARGET_RANLIB="$(AARCH64_CROSS_COMPILE)ranlib" \
+	TARGET_STRIP="$(AARCH64_CROSS_COMPILE)strip"
+
+GRUB_MODULES += boot chain configfile echo efinet eval ext2 fat font gettext \
+		gfxterm gzio help linux loadenv lsefi normal part_gpt \
+		part_msdos read regexp search search_fs_file search_fs_uuid \
+		search_label terminal terminfo test tftp time
+
+$(GRUB_PATH)/configure: $(GRUB_PATH)/configure.ac
+	cd $(GRUB_PATH) && ./autogen.sh
+
+$(GRUB_PATH)/Makefile: $(GRUB_PATH)/configure
+	cd $(GRUB_PATH) && ./configure --target=aarch64 --enable-boot-time $(grub-flags)
+
+.PHONY: grub
+grub: $(GRUB_PATH)/Makefile | $(OUT_PATH)
+	$(MAKE) -C $(GRUB_PATH) && \
+	cd $(GRUB_PATH) && ./grub-mkimage \
+		--output=$(GRUB_BIN) \
+		--config=$(GRUB_CONFIG_PATH)/grub.cfg \
+		--format=arm64-efi \
+		--directory=grub-core \
+		--prefix=/boot/grub \
+		$(GRUB_MODULES)
+
+.PHONY: grub-clean
+grub-clean:
+	@if [ -e $(GRUB_PATH)/Makefile ]; then $(MAKE) -C $(GRUB_PATH) clean; fi
+	@rm -f $(GRUB_BIN)
+	@rm -f $(GRUB_PATH)/configure
+
+
 ################################################################################
 # Run targets
 ################################################################################
diff --git a/fvp/grub/grub.cfg b/fvp/grub/grub.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..6ddef3429c754143e6fd2478f5025fac1b53aab8
--- /dev/null
+++ b/fvp/grub/grub.cfg
@@ -0,0 +1,10 @@
+set prefix='/EFI/BOOT'
+
+set default="0"
+set timeout=10
+
+menuentry 'GNU/Linux (OP-TEE)' {
+    linux /Image console=tty0 console=ttyAMA0,115200 earlycon=pl011,0x1c090000 root=/dev/disk/by-partlabel/system rootwait rw ignore_loglevel efi=noruntime
+    initrd /initrd.img
+    devicetree /foundation-v8.dtb
+}