├── COPYING ├── Makefile ├── README.md ├── myloader.c └── myloader_win.c /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 KANATSU Minoru 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | The views and conclusions contained in the software and documentation are those 25 | of the authors and should not be interpreted as representing official policies, 26 | either expressed or implied, of the FreeBSD Project. 27 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ARCH = x86_64 2 | EFIROOT = /usr 3 | HDDRROOT = $(EFIROOT)/include/efi 4 | INCLUDES = -I. -I$(HDDRROOT) -I$(HDDRROOT)/$(ARCH) -I$(HDDRROOT)/protocol 5 | 6 | CRTOBJS = $(EFIROOT)/lib/crt0-efi-$(ARCH).o 7 | CFLAGS = -O2 -fPIC -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants -mno-red-zone 8 | ifeq ($(ARCH),x86_64) 9 | CFLAGS += -DEFI_FUNCTION_WRAPPER 10 | endif 11 | 12 | CPPFLAGS = -DCONFIG_$(ARCH) 13 | FORMAT = efi-app-$(ARCH) 14 | INSTALL = install 15 | LDFLAGS = -nostdlib 16 | LDSCRIPT = $(EFIROOT)/lib/elf_$(ARCH)_efi.lds 17 | LDFLAGS += -T $(LDSCRIPT) -shared -Bsymbolic -L$(EFIROOT)/lib $(CRTOBJS) 18 | LOADLIBS = -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name) 19 | 20 | prefix = 21 | CC = $(prefix)gcc 22 | AS = $(prefix)as 23 | LD = $(prefix)ld 24 | AR = $(prefix)ar 25 | RANLIB = $(prefix)ranlib 26 | OBJCOPY = $(prefix)objcopy 27 | 28 | CN_NAME = John Doe 29 | 30 | %.efi: %.so 31 | $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \ 32 | -j .rela -j .reloc --target=$(FORMAT) $*.so $@ 33 | 34 | %.so: %.o 35 | $(LD) $(LDFLAGS) $^ -o $@ $(LOADLIBS) 36 | 37 | %.o: %.c 38 | $(CC) $(INCLUDES) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ 39 | 40 | TARGETS = myloader.efi 41 | KEY = MOK.key MOK.crt 42 | CERT = MOK.cer 43 | 44 | all: $(TARGETS) 45 | 46 | sign: $(CERT) $(TARGETS) 47 | sbsign --key MOK.key --cert MOK.crt $(TARGETS) 48 | 49 | $(CERT): $(KEY) 50 | openssl x509 -in MOK.crt -out MOK.cer -outform DER 51 | 52 | $(KEY): 53 | openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -out MOK.crt -nodes -days 3650 -subj "/CN=$(CN_NAME)/" 54 | 55 | clean: 56 | rm -f $(TARGETS) $(TARGETS).signed 57 | 58 | clean_key: 59 | rm -f $(KEY) $(CERT) 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What's this 2 | 3 | Linux boot loader for UEFI environment 4 | 5 | # How to use it 6 | 7 | 1. Build kernel not to use initrd 8 | 9 | 2. Write kernel cmdline in Options variable in myloader.c 10 | 11 | 3. Make 12 | 13 | 4. Put your kernel (its name as a vmlinuz) and SimpleMyLoader.efi in EFI System Partition root directory 14 | 15 | 5. Boot with SimpleMyLoader 16 | 17 | # Attention 18 | 19 | this program is depend on gnu-efi library 20 | 21 | # LICENSE 22 | 23 | This software is released under the 2-clause BSD license, see COPYING 24 | -------------------------------------------------------------------------------- /myloader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | EFI_STATUS 5 | efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) 6 | { 7 | EFI_DEVICE_PATH *Path; 8 | EFI_LOADED_IMAGE *LoadedImageParent; 9 | EFI_LOADED_IMAGE *LoadedImage; 10 | EFI_HANDLE Image; 11 | CHAR16 *Options = L"root=/dev/sda2 rootfstype=btrfs rw quiet splash"; 12 | EFI_STATUS Status=EFI_SUCCESS; 13 | 14 | InitializeLib(ImageHandle, SystemTable); 15 | Print(L"Hello, EFI!\n"); 16 | 17 | Status = uefi_call_wrapper(BS->OpenProtocol, 6, ImageHandle, &LoadedImageProtocol, &LoadedImageParent, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); 18 | if (EFI_ERROR(Status)) { 19 | Print(L"Could not get LoadedImageProtocol handler %r\n", Status); 20 | return Status; 21 | } 22 | 23 | Path = FileDevicePath(LoadedImageParent->DeviceHandle, L"\\vmlinuz"); 24 | if (Path == NULL) { 25 | Print(L"Could not get device path."); 26 | return EFI_INVALID_PARAMETER; 27 | } 28 | 29 | Status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, ImageHandle, Path, NULL, 0, &Image); 30 | if (EFI_ERROR(Status)) { 31 | Print(L"Could not load %r", Status); 32 | FreePool(Path); 33 | return Status; 34 | } 35 | 36 | Status = uefi_call_wrapper(BS->OpenProtocol, 6, Image, &LoadedImageProtocol, &LoadedImage, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); 37 | if (EFI_ERROR(Status)) { 38 | Print(L"Could not get LoadedImageProtocol handler %r\n", Status); 39 | uefi_call_wrapper(BS->UnloadImage, 1, Image); 40 | FreePool(Path); 41 | return Status; 42 | } 43 | LoadedImage->LoadOptions = Options; 44 | LoadedImage->LoadOptionsSize = (StrLen(LoadedImage->LoadOptions)+1) * sizeof(CHAR16); 45 | 46 | Status = uefi_call_wrapper(BS->StartImage, 3, Image, NULL, NULL); 47 | uefi_call_wrapper(BS->UnloadImage, 1, Image); 48 | FreePool(Path); 49 | 50 | return EFI_SUCCESS; 51 | } 52 | -------------------------------------------------------------------------------- /myloader_win.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | EFI_STATUS 5 | efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) 6 | { 7 | EFI_DEVICE_PATH *Path; 8 | EFI_LOADED_IMAGE *LoadedImageParent; 9 | EFI_LOADED_IMAGE *LoadedImage; 10 | EFI_HANDLE Image; 11 | EFI_STATUS Status=EFI_SUCCESS; 12 | 13 | InitializeLib(ImageHandle, SystemTable); 14 | Print(L"Hello, EFI!\n"); 15 | 16 | Status = uefi_call_wrapper(BS->OpenProtocol, 6, ImageHandle, &LoadedImageProtocol, &LoadedImageParent, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); 17 | if (EFI_ERROR(Status)) { 18 | Print(L"Could not get LoadedImageProtocol handler %r\n", Status); 19 | return Status; 20 | } 21 | 22 | Path = FileDevicePath(LoadedImageParent->DeviceHandle, L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"); 23 | if (Path == NULL) { 24 | Print(L"Could not get device path."); 25 | return EFI_INVALID_PARAMETER; 26 | } 27 | 28 | Status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, ImageHandle, Path, NULL, 0, &Image); 29 | if (EFI_ERROR(Status)) { 30 | Print(L"Could not load %r", Status); 31 | FreePool(Path); 32 | return Status; 33 | } 34 | 35 | Status = uefi_call_wrapper(BS->StartImage, 3, Image, NULL, NULL); 36 | uefi_call_wrapper(BS->UnloadImage, 1, Image); 37 | FreePool(Path); 38 | 39 | return EFI_SUCCESS; 40 | } 41 | --------------------------------------------------------------------------------