Set DS to make work on hardware, more failed UEFI attempts
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,6 @@
|
||||
*.bin
|
||||
*.efi
|
||||
*.img
|
||||
*.iso
|
||||
*.o
|
||||
*.so
|
||||
|
||||
3
Makefile
3
Makefile
@@ -1,8 +1,5 @@
|
||||
.POSIX:
|
||||
|
||||
-include params.makefile
|
||||
|
||||
BITS ?= 32
|
||||
IN_EXT ?= .S
|
||||
LD ?= ld
|
||||
# Use gcc so that the preprocessor will run first.
|
||||
|
||||
19
README.md
19
README.md
@@ -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>
|
||||
|
||||
|
||||
1
TODO.md
1
TODO.md
@@ -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
6
a.ld
@@ -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 :
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "common.h"
|
||||
BEGIN
|
||||
cli
|
||||
mov $msg, %si
|
||||
mov $0x0e, %ah
|
||||
loop:
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# More minimal than the hello world.
|
||||
#include "common.h"
|
||||
BEGIN
|
||||
cli
|
||||
mov $0x40, %al
|
||||
mov $0x0e, %ah
|
||||
int $0x10
|
||||
|
||||
5
common.h
5
common.h
@@ -1,2 +1,5 @@
|
||||
#define BEGIN .code16
|
||||
#define BEGIN .code16; \
|
||||
cli; \
|
||||
mov $0x0000, %ax; \
|
||||
mov %ax, %ds
|
||||
#define END
|
||||
|
||||
14
min.S
14
min.S
@@ -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
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
.global _start
|
||||
_start:
|
||||
cli
|
||||
mov $0x0000, %ax
|
||||
mov %ax, %ds
|
||||
mov $msg, %si
|
||||
mov $0x0e, %ah
|
||||
loop:
|
||||
|
||||
@@ -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
6
uefi/Makefile.bak
Normal file
@@ -0,0 +1,6 @@
|
||||
.POSIX:
|
||||
|
||||
.PHONY: run
|
||||
|
||||
run:
|
||||
qemu-system-32 -bios ovmf.fd
|
||||
@@ -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.
|
||||
|
||||
22
uefi/main.c
22
uefi/main.c
@@ -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;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user