build docs locally
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,4 +6,5 @@
|
||||
*.o
|
||||
*.so
|
||||
*.tmp
|
||||
/README.html
|
||||
tmp.S
|
||||
|
||||
10
Makefile
10
Makefile
@@ -1,6 +1,7 @@
|
||||
.POSIX:
|
||||
|
||||
COMMON ?= common.h
|
||||
DOC_OUT = README.html
|
||||
LD ?= ld
|
||||
LINKER_SCRIPT ?= linker.ld
|
||||
# Use gcc so that the preprocessor will run first.
|
||||
@@ -17,7 +18,7 @@ OUTS := $(sort $(foreach IN_EXT,$(NASM_EXT) $(GAS_EXT),$(patsubst %$(IN_EXT),%$(
|
||||
RUN_FILE := $(RUN)$(OUT_EXT)
|
||||
|
||||
.PRECIOUS: %$(OBJ_EXT)
|
||||
.PHONY: all clean run
|
||||
.PHONY: all clean doc run
|
||||
|
||||
all: $(OUTS)
|
||||
|
||||
@@ -36,7 +37,7 @@ all: $(OUTS)
|
||||
$(COMMON):
|
||||
|
||||
clean:
|
||||
rm -fr *$(OBJ_EXT) *$(OUT_EXT) *$(TMP_EXT)
|
||||
rm -fr '$(DOC_OUT)' *$(OBJ_EXT) *$(OUT_EXT) *$(TMP_EXT)
|
||||
|
||||
run: $(RUN_FILE)
|
||||
$(QEMU) -drive 'file=$(RUN_FILE),format=raw' -smp 2 -soundhw pcspk
|
||||
@@ -72,3 +73,8 @@ big$(OUT_EXT): all
|
||||
#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_DIR)'
|
||||
|
||||
doc: $(DOC_OUT)
|
||||
|
||||
$(DOC_OUT): README.adoc
|
||||
asciidoctor -o $@ -v $<
|
||||
|
||||
24
README.adoc
24
README.adoc
@@ -165,6 +165,13 @@ TODO: detect if we are on 16 or 32 bit automatically from control registers. Now
|
||||
|
||||
TODO: Take segmentation offsets into account: http://stackoverflow.com/questions/10354063/how-to-use-a-logical-address-in-gdb
|
||||
|
||||
=== Build the documentation locally
|
||||
|
||||
....
|
||||
make doc
|
||||
xdg-open README.html
|
||||
....
|
||||
|
||||
== Minimal examples
|
||||
|
||||
These are the first ones you should look at.
|
||||
@@ -208,6 +215,8 @@ Go into an infinite loop instead of using `hlt`:
|
||||
./run infinite_loop
|
||||
....
|
||||
|
||||
Source: link:infinite_loop.S[].
|
||||
|
||||
The outcome if visibly the same, but TODO: it likely wastes more energy in real hardware?
|
||||
|
||||
==== Linker script
|
||||
@@ -228,6 +237,21 @@ Print `hello world` after the firmware messages:
|
||||
|
||||
Source: link:bios_hello_world.S[]
|
||||
|
||||
==== C hello world
|
||||
|
||||
TODO get working.
|
||||
|
||||
Same output as <<bios-hello-world>>, but written in C:
|
||||
|
||||
....
|
||||
cd c_hello_world
|
||||
./run
|
||||
....
|
||||
|
||||
Source: link:c_hello_world[]
|
||||
|
||||
Single stage, so still limited to 512 bytes of code + data!
|
||||
|
||||
=== No linker script
|
||||
|
||||
Print `hello world` without using an explitic linker script:
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
TODO not working.
|
||||
|
||||
A single stage educational minimal C BIOS hello world example for: https://stackoverflow.com/questions/22054578/how-to-run-a-program-without-an-operating-system/32483545#32483545
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eux
|
||||
as -ggdb3 -o entry.o entry.S
|
||||
gcc -c -ggdb3 -nostartfiles -nostdlib -o main.o main.c
|
||||
ld -o main.elf -T linker.ld entry.o main.o
|
||||
ld --oformat binary -o main.img -T linker.ld entry.o main.o
|
||||
qemu-system-x86_64 -hda main.img
|
||||
@@ -1,17 +0,0 @@
|
||||
ENTRY(mystart)
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
entry.o(.text)
|
||||
*(.text)
|
||||
*(.rodata)
|
||||
*(.data)
|
||||
/**(.eh_frame)*/
|
||||
. = 0x1FE;
|
||||
SHORT(0xAA55)
|
||||
}
|
||||
/* Reserve 16 MiB of stack. */
|
||||
__stack_bottom = .;
|
||||
. = . + 0x1000000;
|
||||
__stack_top = .;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
void main(void) {
|
||||
while (1);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
.code16
|
||||
.text
|
||||
.global mystart
|
||||
mystart:
|
||||
mov %rsp, __stack_top
|
||||
mov %sp, __stack_top
|
||||
call main
|
||||
jmp .
|
||||
25
c_hello_world/linker.ld
Normal file
25
c_hello_world/linker.ld
Normal file
@@ -0,0 +1,25 @@
|
||||
ENTRY(mystart)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x7c00;
|
||||
.text : {
|
||||
entry.o(.text)
|
||||
*(.text)
|
||||
*(.data)
|
||||
*(.rodata)
|
||||
__bss_start = .;
|
||||
*(.bss)
|
||||
__bss_end = .;
|
||||
}
|
||||
/* https://stackoverflow.com/questions/53584666/why-does-gnu-ld-include-a-section-that-does-not-appear-in-the-linker-script */
|
||||
.sig : AT(ADDR(.text) + 512 - 2)
|
||||
{
|
||||
SHORT(0xaa55);
|
||||
}
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
}
|
||||
__stack_bottom = .;
|
||||
. = . + 0x1000;
|
||||
__stack_top = .;
|
||||
}
|
||||
15
c_hello_world/main.c
Normal file
15
c_hello_world/main.c
Normal file
@@ -0,0 +1,15 @@
|
||||
void main(void) {
|
||||
int i;
|
||||
char s[] = "hello world";
|
||||
for (i = 0; i < sizeof(s); ++i) {
|
||||
__asm__ (
|
||||
"mov %0, %%ax; int $0x10"
|
||||
:
|
||||
: "m" (s[i])
|
||||
: "%ax"
|
||||
);
|
||||
}
|
||||
while (1) {
|
||||
__asm__ ("hlt");
|
||||
};
|
||||
}
|
||||
7
c_hello_world/run
Executable file
7
c_hello_world/run
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eux
|
||||
as -ggdb3 --32 -o entry.o entry.S
|
||||
gcc -c -ggdb3 -m16 -nostartfiles -nostdlib -o main.o -std=c99 main.c
|
||||
ld -m elf_i386 -o main.elf -T linker.ld entry.o main.o
|
||||
objcopy -O binary main.elf main.img
|
||||
qemu-system-x86_64 -drive file=main.img,format=raw
|
||||
Reference in New Issue
Block a user