Bochs works, failed PIT and beep attempts
This commit is contained in:
7
Makefile
7
Makefile
@@ -30,6 +30,13 @@ clean:
|
||||
run: all
|
||||
qemu-system-i386 '$(RUN)$(OUT_EXT)'
|
||||
|
||||
bochs: all
|
||||
bochs -qf /dev/null \
|
||||
'ata0-master: type=disk, path="$(RUN)$(OUT_EXT)", mode=flat, cylinders=1, heads=1, spt=1' \
|
||||
'boot: disk' \
|
||||
'display_library: sdl' \
|
||||
'megs: 128'
|
||||
|
||||
BIG_IMG_DIR := big_img$(TMP_EXT)
|
||||
BOOT_DIR := $(BIG_IMG_DIR)/boot
|
||||
GRUB_DIR := $(BOOT_DIR)/grub
|
||||
|
||||
11
README.md
11
README.md
@@ -29,8 +29,11 @@ Hello world programs that run without an operating system.
|
||||
1. [Interrupt zero divide](interrupt_zero_divide.S)
|
||||
1. in
|
||||
1. [in keyboard](in_keyboard.S)
|
||||
1. [in PIT (TODO)](in_pit.S)
|
||||
1. [in RTC](in_rtc.S)
|
||||
1. [in PIT (TODO)](in_pit.S)
|
||||
1. [in beep (TODO)](in_beep.S)
|
||||
1. [in beep_kernel (TODO)](in_beep_kernel.S)
|
||||
1. [in beep_illinois (TODO)](in_beep_illinois.S)
|
||||
1. [in mouse (TODO)](in_mouse.S)
|
||||
1. APM
|
||||
1. [APM shutdown](apm_shutdown.S)
|
||||
@@ -52,7 +55,7 @@ Hello world programs that run without an operating system.
|
||||
|
||||
## Getting started
|
||||
|
||||
sudo apt-get install build-essential gnu-efi qemu nasm xorriso
|
||||
sudo apt-get install bochs bochs-sdl build-essential gnu-efi qemu nasm xorriso
|
||||
|
||||
### Emulator
|
||||
|
||||
@@ -65,6 +68,10 @@ Run a given program:
|
||||
make run RUN=min
|
||||
make run RUN=bios_one_char
|
||||
|
||||
Use Bochs instead of QEMU:
|
||||
|
||||
make bochs RUN=min
|
||||
|
||||
Tested on Ubuntu 14.04 AMD64.
|
||||
|
||||
### Real hardware
|
||||
|
||||
17
TODO.md
17
TODO.md
@@ -8,7 +8,20 @@
|
||||
- instructions
|
||||
|
||||
- cache: wbinvd
|
||||
- outb inb
|
||||
|
||||
- inb outb
|
||||
|
||||
Answer with bare metal Tetris
|
||||
|
||||
- http://stackoverflow.com/questions/8365746/what-does-outb-in-att-asm-mean
|
||||
- http://stackoverflow.com/questions/3215878/what-are-in-out-instructions-in-x86-used-for
|
||||
- http://wiki.osdev.org/Text_UI
|
||||
|
||||
Port 0x80 on Linux kenrnel: https://github.com/torvalds/linux/blob/v4.2/arch/x86/boot/boot.h#L78 http://stackoverflow.com/questions/6793899/what-does-the-0x80-port-address-connects
|
||||
|
||||
Port 0x61 speaker https://courses.engr.illinois.edu/ece390/books/labmanual/io-devices-speaker.html
|
||||
|
||||
- http://wiki.osdev.org/GUI
|
||||
- lgdtl, paging http://stackoverflow.com/questions/21128311/the-physical-address-of-global-descriptor-table http://stackoverflow.com/questions/7415515/problem-accessing-control-registers-cr0-cr2-cr3
|
||||
- lidtl, interrupts, IDTR
|
||||
- https://en.wikipedia.org/wiki/Double_fault
|
||||
@@ -62,7 +75,7 @@
|
||||
|
||||
- play with hardware
|
||||
|
||||
- keyboard through interrupt (high level int 16 bios done)
|
||||
- keyboard through interrupt (high level BIOS int 16 that waits for input done)
|
||||
- keyboard protected mode: http://stackoverflow.com/questions/219120/x86-assembly-protected-mode-keyboard-access
|
||||
- set a pixel on screen in protected mode http://stackoverflow.com/questions/14419088/assembly-draw-a-pixel-on-the-screen-in-protected-mode
|
||||
- USB
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
- <https://github.com/scanlime/metalkit> A more automated / general bare metal compilation system. Untested, but looks promising.
|
||||
|
||||
- <https://courses.engr.illinois.edu/ece390/books/labmanual/index.html> Illinois course from 2004
|
||||
|
||||
The following did not work on my machine out of the box:
|
||||
|
||||
- <https://github.com/apparentlymart/ToyOS>
|
||||
|
||||
18
common.h
18
common.h
@@ -44,6 +44,8 @@ Print a single immediate byte or 8 bit register.
|
||||
Usage: character 'A' (ASCII 61):
|
||||
|
||||
PUTS(61)
|
||||
|
||||
Clobbers: ax
|
||||
*/
|
||||
#define PUTC(c) \
|
||||
mov $0x0E, %ah;\
|
||||
@@ -54,21 +56,23 @@ Usage: character 'A' (ASCII 61):
|
||||
Convert a byte to hex ASCII value.
|
||||
c: r/m8 byte to be converted
|
||||
Output: two ASCII characters, is stored in `al:bl`
|
||||
Clobbers: ax
|
||||
http://stackoverflow.com/questions/3853730/printing-hexadecimal-digits-with-assembly
|
||||
*/
|
||||
#define HEX(c) GAS_HEX c
|
||||
.macro GAS_HEX c
|
||||
mov \c, %al
|
||||
mov \c, %bl
|
||||
mov \c, %ah
|
||||
shr $4, %al
|
||||
GAS_HEX_NIBBLE al
|
||||
and $0x0F, %bl
|
||||
GAS_HEX_NIBBLE bl
|
||||
and $0x0F, %ah
|
||||
GAS_HEX_NIBBLE ah
|
||||
.endm
|
||||
|
||||
/*
|
||||
Convert the low nibble of a r8 reg to ASCII of 8-bit in-place.
|
||||
reg: r8 to be converted
|
||||
Clobbered registers: none
|
||||
Output: stored in reg itself. Letters are uppercase.
|
||||
*/
|
||||
.macro GAS_HEX_NIBBLE reg
|
||||
@@ -84,10 +88,16 @@ letter:
|
||||
end:
|
||||
.endm
|
||||
|
||||
/*
|
||||
Print a byte as two hexadecimal digits.
|
||||
|
||||
Clobbers: ax, dl
|
||||
*/
|
||||
#define PRINT_HEX(reg) \
|
||||
HEX(<reg>);\
|
||||
mov %ah, %dl;\
|
||||
PUTC(%al);\
|
||||
PUTC(%bl)
|
||||
PUTC(%dl)
|
||||
|
||||
#define PRINT_NEWLINE \
|
||||
PUTC($0x0A);\
|
||||
|
||||
10
in.md
10
in.md
@@ -1,8 +1,16 @@
|
||||
# in
|
||||
|
||||
# out
|
||||
|
||||
IO operations.
|
||||
|
||||
Do not work with immediates: only registers or memory locations.
|
||||
|
||||
## Bit 0x80
|
||||
|
||||
TODO http://wiki.osdev.org/CMOS#Getting_Current_Date_and_Time_from_RTC says:
|
||||
|
||||
/* since the 0x80 bit of al is not set, NMI is active */
|
||||
out 0x70,al
|
||||
out 0x70, al
|
||||
|
||||
What does it mean?
|
||||
|
||||
27
in_beep.S
Normal file
27
in_beep.S
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
The beep circuit is linked to the PIT.
|
||||
|
||||
I think it is possible to make a beep after a certain amount of time passes.
|
||||
|
||||
http://fly.srk.fer.hr/GDM/articles/sndmus/speaker1.html
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
.equ div, 1193181 / 1000;
|
||||
|
||||
BEGIN
|
||||
start:
|
||||
PUTC($0x61)
|
||||
mov $0xb6, %al
|
||||
out %al, $0x43 /* Ctr 2, squarewave, load, binary */
|
||||
mov div, %al
|
||||
out %al, $0x42 /* LSB of counter */
|
||||
mov div, %al
|
||||
shr $8, %al
|
||||
out %al, $0x42 /* MSB of counter */
|
||||
in $0x61, %al /* Dummy read of System Control Port B */
|
||||
mov $0x03, %al
|
||||
out %al, $0x61 /* Enable timer 2 output to speaker */
|
||||
jmp start
|
||||
END
|
||||
37
in_beep_illinois.S
Normal file
37
in_beep_illinois.S
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
https://courses.engr.illinois.edu/ece390/books/labmanual/io-devices-speaker.html
|
||||
|
||||
TODO not working on QEMU
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
BEGIN
|
||||
start:
|
||||
PUTC($0x61)
|
||||
|
||||
movb $182,%al # Prepare the speaker for the
|
||||
outb %al, $0x43 # note.
|
||||
movw $4560,%ax # Frequency number (in decimal)
|
||||
# for middle C.
|
||||
outb %al, $0x42 # Output low byte.
|
||||
movb %ah,%al # Output high byte.
|
||||
outb %al, $0x42
|
||||
inb $0x61,%al # Turn on note (get value from
|
||||
# port 61h).
|
||||
orb $0b00000011,%al # Set bits 1 and 0.
|
||||
outb %al, $0x61 # Send new value.
|
||||
movw $25,%bx # Pause for duration of note.
|
||||
.pause1:
|
||||
movw $65535,%cx
|
||||
.pause2:
|
||||
decw %cx
|
||||
jne .pause2
|
||||
decw %bx
|
||||
jne .pause1
|
||||
inb $0x61,%al # Turn off note (get value from
|
||||
# port 61h).
|
||||
andb $0b11111100,%al # Reset bits 1 and 0.
|
||||
outb %al, $0x61 # Send new value.
|
||||
|
||||
jmp start
|
||||
END
|
||||
25
in_beep_kernel.S
Normal file
25
in_beep_kernel.S
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Extracted from: https://github.com/torvalds/linux/blob/v4.2/arch/x86/realmode/rm/wakemain.c#L38
|
||||
|
||||
TODO not working on QEMU
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
.equ div, 1193181 / 1000;
|
||||
|
||||
BEGIN
|
||||
start:
|
||||
PUTC($0x61)
|
||||
mov $0xb6, %al
|
||||
out %al, $0x43 /* Ctr 2, squarewave, load, binary */
|
||||
mov div, %al
|
||||
out %al, $0x42 /* LSB of counter */
|
||||
mov div, %al
|
||||
shr $8, %al
|
||||
out %al, $0x42 /* MSB of counter */
|
||||
in $0x61, %al /* Dummy read of System Control Port B */
|
||||
mov $0x03, %al
|
||||
out %al, $0x61 /* Enable timer 2 output to speaker */
|
||||
jmp start
|
||||
END
|
||||
40
in_pit.S
40
in_pit.S
@@ -1,10 +1,46 @@
|
||||
/*
|
||||
TODO http://wiki.osdev.org/PIT
|
||||
# PIT
|
||||
|
||||
TODO get working
|
||||
|
||||
TODO answer with example http://stackoverflow.com/questions/13950264/does-using-tsc-as-clock-source-improve-timer-and-scheduling-granularity
|
||||
|
||||
Programmable interrupt timer.
|
||||
|
||||
Can generate periodic interrupts, or sounds.
|
||||
|
||||
The kernel has a Morse code encoder with it. https://github.com/torvalds/linux/blob/v4.2/arch/x86/realmode/rm/wakemain.c#L38
|
||||
|
||||
Going to use in 0x40
|
||||
|
||||
## 1193181
|
||||
|
||||
Magic number that is the frequency of the oscillator.
|
||||
|
||||
http://f.osdev.org/viewtopic.php?f=1&t=15503
|
||||
|
||||
## Bibliography
|
||||
|
||||
- https://en.wikipedia.org/wiki/Intel_8253
|
||||
- http://wiki.osdev.org/PIT
|
||||
- http://kernelx.weebly.com/programmable-interval-timer.html
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define PIT_CHANNEL0 $0x40
|
||||
#define PIT_CHANNEL1 $0x41
|
||||
#define PIT_CHANNEL2 $0x42
|
||||
#define PIT_CMDREG $0x43
|
||||
|
||||
BEGIN
|
||||
hlt
|
||||
start:
|
||||
#u16 div = 1193181/hz;
|
||||
# Linux kernel
|
||||
#outb(0xb6, 0x43); /* Ctr 2, squarewave, load, binary */
|
||||
#outb(div, 0x42); /* LSB of counter */
|
||||
#outb(div >> 8, 0x42); /* MSB of counter */
|
||||
#enable = 0x03; /* Turn on speaker */
|
||||
#inb(0x61); /* Dummy read of System Control Port B */
|
||||
#outb(enable, 0x61); /* Enable timer 2 output to speaker */
|
||||
END
|
||||
|
||||
27
in_rtc.S
27
in_rtc.S
@@ -1,14 +1,35 @@
|
||||
/*
|
||||
TODO http://wiki.osdev.org/RTC
|
||||
# in RTC
|
||||
|
||||
Real time clock.
|
||||
|
||||
Gives wall time with precision of seconds.
|
||||
|
||||
Uses a separate battery to keep going.
|
||||
|
||||
http://stackoverflow.com/questions/1465927/how-can-i-access-system-time-using-nasm
|
||||
|
||||
http://wiki.osdev.org/RTC
|
||||
|
||||
http://wiki.osdev.org/CMOS
|
||||
|
||||
Kenrel 4.2 usage: https://github.com/torvalds/linux/blob/v4.2/arch/x86/kernel/rtc.c#L121
|
||||
|
||||
http://stackoverflow.com/questions/1465927/how-can-i-access-system-time-using-nasm
|
||||
## Milliseconds
|
||||
|
||||
Not possible. Must use the PIT.
|
||||
|
||||
## Time zone
|
||||
|
||||
QEMU uses UTC.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
BEGIN
|
||||
|
||||
/*
|
||||
TODO what do those numbers mean? Where is this all documented?
|
||||
*/
|
||||
.equ RTCaddress, 0x70
|
||||
.equ RTCdata, 0x71
|
||||
|
||||
@@ -68,6 +89,4 @@ update_in_progress:
|
||||
PRINT_NEWLINE
|
||||
|
||||
jmp update_in_progress
|
||||
|
||||
hlt
|
||||
END
|
||||
|
||||
8
nasm/bios_one_char.asm
Normal file
8
nasm/bios_one_char.asm
Normal file
@@ -0,0 +1,8 @@
|
||||
org 0x7c00
|
||||
bits 16
|
||||
cli
|
||||
mov ax, 0x0E61
|
||||
int 0x10
|
||||
hlt
|
||||
times 510 - ($-$$) db 0
|
||||
dw 0xaa55
|
||||
Reference in New Issue
Block a user