Mercurial > hg > Members > taiki > EFIKernel
changeset 15:ac5d699b9787
add config and open.
author | taiki |
---|---|
date | Tue, 29 Jan 2013 14:45:00 +0900 |
parents | 30ba02c504a0 (diff) 09ced7d8f64a (current diff) |
children | 2013da6b3211 |
files | boot/Makefile boot/bootx64.c boot/bootx64.efi |
diffstat | 7 files changed, 154 insertions(+), 72 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Tue Jan 22 02:39:35 2013 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -ARCH =$(shell uname -m |sed s,i[3456789]86,ia32,) -LIB_PATH = /usr/lib64 -EFI_INCLUDE = /usr/include/efi -EFI_INCLUDES = -nostdinc -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol - -EFI_PATH = /usr/lib64/gnuefi -EFI_CRT_OBJS = $(EFI_PATH)/crt0-efi-$(ARCH).o -EFI_LDS = $(EFI_PATH)/elf_$(ARCH)_efi.lds - -CFLAGS = -fno-stack-protector -fpic -fshort-wchar -mno-red-zone $(EFI_INCLUDES) -ifeq ($(ARCH),x86_64) - CFLAGS += -DEFI_FUNCTION_WRAPPER -endif - -LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) -L$(LIB_PATH) \ - $(EFI_CRT_OBJS) -lefi -lgnuefi - -TARGET = bootx64.efi -OBJS = bootx64.o -SOURCES = bootx64.c - -all: $(TARGET) - -bootx64.so: $(OBJS) - $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) - -%.efi: %.so - objcopy -j .text -j .sdata -j .data \ - -j .dynamic -j .dynsym -j .rel \ - -j .rela -j .reloc -j .eh_frame \ - --target=efi-app-$(ARCH) $^ $@ - -clean: - rm -rf $(TARGET) *.o *.so
--- a/Makefile.def Tue Jan 22 02:39:35 2013 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -CC = elf-cbc-gcc-4.6.0 -LD = x86_64-elf-ld -EFI_TOOLS = /Users/taira/cross/EFI_TOOLS/bin -OBJCOPY = x86_64-pc-mingw32-objcopy
--- a/boot/Makefile Tue Jan 22 02:39:35 2013 +0900 +++ b/boot/Makefile Tue Jan 29 14:45:00 2013 +0900 @@ -1,21 +1,23 @@ ARCH = $(shell uname -m | sed s,i[3456789]86,ia32,) -EFI_INCLUDE = /usr/local/include/efi +EFI_INCLUDE = /usr/include/efi EFI_INCLUDES = -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol -EFI_PATH = /usr/local/lib +EFI_PATH = /usr/lib64/gnuefi +EFI_LIB_PATH = /usr/lib64 LIB_GCC = $(shell $(CC) -print-libgcc-file-name) -EFI_LIBS = -lefi -lgnuefi $(LIB_GCC) $(EFI_PATH)/libgnuefi.a $(EFI_PATH)/libefi.a +EFI_LIBS = -lefi -lgnuefi $(LIB_GCC) EFI_CRT_OBJS = $(EFI_PATH)/crt0-efi-$(ARCH).o EFI_LDS = $(EFI_PATH)/elf_$(ARCH)_efi.lds -CFLAGS = -O2 -mno-red-zone -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -fno-merge-constants -Wall -Werror $(EFI_INCLUDES) +CFLAGS = -O2 -g -mno-red-zone -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -fno-merge-constants -Wall -Werror $(EFI_INCLUDES) ifeq ($(ARCH),x86_64) CFLAGS += -DEFI_FUNCTION_WRAPPER endif -LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) $(EFI_CRT_OBJS) +LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_LIB_PATH) $(EFI_CRT_OBJS) TARGET = bootx64.efi OBJS = bootx64.o + all: $(TARGET) bootx64.efi: $(OBJS)
--- a/boot/bootx64.c Tue Jan 22 02:39:35 2013 +0900 +++ b/boot/bootx64.c Tue Jan 29 14:45:00 2013 +0900 @@ -1,37 +1,164 @@ -#include <efi.h> -#include <efilib.h> +/* + * This program is EFI boot loader. + * load Mach-O kernel, and locate on memory, and jump kernel. + * + * Author: Taiki TAIRA. + */ + +#include "bootx64.h" + +INTN +efi_error(CHAR16* error_massage, EFI_STATUS status) +{ + Print(L"%s", error_massage); + if (status < 0) return ERROR; + return SUCCESS; +} + +EFI_STATUS +load_mach_o() +{ + Print(L"kernel load ... \n"); + return EFI_SUCCESS; +} + +EFI_STATUS +open(CHAR16 *name, UINTN *fd, fs_t *fs) +{ + EFI_STATUS status; + EFI_FILE_HANDLE fh; + + if (name == NULL || fd == NULL) return EFI_INVALID_PARAMETER; + + status = uefi_call_wrapper(fs->volume->Open, 5, fs->volume, &fh, name, EFI_FILE_MODE_READ, (UINT64)0); + if (status == EFI_SUCCESS) { + *fd = (UINTN)fh; + } + return status; +} + +EFI_STATUS +config_fs_one(EFI_HANDLE dev, VOID *fs) +{ + EFI_STATUS status; + EFI_FILE_IO_INTERFACE *volume; + EFI_FILE_HANDLE volume_fh; + EFI_GUID LocalFsProtocol = LOCALFS_PROTOCOL; + + status = uefi_call_wrapper(BS->HandleProtocol, 3, dev, &FileSystemProtocol, (VOID **)&volume); + if (EFI_ERROR(status)) return EFI_INVALID_PARAMETER; + + /* alloc */ + + status = uefi_call_wrapper(volume->OpenVolume, 2, volume, &volume_fh); + if (EFI_ERROR(status)) { + Print(L"Can not open volume.\n"); + return status; + } + Print(L"Open volume.\n"); + + fs_t *fs_tmp = (fs_t *)fs; + + SetMem(fs, sizeof(fs_t), 0); + + fs_tmp->dev = dev; + fs_tmp->volume = volume_fh; -#define LOCALFS_F2FD(f) ((UINTN)(f)) -#define LOCALFS_FD2F(fd) ((EFI_FILE_HANDLE)(fd)) + status = LibInstallProtocolInterfaces(&dev, &LocalFsProtocol, fs, NULL); + if (EFI_ERROR(status)) return status; + /* free */ + + return EFI_SUCCESS; +} + +EFI_STATUS +config_fs(EFI_HANDLE boot_handle, fs_t *fs, dev_tab_t *boot_dev) +{ + UINTN size = 0; + UINTN i; + EFI_GUID *proto = NULL; + + Print(L"configure filesystems for all volume. \n"); + + uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, &FileSystemProtocol, NULL, &size, NULL); + if (size == 0) return EFI_UNSUPPORTED; + + /* alloc */ + + dev_tab_t *dev_tab = NULL; // all devices + EFI_STATUS status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, &FileSystemProtocol, NULL, &size, (VOID **)dev_tab); + if (status != EFI_SUCCESS) { + efi_error(L"can't get handler.\n", status); + /* free */ + return status; + } + + UINTN ndev = size / sizeof(EFI_HANDLE); + + for (i = 0; i < ndev; i++) { + VOID *fs = NULL; + config_fs_one(dev_tab[i].dev, &fs); + dev_tab[i].fs = fs; + } + + status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, proto, NULL, &size, NULL); + if (EFI_ERROR(status)) { + Print(L"No useable filesystem found.\n"); + return status; + } + + SetMem(proto, sizeof(EFI_HANDLE), 0); + + uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, &proto, NULL, &size, NULL); + + EFI_HANDLE *tab = NULL; + + SetMem(tab, size, 0); + + status = uefi_call_wrapper(BS->LocateHandle, 5, ByProtocol, proto, NULL, &size, tab); + if (status != EFI_SUCCESS) { + Print(L"faild to get handles\n"); + } + + size /= sizeof(EFI_HANDLE); + + UINTN idx = 0; + + for (i=0; i<size; i++) { + dev_tab[idx].dev = tab[i]; + if (tab[i] == boot_handle) boot_dev = dev_tab + idx; + idx++; + } + + return EFI_SUCCESS; +} + +/* start cbc kernel boot loader. */ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *system_table) { InitializeLib(image, system_table); - - //EFI_FILE_HANDLE volume, fh; - EFI_LOADED_IMAGE *info; CHAR16 *kname = L"kernel"; - Print(L"Boot start. %s , %d:\n", kname); + Print(L"Boot start. %s\n", kname); uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x0, 0, NULL); Print(L"Set watchdog timer.\n"); - EFI_STATUS status = uefi_call_wrapper(BS->HandleProtocol, 3, image, &LoadedImageProtocol, (VOID **) &info); - // status = uefi_call_wrapper(volume->Open, 5, volume, &fh, name, EFI_FILE_MODE_READ, (UINT64)0); - - if (status == EFI_SUCCESS) { - Print(L"Opening kernel executable file is success.\n"); - } else { - Print(L"Invalid open kernel executable file.\n"); + EFI_STATUS status = uefi_call_wrapper(BS->HandleProtocol, 3, image, &LoadedImageProtocol, (VOID **) &info); + if (efi_error(L"Load error.\n", status)) { + return EFI_LOAD_ERROR; } - while (1) - { - asm volatile ("cli" : : ); - } + fs_t fs; + dev_tab_t boot_dev; + status = config_fs(info->DeviceHandle, &fs, &boot_dev); - return EFI_SUCCESS; + UINTN fd; + open(kname, &fd, &fs); + + status = EFI_SUCCESS; + return status; }