big-img, chainload self
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@
|
||||
*.iso
|
||||
*.o
|
||||
*.so
|
||||
*.tmp
|
||||
|
||||
20
Makefile
20
Makefile
@@ -8,6 +8,7 @@ MYAS ?= gcc
|
||||
OBJ_EXT ?= .o
|
||||
OUT_EXT ?= .img
|
||||
RUN ?= bios_hello_world
|
||||
TMP_EXT ?= .tmp
|
||||
|
||||
INS := $(wildcard *$(IN_EXT))
|
||||
OUTS := $(patsubst %$(IN_EXT),%$(OUT_EXT),$(INS))
|
||||
@@ -24,7 +25,24 @@ all: $(OUTS)
|
||||
$(MYAS) -c -o '$@' '$<'
|
||||
|
||||
clean:
|
||||
rm -f *$(OBJ_EXT) *$(OUT_EXT)
|
||||
rm -fr *$(OBJ_EXT) *$(OUT_EXT) *$(TMP_EXT)
|
||||
|
||||
run: all
|
||||
qemu-system-i386 '$(RUN)$(OUT_EXT)'
|
||||
|
||||
BIG_IMG_DIR := big_img$(TMP_EXT)
|
||||
BOOT_DIR := $(BIG_IMG_DIR)/boot
|
||||
GRUB_DIR := $(BOOT_DIR)/grub
|
||||
big-img: all
|
||||
rm -rf '$(BIG_IMG_DIR)'
|
||||
mkdir -p '$(GRUB_DIR)'
|
||||
for out in $(OUTS); do\
|
||||
printf "menuentry \"$${out%.*}\" {\n chainloader /boot/$$out\n}\n" >> '$(GRUB_DIR)/grub.cfg';\
|
||||
cp "$$out" '$(BOOT_DIR)';\
|
||||
done
|
||||
# TODO why does this fail to boot properly?
|
||||
#make -C multiboot/hello-world
|
||||
#mkdir -p '$(BOOT_DIR)/multiboot'
|
||||
#printf "menuentry \"multiboot/hello-world\" {\n chainloader /boot/multiboot/hello-world.img\n}\n" >> '$(GRUB_DIR)/grub.cfg';\
|
||||
#cp multiboot/hello-world/main.img '$(BOOT_DIR)/multiboot/hello-world.img'
|
||||
grub-mkrescue -o 'big.img' '$(BIG_IMG_DIR)'
|
||||
|
||||
21
README.md
21
README.md
@@ -10,6 +10,9 @@ Hello world programs that run without an operating system.
|
||||
1. BIOS
|
||||
1. [BIOS one char](bios_one_char.S)
|
||||
1. [BIOS hello world](bios_hello_world.S)
|
||||
1. [BIOS newline](bios_newline.S)
|
||||
1. [BIOS carriage return](bios_carriage_return.S)
|
||||
1. [BIOS clear screen](bios_clear_screen.S)
|
||||
1. APM
|
||||
1. [APM shutdown](apm_shutdown.S)
|
||||
1. [APM shutdown 2](apm_shutdown2.S)
|
||||
@@ -31,6 +34,8 @@ Hello world programs that run without an operating system.
|
||||
|
||||
sudo apt-get install build-essential gnu-efi qemu nasm xorriso
|
||||
|
||||
### Emulator
|
||||
|
||||
Run the default program on QEMU:
|
||||
|
||||
make run
|
||||
@@ -42,7 +47,9 @@ Run a given program:
|
||||
|
||||
Tested on Ubuntu 14.04 AMD64.
|
||||
|
||||
To run on real hardware, insert an USB, determine its device (`/dev/sdX`) with:
|
||||
### Real hardware
|
||||
|
||||
Insert an USB, determine its device (`/dev/sdX`) with:
|
||||
|
||||
sudo lsblk
|
||||
sudo fdisk -l
|
||||
@@ -58,3 +65,15 @@ Then:
|
||||
- choose to boot from the USB
|
||||
|
||||
Tested on: ThinkPad T400.
|
||||
|
||||
#### Big image
|
||||
|
||||
Create a `big.img` that contains all examples that can be booted from GRUB:
|
||||
|
||||
make big-img
|
||||
|
||||
Now if you do:
|
||||
|
||||
sudo dd if=big.img of=/dev/sdX
|
||||
|
||||
you can test several examples with a single USB burn, which is much faster.
|
||||
|
||||
26
bios_carriage_return.S
Normal file
26
bios_carriage_return.S
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
What happens when a newline is output with bios.
|
||||
|
||||
Outcome:
|
||||
|
||||
hello
|
||||
world
|
||||
|
||||
Carriage returns are needed just like in old days.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
BEGIN
|
||||
mov $msg, %si
|
||||
mov $0x0e, %ah
|
||||
loop:
|
||||
lodsb
|
||||
or %al, %al
|
||||
jz halt
|
||||
int $0x10
|
||||
jmp loop
|
||||
halt:
|
||||
hlt
|
||||
msg:
|
||||
.asciz "hello\n\rworld"
|
||||
END
|
||||
29
bios_clear_screen.S
Normal file
29
bios_clear_screen.S
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Clear screen by scrolling.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
BEGIN
|
||||
|
||||
/*
|
||||
Print one char to ensure that something will be claered.
|
||||
|
||||
On some systems, BIOS messages get automatically cleared. Not the case for QEMU 2.0.0.
|
||||
*/
|
||||
mov $0x0E40, %ax
|
||||
int $0x10
|
||||
|
||||
/* Function ID. */
|
||||
mov $0x06, %ah
|
||||
/* nr. of lines to scroll, 00 means clear window. */
|
||||
mov $0x0, %al
|
||||
/* TODO: I think this is the style. */
|
||||
mov $0x7, %bh
|
||||
/* CH,CL: row,column upper left corner (00:00) */
|
||||
mov $0x0, %cx
|
||||
/* DH,DL: row,column lower right corner (24:79) */
|
||||
mov $0x184f, %dx
|
||||
int $0x10
|
||||
|
||||
hlt
|
||||
END
|
||||
26
bios_newline.S
Normal file
26
bios_newline.S
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
What happens when a newline is output with bios.
|
||||
|
||||
Outcome:
|
||||
|
||||
hello
|
||||
world
|
||||
|
||||
Carriage returns are needed just like in old days.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
BEGIN
|
||||
mov $msg, %si
|
||||
mov $0x0e, %ah
|
||||
loop:
|
||||
lodsb
|
||||
or %al, %al
|
||||
jz halt
|
||||
int $0x10
|
||||
jmp loop
|
||||
halt:
|
||||
hlt
|
||||
msg:
|
||||
.asciz "hello\nworld"
|
||||
END
|
||||
@@ -1,12 +1,16 @@
|
||||
/*
|
||||
Print a single `@` character with the BIOS.
|
||||
|
||||
More minimal than the hello world.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
BEGIN
|
||||
mov $0x40, %al
|
||||
mov $0x0e, %ah
|
||||
/*
|
||||
40 == ASCII for '@'
|
||||
0E == BIOS function ID.
|
||||
*/
|
||||
mov $0x0E40, %ax
|
||||
int $0x10
|
||||
hlt
|
||||
END
|
||||
|
||||
13
grub/Makefile
Normal file
13
grub/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
.POSIX:
|
||||
|
||||
.PHONY: clean run
|
||||
|
||||
main.img:
|
||||
make -C '../mbrs' && cp '../bios_hello_world.img.sym' 'iso/boot/main.img'
|
||||
grub-mkrescue -o '$@' iso
|
||||
|
||||
clean:
|
||||
rm -f iso/boot/*.img *.img
|
||||
|
||||
run: main.img
|
||||
qemu-system-i386 -hda '$<'
|
||||
@@ -11,3 +11,5 @@ This example uses a file, but the most common way to use it is with:
|
||||
chainloader +1
|
||||
|
||||
which uses the first sector of some partition instead of a file.
|
||||
|
||||
TODO: why does it fail for hybrid ISO images? <http://superuser.com/questions/154134/grub-how-to-boot-into-iso-partition#comment1337357_154271>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
set timeout=0
|
||||
set default="0"
|
||||
menuentry "main" {
|
||||
menuentry "hello-world" {
|
||||
chainloader /boot/main.img
|
||||
}
|
||||
# Reload ourselves again.
|
||||
menuentry "self +1" {
|
||||
chainloader +1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user