big-img, chainload self

This commit is contained in:
Ciro Santilli
2015-09-18 11:35:08 +02:00
parent 793df24519
commit 7dc6e56e16
10 changed files with 147 additions and 7 deletions

1
.gitignore vendored
View File

@@ -5,3 +5,4 @@
*.iso
*.o
*.so
*.tmp

View File

@@ -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)'

View File

@@ -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
View 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
View 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
View 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

View File

@@ -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
View 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 '$<'

View File

@@ -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>

View File

@@ -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
}