Set DS to make work on hardware, more failed UEFI attempts

This commit is contained in:
Ciro Santilli
2015-09-10 21:55:51 +02:00
parent 2b79ac21df
commit 4fbe9f2246
14 changed files with 102 additions and 20 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,6 @@
*.bin
*.efi
*.img
*.iso
*.o
*.so

View File

@@ -1,8 +1,5 @@
.POSIX:
-include params.makefile
BITS ?= 32
IN_EXT ?= .S
LD ?= ld
# Use gcc so that the preprocessor will run first.

View File

@@ -20,16 +20,29 @@ Hello world examples of programs without an OS. A.K.A. bare bones.
## Getting started
sudo apt-get install build-essential qemu
sudo apt-get install build-essential gnu-efi qemu
make run
make run RUN=min
make run RUN=bios_one_char
Tested on Ubuntu 14.04. TODO: get working on real hardware:
Tested on Ubuntu 14.04.
Run on real hardware: insert as USB, determine its device (`/dev/sdX`) with:
sudo lsblk
sudo fdisk -l
then run:
sudo dd if=bios_hello_world.img of=/dev/sdX
into an USB did not work.
Then:
- insert the USB in a computer
- during boot, hit some special key, usually F12
- choose to boot from the USB
Tested on: ThinkPad T400.
More assembly info at: <https://github.com/cirosantilli/assembly-cheat>

View File

@@ -1,6 +1,5 @@
# TODO
- make work on real hardware
- ACPI
- get multiboot working
- reboot computer. Would put QEMU into an infinite reboot loop. Awesome.

6
a.ld
View File

@@ -1,6 +1,10 @@
SECTIONS
{
/* We could also pass the -Ttext 0x7C00 to as instead of doing this. */
/*
We could also pass the -Ttext 0x7C00 to as instead of doing this.
If your program does not have any memory accesses, you can omit this.
*/
. = 0x7c00;
.text :
{

View File

@@ -1,6 +1,5 @@
#include "common.h"
BEGIN
cli
mov $msg, %si
mov $0x0e, %ah
loop:

View File

@@ -2,7 +2,6 @@
# More minimal than the hello world.
#include "common.h"
BEGIN
cli
mov $0x40, %al
mov $0x0e, %ah
int $0x10

View File

@@ -1,2 +1,5 @@
#define BEGIN .code16
#define BEGIN .code16; \
cli; \
mov $0x0000, %ax; \
mov %ax, %ds
#define END

14
min.S
View File

@@ -6,5 +6,19 @@
/* Don't listen to interrupts. */
cli
/*
Zero ds.
This is only needed if we are going to access memory.
The program might work on QEMU without this, but fail on real hardware:
http://stackoverflow.com/questions/32508919/how-to-produce-a-minimal-bios-hello-world-boot-sector-with-gcc-that-works-from-a
You cannot write immediates direclty to it, must pass through ax:
http://stackoverflow.com/questions/19074666/8086-why-cant-we-move-an-immediate-data-into-segment-register
*/
mov $0x0000, %ax
mov %ax, %ds
/* Stop the processor. */
hlt

View File

@@ -2,6 +2,8 @@
.global _start
_start:
cli
mov $0x0000, %ax
mov %ax, %ds
mov $msg, %si
mov $0x0e, %ah
loop:

View File

@@ -1,6 +1,37 @@
.POSIX:
.PHONY: run
.PHONY: all clean
run:
qemu-system-32 -bios ovmf.fd
ARCH = $(shell uname -m | sed s,i[3456789]86,ia32,)
OBJS = main.o
TARGET = hello.efi
EFIINC = /usr/include/efi
EFIINCS = -I$(EFIINC) -I$(EFIINC)/$(ARCH) -I$(EFIINC)/protocol
LIB = /usr/lib
EFILIB = /usr/lib
EFI_CRT_OBJS = $(EFILIB)/crt0-efi-$(ARCH).o
EFI_LDS = $(EFILIB)/elf_$(ARCH)_efi.lds
CFLAGS = $(EFIINCS) -fno-stack-protector -fpic \
-fshort-wchar -mno-red-zone -Wall
ifeq ($(ARCH),x86_64)
CFLAGS += -DEFI_FUNCTION_WRAPPER
endif
LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared \
-Bsymbolic -L $(EFILIB) -L $(LIB) $(EFI_CRT_OBJS)
all: $(TARGET)
hello.so: $(OBJS)
ld $(LDFLAGS) $(OBJS) -o $@ -lefi -lgnuefi
%.efi: %.so
objcopy -j .text -j .sdata -j .data -j .dynamic \
-j .dynsym -j .rel -j .rela -j .reloc \
--target=efi-app-$(ARCH) $^ $@
clean:
rm -f *.efi *.o *.so

6
uefi/Makefile.bak Normal file
View File

@@ -0,0 +1,6 @@
.POSIX:
.PHONY: run
run:
qemu-system-32 -bios ovmf.fd

View File

@@ -4,10 +4,13 @@ Successor for BIOS.
TODO get a hello world program working.
- http://www.rodsbooks.com/efi-programming/hello.html Best source so far: allowed me to compile the hello world! TODO: how to run it now on QEMU and real hardware?
- http://wiki.osdev.org/UEFI
- https://fedoraproject.org/wiki/Using_UEFI_with_QEMU
- https://wiki.ubuntu.com/UEFI/OVMF
Running without image gives the UEFI shell, and a Linux kernel image booted fine with it: http://unix.stackexchange.com/a/228053/32558 , so we just need to generate the image.
OVMF.fd IA32 r15214 downloaded from: https://sourceforge.net/projects/edk2/files/OVMF/OVMF-IA32-r15214.zip/download
Included in-source for convenience, even though it is ugly.

View File

@@ -1,13 +1,23 @@
#include <efi.h>
#include <efilib.h>
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
InitializeLib(ImageHandle, SystemTable);
Print(L"Hello, world!\n");
return EFI_SUCCESS;
}
/*
#include <efi.h>
#include <efilib.h>
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
InitializeLib(ImageHandle, SystemTable);
conout = SystemTable->ConOut;
uefi_call_wrapper(conout->OutputString, 2, conout, (CHAR16 *)L"Hello World\n\r");
return EFI_SUCCESS;
}
}
*/