Compare commits

..

No commits in common. "master" and "v0.14" have entirely different histories.

94 changed files with 7927 additions and 1761 deletions

43
.bochsrc Normal file
View File

@ -0,0 +1,43 @@
# configuration file generated by Bochs
config_interface: textconfig
display_library: x
megs: 32
romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xf0000
vgaromimage: /usr/share/bochs/VGABIOS-lgpl-latest
boot: floppy
floppya: 1_44="/dev/fd0", status=inserted
# no floppyb
ata0: enabled=0
ata1: enabled=0
ata2: enabled=0
ata3: enabled=0
parport1: enabled=1, file=""
com1: enabled=1, dev=""
usb1: enabled=1, ioaddr=0xff80, irq=10
# no sb16
floppy_bootsig_check: disabled=0
vga_update_interval: 30000
keyboard_serial_delay: 20000
keyboard_paste_delay: 100000
floppy_command_delay: 50000
ips: 500000
text_snapshot_check: 0
mouse: enabled=0
private_colormap: enabled=0
i440fxsupport: enabled=0
clock: sync=none, time0=local
# no ne2k
newharddrivesupport: enabled=1
# no loader
log: -
logprefix: %t%e%d
debugger_log: -
panic: action=fatal
error: action=report
info: action=report
debug: action=ignore
pass: action=fatal
keyboard_mapping: enabled=0, map=
keyboard_type: mf
user_shortcut: keys=none
# no cmosimage

3
.gitignore vendored
View File

@ -1,3 +0,0 @@
.rscons*
/i686-elf-gcc/
/build/

117
Makefile Normal file
View File

@ -0,0 +1,117 @@
#####################################################################
# Author: Josh Holtrop / Benjamen R. Meyer #
# Date: 02/15/04 Modified: 06/07/04 #
# Purpose: To build Josh Holtrop's OS (HOS) using GNU make #
# Note: This makefile is for use on Linux & other Unix-like systems #
#####################################################################
##############
# Variables: #
##############
# Information for creating a floppy image
# Note: FLOPPY_FS and FLOPPY_FAT_SIZE are related fields.
# FLOPPY_FAT_SIZE should be either 12 or 16,
# depending on if FLOPPY_FS is FAT12 or FAT16, respectively.
MKDOSFS_PROG=mkdosfs
FLOPPY_IMAGE=floppy.img
FLOPPY_BLOCK_COUNT=1440
FLOPPY_FS=FAT12
FLOPPY_FAT_SIZE=12
FLOPPY_MOUNT=./floppy_image
# Floppy images are good for programs like VMware and Bochs Pentium Emulator. ;-)
# Program for copying
COPY_BIN=cp
##########################################
# Build the IPL (Boot Loader) and Kernel #
##########################################
all:
# A word of warning to users :-> And a little helpful information ;-)
@echo "Installation must be done as root."
@echo "Type 'make install' to install to a floppy in drive '/dev/fd0'"
@echo "Type 'make install_img' to create a floppy image and install to it."
make -C boot
make -C kernel
#################################################
# Clean up the source directory of any binaries #
#################################################
clean:
make -C boot clean
make -C kernel clean
###########################################
# The following is for the floppy drive #
# Note: This must be done on *nix as root #
###########################################
##########################
# Make install to floppy #
##########################
install: Install_IPL File_Copy
############################################
# Write the Stage 1 IPL to the boot sector #
############################################
Install_IPL:
$(MKDOSFS_PROG) /dev/fd0
dd if=boot/stage1.bin of=/dev/fd0
#################################
# Copy the files onto the drive #
#################################
File_Copy:
- mkdir floppy_mount
@echo "Mounting floppy to ./floppy_mount..."
mount /dev/fd0 ./floppy_mount
@echo "Copying stage 2 bootloader to the floppy..."
$(COPY_BIN) boot/stage2.bin ./floppy_mount
@echo "Copying kernel to the floppy..."
$(COPY_BIN) kernel/kernel.bin ./floppy_mount
@echo "Unmounting floppy..."
umount ./floppy_mount
- rm -rf floppy_mount
############################################
# The following is for the floppy image. #
# Note: This must be done on *nix as root. #
############################################
######################################
# Create and Format the floppy image #
######################################
install_img:
$(MKDOSFS_PROG) -C -F $(FLOPPY_FAT_SIZE) -r 112 $(FLOPPY_IMAGE) $(FLOPPY_BLOCK_COUNT)
############################################
# Write the Stage 1 IPL to the boot sector #
############################################
@echo "Writing boot sector to image..."
dd if=boot/stage1.bin of=$(FLOPPY_IMAGE) seek=0
#################################
# Copy the files onto the image #
#################################
- mkdir $(FLOPPY_MOUNT)
@echo "Mounting floppy image..."
mount $(FLOPPY_IMAGE) $(FLOPPY_MOUNT) -o loop
@echo "Copying stage 2 bootloader to the floppy image..."
$(COPY_BIN) boot/stage2.bin $(FLOPPY_MOUNT)
@echo "Copying kernel to the floppy image..."
$(COPY_BIN) kernel/kernel.bin $(FLOPPY_MOUNT)
@echo "Unmounting floppy image..."
mount $(FLOPPY_IMAGE) $(FLOPPY_MOUNT) -o loop

View File

@ -1,166 +0,0 @@
path_prepend "i686-elf-gcc/bin"
configure do
rscons "i686-elf-gcc.rb", "-b", "#{build_dir}/i686-elf-gcc"
check_c_compiler "i686-elf-gcc"
check_program "genext2fs"
check_program "grub-mkstandalone"
check_program "mformat", on_fail: "Install the mtools package"
check_program "xorriso"
check_cfg package: "freetype2", on_fail: "Install libfreetype-dev", use: "freetype"
end
require "tmpdir"
# EFI (w/ GRUB) partition size (MiB)
EFI_PART_SIZE = 8
# HOS partition size (MiB)
HOS_PART_SIZE = 4
# Kernel default font size
KFONT_SIZE = 15
class BiosImage < Builder
def run(options)
unless @cache.up_to_date?(@target, nil, @sources, @env)
print_run_message("Generating BIOS boot image #{@target}", nil)
Dir.mktmpdir do |tmpdir|
# Create iso directory.
FileUtils.mkdir_p("#{tmpdir}/iso/boot/grub")
File.open("#{tmpdir}/iso/boot/grub/grub.cfg", "wb") do |fh|
fh.write(<<EOF)
set default="0"
set timeout=1
menuentry "HOS" {
insmod multiboot2
multiboot2 /hos.elf
}
EOF
end
@sources.each do |source|
FileUtils.cp(source, "#{tmpdir}/iso")
end
# Build bootable GRUB image.
system(*%W[grub-mkrescue -o #{@target} #{tmpdir}/iso], err: "#{@env.build_root}/grub-mkrescue.log")
end
@cache.register_build(@target, nil, @sources, @env)
end
true
end
end
class EfiImage < Builder
def run(options)
unless @cache.up_to_date?(@target, nil, @sources, @env)
print_run_message("Generating EFI boot image #{@target}", nil)
Dir.mktmpdir do |tmpdir|
# Build a standalone GRUB.
File.open("#{tmpdir}/grub.cfg", "wb") do |fh|
fh.write(<<EOF)
insmod part_gpt
configfile (hd0,gpt2)/grub.cfg
EOF
end
system(*%W[grub-mkstandalone -O x86_64-efi -o #{tmpdir}/BOOTX64.EFI boot/grub/grub.cfg=#{tmpdir}/grub.cfg])
# Create EFI partition.
system(*%W[dd if=/dev/zero of=#{tmpdir}/efi.part bs=1M count=#{EFI_PART_SIZE}], err: "/dev/null")
system(*%W[mformat -i #{tmpdir}/efi.part ::])
system(*%W[mmd -i #{tmpdir}/efi.part ::/EFI])
system(*%W[mmd -i #{tmpdir}/efi.part ::/EFI/BOOT])
system(*%W[mcopy -i #{tmpdir}/efi.part #{tmpdir}/BOOTX64.EFI ::/EFI/BOOT])
# Create ext2 HOS partition.
FileUtils.mkdir_p("#{tmpdir}/ext2")
@sources.each do |source|
FileUtils.cp(source, "#{tmpdir}/ext2")
end
File.open("#{tmpdir}/ext2/grub.cfg", "wb") do |fh|
fh.write(<<EOF)
set default="0"
set timeout=1
menuentry "HOS" {
insmod part_gpt
insmod multiboot2
set root=(hd0,gpt2)
multiboot2 /hos.elf
}
EOF
end
system(*%W[genext2fs -b #{HOS_PART_SIZE * 1024} -d #{tmpdir}/ext2 #{tmpdir}/ext2.part])
# Create full disk image.
system(*%W[dd if=/dev/zero of=#{@target} bs=1M count=#{EFI_PART_SIZE + HOS_PART_SIZE + 2}], err: "/dev/null")
system(*%W[parted -s #{@target} mklabel gpt])
system(*%W[parted -s #{@target} mkpart efi 1MiB #{EFI_PART_SIZE + 1}MiB])
system(*%W[parted -s #{@target} mkpart hos #{EFI_PART_SIZE + 1}MiB #{EFI_PART_SIZE + HOS_PART_SIZE + 1}MiB])
system(*%W[dd if=#{tmpdir}/efi.part of=#{@target} bs=1M seek=1 conv=notrunc], err: "/dev/null")
system(*%W[dd if=#{tmpdir}/ext2.part of=#{@target} bs=1M seek=#{1 + EFI_PART_SIZE} conv=notrunc], err: "/dev/null")
end
@cache.register_build(@target, nil, @sources, @env)
end
true
end
end
class FontGen < Builder
def run(options)
if @command
finalize_command
else
fontgen = @vars["fontgen"]
@sources += [fontgen]
command = %W[#{fontgen} #{@sources.first} #{KFONT_SIZE} #{@target}]
standard_command("FontGen <target>#{@target}<reset>", command, {})
end
end
end
class Size < Builder
def run(options)
if @command
finalize_command
else
@vars["_SOURCES"] = @sources
@vars["_TARGET"] = @target
command = @env.build_command(%w[${SIZE} ${_SOURCES}], @vars)
standard_command("Size <target>#{@target}<reset>", command, stdout: @target)
end
end
end
# FontGen Environment
fontgen_env = env "fontgen", use: "freetype" do |env|
env["CC"] = "gcc"
env.Program("^/fontgen.bin", glob("fontgen/**/*.c"))
end
# Kernel Environment
kernel_env = env "kernel" do |env|
env.add_builder(EfiImage)
env.add_builder(BiosImage)
env.add_builder(FontGen)
env.add_builder(Size)
env["OBJDUMP"] = "i686-elf-objdump"
env["SIZE"] = "i686-elf-size"
env["CCFLAGS"] += %w[-ffreestanding -Wall -O2]
env["LDFLAGS"] += %w[-ffreestanding -nostdlib -T src/link.ld]
env["LDFLAGS"] += %W[-Wl,-Map,${_TARGET}.map]
env["LIBS"] += %w[gcc]
env.FontGen("^/kfont/kfont.c", "font/Hack-Regular.ttf",
"fontgen" => fontgen_env.expand("^/fontgen.bin"))
env.barrier
env["CPPPATH"] += ["#{env.build_root}/kfont"]
env.Program("^/hos.elf", glob("src/**/*.{S,c}") + ["^/kfont/kfont.c"])
env.depends("#{env.build_root}/hos.elf", "src/link.ld")
env.Disassemble("^/hos.elf.txt", "^/hos.elf")
env.Size("^/hos.elf.size", "^/hos.elf")
env.EfiImage("^/hos-efi.img", %w[^/hos.elf])
env.BiosImage("^/hos.img", %w[^/hos.elf])
end
task "run", desc: "Run HOS in QEMU" do
img = kernel_env.expand("^/hos.img")
sh %W[qemu-system-x86_64 -hda #{img}]
end
task "run-efi", desc: "Run HOS EFI in QEMU" do
img = kernel_env.expand("^/hos-efi.img")
sh %W[qemu-system-x86_64 -bios OVMF.fd -hda #{img}]
end

32
boot/Makefile Normal file
View File

@ -0,0 +1,32 @@
#####################################################################
# Author: Josh Holtrop / Benjamen R. Meyer #
# Date: 02/15/04 #
# Purpose: To build Josh Holtrop's OS (HOS) using GNU make #
# Note: This makefile is for use on Linux & other Unix-like systems #
#####################################################################
# Assembler information:
NASM_BIN=nasm
#################
# Build the IPL #
#################
all: stage1 stage2
################
# IPL: Stage 1 #
################
stage1: stage1.asm
$(NASM_BIN) stage1.asm -o stage1.bin
################
# IPL: Stage 2 #
################
stage2: stage2.asm
$(NASM_BIN) stage2.asm -o stage2.bin
#########
# Clean #
#########
clean:
- rm *.bin *~

26
boot/bootdef.inc Normal file
View File

@ -0,0 +1,26 @@
%define VERSION "0.03" ;HOS bootloader version
%define BOOT_FAT_SEG 0x07E0 ;right after boot sector
%define BOOT_ROOT_SEG 0x0900 ;right after FAT
%define BOOT_KERNEL_SEG 0x0AC0 ;right after ROOT_DIR
%define BOOT_STAGE2_SEG 0x0B00 ;right after KERNEL_SEG
%define BOOT_STAGE2_ADD 0xB000 ;address of stage2 to jump to, org at
%define BOOT_KERNEL_ADD 0x106000 ;final pmode kernel destination - physical
%define BOOT_RD_ADD 0x200000 ;2mb for ram disk
%define BOOT_DATA_SEG 0x9000 ;data gathered by stage2 loader goes here
%define BOOT_HASRD 0x0000 ;1
%define BOOT_VESA 0x0002 ;2 - 0 for console, otherwise VESA mode
%define BOOT_VESA_OEM 0x0004 ;258 - null-terminated OEM identification string
%define BOOT_VESA_VBE 0x0106 ;512 - copy of VESA VBEInfoBlock
%define BOOT_VESA_INFO 0x0306 ;256 - copy of VESA ModeInfoBlock for selected mode
%define BOOT_MEMENTRIES 0x040A ;4 - dword = number of memmap entries
%define BOOT_MEMMAP 0x2000 ;? - memory map information
%define BOOT_DRIVE 0x7C24 ;1 - boot drive

235
boot/stage1.asm Normal file
View File

@ -0,0 +1,235 @@
;stage1.asm
;This is the stage1 section of the HOS bootloader
;It is 512 bytes to be put on the first sector of a floppy
;Author: Josh Holtrop
;Date: 03/11/04
;Modified: 05/21/04
%include "bootdef.inc"
[bits 16]
org 0x7c00
jmp short start
; --------------------------------------------------
; data portion of the "DOS BOOT RECORD"
; ----------------------------------------------------------------------
brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ
brOEM DB 'MSDOS5.0' ; 0003h - OEM ID - Windows 95B
brBPS DW 512 ; 000Bh - Bytes per sector
brSPC DB 1 ; 000Dh - Sector per cluster
brSc_b4_fat DW 1 ; 000Eh - Reserved sectors
brFATs DB 2 ; 0010h - FAT copies
brRootEntries DW 0E0H ; 0011h - Root directory entries
brSectorCount DW 2880 ; 0013h - Sectors in volume, < 32MB
brMedia DB 240 ; 0015h - Media descriptor
brSPF DW 9 ; 0016h - Sectors per FAT
brSc_p_trk DW 18 ; 0018h - Sectors per head/track
brHPC DW 2 ; 001Ah - Heads per cylinder
brSc_b4_prt DD 0 ; 001Ch - Hidden sectors
brSectors DD 0 ; 0020h - Total number of sectors
brDrive DB 0 ; 0024h - Physical drive no.
DB 0 ; 0025h - Reserved (FAT32)
DB 29H ; 0026h - Extended boot record sig (FAT32)
brSerialNum DD 404418EAH ; 0027h - Volume serial number
brLabel DB 'Holtrops OS' ; 002Bh - Volume label
brFSID DB 'FAT12 ' ; 0036h - File System ID
;------------------------------------------------------------------------
start:
jmp 0:jmphere ;ensure that cs=0 and ip=0x7c00...
jmphere:
;dl=drive number, save it!
xor ax, ax
mov ds, ax
mov [brDrive], dl
cli
mov ss, ax
mov sp, 0x7Bfe ;right under boot sector
sti
mov ax, 0xb800
mov ds, ax
mov es, ax
xor di, di
mov ax, 0x0700
mov cx, 2000
cls:
stosw
loop cls
enable_a20:
in al, 0x64
test al, 2
jnz enable_a20
mov al, 0xD1
out 0x64, al
ea20_2: in al, 0x64
and ax, byte 2
jnz ea20_2
mov al, 0xDF
out 0x60, al
unreal:
xor ax, ax
mov es, ax
mov ds, ax
lgdt [gdtr] ;load gdt
cli
push es
push ds ;save segment values
mov ebx, cr0
inc bl
mov cr0, ebx ;pmode!
mov ax, KERNEL_DATA
mov es, ax
mov ds, ax ;load segment limits
dec bl
mov cr0, ebx ;back to real mode!
pop ds
pop es ;segments back, with 4gb limits!
sti
;now lets read in the FAT and root directory so we can search for the stage2 file...
mov ax, 0x0209 ;FAT1
mov cx, 0x0002
xor dh, dh
mov dl, [brDrive]
mov bx, BOOT_FAT_SEG
mov es, bx
xor bx, bx
int 0x13
mov ax, 0x020E ;root directory
mov cx, 0x0002 ;cyl/sect
mov dh, 0x01 ;head
mov dl, [brDrive] ;drive
mov bx, BOOT_ROOT_SEG
mov es, bx
xor bx, bx
int 0x13
;k now read root directory
mov bx, BOOT_ROOT_SEG
mov ds, bx
xor si, si ;k now ds:si points to beginning of root directory
mov es, si
mov cx, 224 ;max root entries
loop_compare:
mov di, stage2
push cx
push si ;save pointer to root dir entry
mov cx, 11
loop_name:
cmpsb
loopz loop_name
jnz goon ;cx didn't get to zero, bad file
pop si
pop cx
jmp found_file ;good file, ds:si points to start of root directory entry
goon:
pop si
pop cx
add si, 32
loop loop_compare
error:
jmp $ ;halt! no kernel file found!
found_file: ;ds:si points to root dir entry
xor ax, ax
mov gs, ax
mov ax, BOOT_STAGE2_SEG
mov es, ax
mov ax, [ds:si+26]
mov bx, BOOT_FAT_SEG
mov ds, bx ;ds points to beginning of FAT
xor di, di
readstage2_loop:
cmp ax, 0xff7
jg readstage2_done
inc di
push ax
call getCHSfromCluster
mov ax, 0x0201
mov dl, [gs:BOOT_DRIVE]
xor bx, bx
int 0x13
mov bx, es
add bx, 0x0020
mov es, bx
pop ax ;current logical cluster #
mov cx, ax ;cx=logical cluster
mov dx, 3
mul dx
shr ax, 1 ;ax=logical cluster * 3 / 2
mov si, ax
test cl, 1 ;is bit0 set?
jnz odd_cluster
even_cluster:
lodsw
and ax, 0x0fff
jmp got_cluster
odd_cluster:
lodsw
shr ax, 4
got_cluster:
jmp readstage2_loop
readstage2_done:
jmp 0:BOOT_STAGE2_ADD
;------------------------------------------------------
getCHSfromCluster:
;input: ax=lba of sector on floppy (0-2879)
add ax, 31 ;convert logical cluster# to lba#
xor dx, dx ;lba->chs
mov bx, 18
div bx
inc dx
mov cl, dl ;sector# (1-18)
xor dx, dx
mov bx, 2
div bx
mov ch, al ;cylinder# (0-79)
mov dh, dl ;head# (0-1)
ret
;-------------------------------------------------------
gdtr:
dw gdt_end-gdt-1
dd gdt
gdt:
dd 0
dd 0
KERNEL_DATA equ $-gdt
db 0xff ;segment 16 = 4gb data
db 0xff
db 0x00
db 0x00
db 0x00
db 0x92
db 0xcf ;cf
db 0x00
gdt_end:
stage2: db "STAGE2 BIN"
times 510-($-$$) db 0
db 0x55, 0xaa

978
boot/stage2.asm Normal file
View File

@ -0,0 +1,978 @@
;stage2.asm
;This is the stage2 section of the HOS bootloader
;It is to be copied into the normal FAT12 filesystem to be loaded by stage1
;Author: Josh Holtrop
;Date: 03/11/04
;Modified: 05/21/04
%include "bootdef.inc"
%define VESA_MODEINFO_SEG 0x0120
%define VESA_MODELIST_SEG 0x0140
%define GOOD_MODELIST_SEG 0x0160
[bits 16]
org BOOT_STAGE2_ADD
;k now read root directory
mov bx, BOOT_ROOT_SEG
mov ds, bx
xor si, si ;k now ds:si points to beginning of root directory
mov es, si
mov cx, 224 ;max root entries
loop_compare:
mov di, kernel
push cx
push si ;save pointer to root dir entry
mov cx, 11
loop_name:
cmpsb
loopz loop_name
jnz goon ;cx didn't get to zero, bad file
pop si
pop cx
jmp found_file ;good file, ds:si points to start of root directory entry
goon:
pop si
add si, 32
pop cx
loop loop_compare
error:
jmp $ ;halt! no kernel file found!
found_file: ;ds:si points to root dir entry of kernel file
xor ax, ax
mov gs, ax
mov ax, [ds:si+26]
mov bx, BOOT_FAT_SEG
mov ds, bx ;ds points to beginning of FAT
mov edi, BOOT_KERNEL_ADD
readkernel_loop:
cmp ax, 0xff7
jg readkernel_done
push ax
call getCHSfromCluster
mov ax, 0x0201
mov dl, [gs:BOOT_DRIVE]
mov bx, BOOT_KERNEL_SEG
mov es, bx
xor bx, bx
int 0x13
mov cx, 256
xor ax, ax
mov es, ax
mov esi, BOOT_KERNEL_SEG*16
copykernel_loop:
mov ax, [es:esi]
mov [es:edi], ax
inc esi
inc esi
inc edi
inc edi
loop copykernel_loop
pop ax ;current logical cluster #
mov cx, ax ;cx=logical cluster
mov dx, 3
mul dx
shr ax, 1 ;ax=logical cluster * 3 / 2
mov si, ax
test cl, 1 ;is bit0 set?
jnz odd_cluster
even_cluster:
lodsw
and ax, 0x0fff
jmp got_cluster
odd_cluster:
lodsw
shr ax, 4
got_cluster:
jmp readkernel_loop
;------------------------------------------------------
readkernel_done: ;-------------put more real mode init stuff here!
;----ask to load RD from floppy
mov ax, 0xb800
mov es, ax
xor ax, ax
mov ds, ax
xor di, di
mov cx, 2000
mov ax, 0x0700
cls_loop:
stosw
loop cls_loop
mov dx, 0x3d4 ;move cursor off screen...
mov al, 0x0e
out dx, al
inc dx
mov al, 0xff
out dx, al
dec dx
mov al, 0x0f
out dx, al
inc dx
out dx, al
xor di, di
mov si, txt_welcome
mov ah, 0x1f
call puts
mov di, 160
mov si, txt_rd1
mov ah, 7
call puts
mov si, txt_rd2
mov di, 160*2
call puts
mov di, 160*3
mov si, txt_input
call puts
get_rd:
xor ax, ax
int 0x16
cmp al, '1'
jz got_rd
cmp al, '2'
jnz get_rd
got_rd:
stosb
sub al, '1'
push ds
mov bx, BOOT_DATA_SEG ;segment for data to send kernel
mov ds, bx
mov [ds:BOOT_HASRD], al
pop ds ;ds=0
cmp al, 0 ;dont load rd
jnz yes_rd
jmp no_rd
yes_rd:
mov cx, 80
mov edi, 0xb8000+160*4
filler_loop: ;draw a red bar
mov word [ds:edi], 0x0400+177
inc edi
inc edi
loop filler_loop
mov cx, 80 ;80 cylinders to read
xor si, si ;start at cylinder 0
mov edi, BOOT_RD_ADD ;ram disk address
read_cylinder:
push cx
mov bx, 0x0100 ;read sectors from head 0
mov es, bx
xor bx, bx ;es:bx = data buffer for read
mov ax, 0x0212 ;ah = int 0x13 function 2, al = number of sectors to read
mov cx, si ;what cyl. we are on is now in cx
mov ch, cl ;ch = cyl. number
mov cl, 1 ;cl = sector number 1-63
xor dx, dx ;dh = head number
mov dl, [gs:BOOT_DRIVE] ;dl = drive number
int 0x13
mov bx, 0x0100 ;now read sectors from head 1
mov es, bx
mov bx, 9216 ;es:bx = data buffer for read
mov ax, 0x0212 ;ah = int 0x13 function 2, al = number of sectors to read
mov cx, si ;what cyl. we are on is now in cx
mov ch, cl ;ch = cyl. number
mov cl, 1 ;cl = sector number 1-63
mov dh, 1 ;dh = head number
mov dl, [gs:BOOT_DRIVE] ;dl = drive number
int 0x13
mov ebx, 0xb8000
add bx, si
shl bl, 1
mov word [ds:ebx+160*4], 0x0200+219
push si
mov esi, 0x1000
mov cx, 0x2400
copydisk_loop:
mov ax, [ds:esi]
inc esi
inc esi
mov [ds:edi], ax
inc edi
inc edi
loop copydisk_loop
pop si ;what cylinder# we are on...
inc si
pop cx
loop read_cylinder
;------------------------------------------------------
no_rd:
mov ax, BOOT_DATA_SEG
mov es, ax
mov di, BOOT_MEMMAP ;store memmap info in es:di for kernel
xor edx, edx
mov ax, 0x0100
mov ds, ax
xor ebx, ebx
getmemmap_loop:
push es
push di
push edx
mov ax, 0x0100 ;get memory map
mov es, ax
xor di, di
mov eax, 0x0000E820
mov ecx, 0x00000014
;mov ebx, 0x00000000
mov edx, 0x534D4150 ;'SMAP'
int 0x15
jc getmemmap_carry
cmp eax, 0x534D4150 ;eax should be 'SMAP' on return...
jnz getmemmap_error
cmp ebx, 0
jz getmemmap_done
pop edx ;now, copy memmap entry to es:di on the stack
pop di
pop es
xor si, si
mov cx, 20
getmemmap_copymem_loop:
lodsb
stosb
loop getmemmap_copymem_loop
inc edx
jmp getmemmap_loop
getmemmap_error:
mov ax, 0xb800
mov es, ax
mov di, 160*24
xor ax, ax
mov ds, ax
mov si, txt_memerror
mov ah, 0x04
call puts
hlt
jmp $
getmemmap_carry:
dec edx
getmemmap_done:
pop edx
pop di
pop es
xor si, si
mov cx, 20
getmemmap_done_copymem_loop:
lodsb
stosb
loop getmemmap_done_copymem_loop
inc edx
mov di, BOOT_MEMENTRIES
mov [es:di], edx ;save # of memmap entries for kernel
;on to vesa info...
xor ax, ax
mov gs, ax
mov ds, ax
mov ax, 0xb800
mov es, ax
mov di, 160
mov cx, 2000-80
mov ax, 0x0700
cls_vesa_loop:
stosw
loop cls_vesa_loop
mov si, txt_vesa
mov di, 160*1
mov ah, 7
call puts
push di
mov ax, 0x0100
mov es, ax
xor di, di
mov dword [es:di], "2EBV"
mov ax, 0x4F00
int 0x10
pop di
cmp ax, 0x004F
jz vesa_good
mov si, txt_novesa
mov ax, 0xb800
mov es, ax
mov ah, 7
call puts
mov ax, BOOT_DATA_SEG
mov ds, ax
mov word [ds:BOOT_VESA], 0
jmp vesa_done
vesa_good:
mov ax, 0xb800
mov es, ax
mov ax, 0x0100
mov ds, ax
xor si, si
mov bx, [4]
mov al, bh
call puthex
mov al, '.'
stosb
mov al, 7
stosb
mov al, bl
call puthex
add di, 4
cmp bh, 2
jge vesa_good2
xor ax, ax
mov ds, ax
mov si, txt_vesaold
mov ah, 7
call puts
mov ax, BOOT_DATA_SEG
mov ds, ax
mov word [ds:BOOT_VESA], 0
jmp vesa_done
vesa_good2:
mov ebx, [6] ;something like 0x00000E60
mov edx, [14]
mov si, bx
shr ebx, 16
mov ds, bx ;ds:si points to null-terminated OEM identification string
mov ah, 2
push si
call puts
pop si
mov ax, BOOT_DATA_SEG
mov es, ax
mov di, BOOT_VESA_OEM
vesa_copyoem:
lodsb
stosb
or al, al
jnz vesa_copyoem
mov ax, 0x0100
mov ds, ax
xor si, si
mov di, BOOT_VESA_VBE
mov cx, 512
vesa_copyvbe:
lodsb
stosb
loop vesa_copyvbe
mov si, dx
shr edx, 16
mov ds, dx ;ds:si points to video mode list
mov ax, VESA_MODELIST_SEG
mov es, ax
xor di, di
vesa_copymodes:
lodsw
stosw
cmp ax, 0xffff
jnz vesa_copymodes
mov ax, GOOD_MODELIST_SEG
mov es, ax
xor di, di
mov cx, 256
mov ax, 0xffff
clear_good_mode_list_loop:
stosw
loop clear_good_mode_list_loop
mov ax, VESA_MODELIST_SEG
mov ds, ax
xor si, si ;ds:si points to video mode list where we can edit it :)
mov ax, GOOD_MODELIST_SEG
mov es, ax
xor di, di
xor dx, dx ;dx=what good mode # we are on
vesa_readmodeinfo_loop:
lodsw
cmp ax, 0xffff
jz vesa_endofmodes
push ax ;save mode#
call checkmode
cmp ax, 0
jz vesa_readmodeinfo_good
pop ax
jmp vesa_readmodeinfo_loop
vesa_readmodeinfo_good:
pop ax ;restore mode#
stosw
call vesa_showmodeinfo
inc dx
jmp vesa_readmodeinfo_loop
vesa_endofmodes: ;here we have a list of good modes at GOOD_MODELIST_SEG:0
xor ax, ax
mov ds, ax
mov si, txt_consolemode
mov ax, 0xb800
mov es, ax
mov di, 160*2
mov ah, 7
call puts
mov di, 160*3
mov cx, dx
mov al, 'b'
vesa_displaylabels:
stosb
push ax
mov al, 7
stosb
mov al, '.'
stosb
mov al, 7
stosb
pop ax
inc al
add di, 160-4
loop vesa_displaylabels ;done drawing screen of VESA choices, now ask for one
;valid options are 'a' through (al-1)
mov bl, al
xor ax, ax
mov ds, ax
mov di, 160*24
mov si, txt_input
mov ah, 14
call puts
vesa_getchoice:
xor ax, ax
int 0x16
cmp al, 'a'
jl vesa_getchoice
cmp al, bl
jge vesa_getchoice
stosb
push ax
mov al, 14
stosb
pop ax
xor ah, ah
sub ax, 'a'
cmp ax, 0
jz vesa_consolemode_only
mov cx, ax ;cx holds good mode# (1=first good vesa mode)
dec cx
mov ax, GOOD_MODELIST_SEG
mov ds, ax
shl cx, 1
mov si, cx ;ds:si points to word containing selected mode#
lodsw
mov cx, ax
mov dx, ax ;cx and dx hold mode#
mov ax, VESA_MODEINFO_SEG
mov es, ax
xor di, di
mov ax, 0x4F01
int 0x10
call checkvesa
mov ax, VESA_MODEINFO_SEG
mov ds, ax
xor si, si
mov ax, BOOT_DATA_SEG
mov es, ax
mov di, BOOT_VESA_INFO
mov cx, 256
vesa_copymodeinfo_loop:
lodsb
stosb
loop vesa_copymodeinfo_loop ;store ModeInfoBlock for current
mov [es:BOOT_VESA], dx ;store mode# for kernel
; mov ax, 0xb800
; mov es, ax
; xor di, di
; mov al, dh
; call puthex2
; mov al, dl
; call puthex2
mov bx, dx
or bx, 0x4000 ;set "use LFB" bit of mode#
mov ax, 0x4F02
int 0x10 ;switch to graphics mode!!!
call checkvesa
jmp vesa_done
vesa_consolemode_only:
mov ax, BOOT_DATA_SEG
mov es, ax
mov word [es:BOOT_VESA], 0
jmp vesa_done
;------------------------------------------------------
vesa_showmodeinfo:
pusha
push es
push ds
mov ax, VESA_MODEINFO_SEG
mov ds, ax
xor si, si
mov ax, 0xb800
mov es, ax
mov cx, dx
mov ax, 160
mul dx ;ax=160*mod#
add ax, 160*3+6 ;offset first line of modes and room on left for label
mov di, ax
mov ax, [ds:18]
call console_putDec
add di, 10
mov al, 'x'
call console_putChar
inc di
inc di
mov ax, [ds:20]
call console_putDec
add di, 10
mov al, 'x'
call console_putChar
inc di
inc di
xor ah, ah
mov al, [ds:25]
call console_putDec
add di, 8
mov al, [ds:0]
test al, 0x80
jz vesa_showmodeinfo_done
mov al, 'L'
call console_putChar
mov al, 'F'
call console_putChar
mov al, 'B'
call console_putChar
inc di
inc di
mov ebx, [ds:40]
mov eax, ebx
shr eax, 24
call puthex2
mov eax, ebx
shr eax, 16
call puthex2
mov al, bh
call puthex2
mov al, bl
call puthex2
vesa_showmodeinfo_done:
pop ds
pop es
popa
ret
;------------------------------------------------------
checkmode:
push bx
push cx
push dx
push es
push ds
push di
push si
mov cx, ax ;cx=modenumber
mov ax, VESA_MODEINFO_SEG
mov es, ax
xor di, di
mov ax, 0x4F01
int 0x10
call checkvesa
xor di, di ;es:di -> ModeInfoBlock struc
mov ax, [es:di] ;ModeAttributes
test al, 1 ;mode supported
jz vesa_modenogood
test al, 8 ;color mode
jz vesa_modenogood
test al, 0x10 ;graphics mode
jz vesa_modenogood
test al, 0x80 ;Linear Frame Buffer supported
jz vesa_modenogood
mov al, [es:di+25] ;BitsPerPixel
cmp al, 16
jz vesa_bppok
cmp al, 24
jz vesa_bppok
cmp al, 32
jnz vesa_modenogood
vesa_bppok:
mov ax, [es:di+18] ;XResolution
mov bx, [es:di+20] ;YResolution
cmp ax, 640 ;640x480
jnz res_goon1
cmp bx, 480
jnz vesa_modenogood
jmp vesa_modegood
res_goon1:
cmp ax, 800
jnz res_goon2
cmp bx, 600
jnz vesa_modenogood
jmp vesa_modegood
res_goon2:
cmp ax, 1024
jnz res_goon3
cmp bx, 768
jnz vesa_modenogood
jmp vesa_modegood
res_goon3:
cmp ax, 1280
jnz res_goon4
cmp bx, 1024
jz vesa_modegood
cmp bx, 960
jz vesa_modegood
jmp vesa_modenogood
res_goon4:
cmp ax, 1600
jnz vesa_modenogood
cmp bx, 1200
jnz vesa_modenogood
vesa_modegood:
pop si
pop di
pop ds
pop es
pop dx
pop cx
pop bx
xor ax, ax
ret
vesa_modenogood:
pop si
pop di
pop ds
pop es
pop dx
pop cx
pop bx
mov ax, 0xffff
ret
;------------------------------------------------------
vesa_done:
; xor ax, ax ;wait for keypress...
; int 0x16
jmp go_pm
;------------------------------------------------------
puts:
lodsb
or al, al
jz puts_done
stosb
mov al, ah
stosb
jmp puts
puts_done:
ret
;------------------------------------------------------
checkvesa:
cmp ax, 0x004F
jnz vesaerror
ret
vesaerror:
mov ax, 0xb800
mov es, ax
xor ax, ax
mov ds, ax
mov si, txt_vesaerror
mov di, 160*24
mov ah, 4
call puts
cli
hlt
;-------Function console_putDec
;input:
; AX = number to display
;output:
; number written in decimal to es:di
console_putDec:
pusha
xor dx, dx
xor bh, bh ;no characters written yet
mov cx, 10000
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon1
call console_putChar
mov bh, 1
.goon1:
mov ax, dx ;load remainder to ax
xor dx, dx
mov cx, 1000
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon11
call console_putChar
mov bh, 1
jmp .goon2
.goon11:
cmp bh, 0
je .goon2
call console_putChar
.goon2:
mov ax, dx ;load remainder to ax
xor dx, dx
mov cx, 100
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon21
call console_putChar
mov bh, 1
jmp .goon3
.goon21:
cmp bh, 0
je .goon3
call console_putChar
.goon3:
mov ax, dx ;load remainder to ax
xor dx, dx
mov cx, 10
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon31
call console_putChar
mov bh, 1
jmp .goon4
.goon31:
cmp bh, 0
je .goon4
call console_putChar
.goon4: ;here dx contains last remainder
mov ax, dx
add ax, '0'
call console_putChar
popa
ret
;------------------------------------------------------
console_putChar:
stosb
mov al, 7
stosb
ret
;------------------------------------------------------
puthex:
;es:di points to video memory
;al holds hex value
push ax
mov ah, al
shr ax, 4
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex_goon1
add al, 'A'-'9'-1
puthex_goon1:
cmp al, '0'
jz puthex_skipzero
stosb
mov al, 7
stosb
puthex_skipzero:
pop ax
push ax
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex_goon2
add al, 'A'-'9'-1
puthex_goon2:
stosb
mov al, 7
stosb
pop ax
ret
;------------------------------------------------------
puthex2:
;es:di points to video memory, always displays 2 characters!
;al holds hex value
push ax
mov ah, al
shr ax, 4
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex2_goon1
add al, 'A'-'9'-1
puthex2_goon1:
stosb
mov al, 7
stosb
pop ax
push ax
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex2_goon2
add al, 'A'-'9'-1
puthex2_goon2:
stosb
mov al, 7
stosb
pop ax
ret
;------------------------------------------------------
txt_welcome: db " HOS bootloader v", VERSION, "! ", 0
txt_rd1: db "1. Do not load an initial ram disk", 0
txt_rd2: db "2. Load initial ram disk from boot media", 0
txt_input: db "Enter your selection: ", 0
txt_vesa: db "VESA version: ", 0
txt_vesaerror: db "VESA function call error! Halting system!", 0
txt_novesa: db "VESA not found. Starting in console mode...", 0
txt_vesaold: db "VESA version 2.0 required. Starting in console mode...", 0
txt_consolemode: db "a. Console mode only.", 0
txt_memerror: db "Extended Memory Map information unavailable! Halting system...", 0
;------------------------------------------------------
getCHSfromCluster:
;input: ax=lba of sector on floppy (0-2879)
add ax, 31 ;convert logical cluster# to lba#
xor dx, dx ;lba->chs
mov bx, 18
div bx
inc dx
mov cl, dl ;sector# (1-18)
xor dx, dx
mov bx, 2
div bx
mov ch, al ;cylinder# (0-79)
mov dh, dl ;head# (0-1)
ret
;-------------------------------------------------------
gdtr:
dw gdt_end-gdt-1
dd gdt
gdt:
dd 0
dd 0
KERNEL_CODE equ $-gdt
db 0xff ;limit 7:0
db 0xff ;limit 15:8
db 0x00 ;base 7:0
db 0x00 ;base 15:8
db 0x00 ;base 23:16
db 0x9a ;access
db 0xcf ;flags / limit 19:16
db 0x00 ;base 31:24
KERNEL_DATA equ $-gdt
db 0xff ;segment 16 = 4gb data
db 0xff
db 0x00
db 0x00
db 0x00
db 0x92
db 0xcf
db 0x00
gdt_end:
;-------------------------------------------------------
gdtr32:
dw gdt_end32-gdt32-1
dd gdt32
gdt32:
dd 0
dd 0
;a base of 0x4000_0000, when added to 0xC000_0000 will produce 0x0000_0000 physical before paging in effect
KERNEL_CODE32 equ $-gdt32
db 0xff ;limit 7:0
db 0xff ;limit 15:8
db 0x00 ;base 7:0
db 0x00 ;base 15:8
db 0x00 ;base 23:16
db 0x9a ;access
db 0xcf ;flags / limit 19:16
db 0x40 ;base 31:24
KERNEL_DATA32 equ $-gdt32
db 0xff ;segment 16 = 4gb data
db 0xff
db 0x00
db 0x00
db 0x00
db 0x92
db 0xcf
db 0x40
gdt_end32:
;------------------------------------------------------
go_pm:
xor ax, ax
mov ds, ax
lgdt [gdtr]
cli
mov eax, cr0
inc eax
mov cr0, eax
jmp KERNEL_CODE:pmode
bits 32
pmode:
lgdt [gdtr32]
jmp KERNEL_CODE32:pmode_offsetted+0xC0000000
pmode_offsetted:
mov ax, KERNEL_DATA32
mov es, ax
mov ds, ax
mov fs, ax
mov gs, ax
jmp KERNEL_CODE:BOOT_KERNEL_ADD+0xC0000000
kernel: db "KERNEL BIN", 0

Binary file not shown.

View File

@ -1,224 +0,0 @@
#include <stdlib.h>
#include <stdint.h>
#include <ft2build.h>
#include <stdio.h>
#include FT_FREETYPE_H
#include <string.h>
#include <strings.h>
#include <ctype.h>
#define N_CHARS 128
#define round_up_26_6(val) (((val) + 63) >> 6u)
int max_advance;
int max_top = -9999;
int min_bottom = 9999;
int line_height;
int baseline_offset;
typedef struct {
int width;
int height;
int top;
int left;
uint8_t * bitmap;
} char_info_t;
static char_info_t char_infos[N_CHARS];
static void load_char(FT_Face face, int char_code)
{
if (FT_Load_Char(face, char_code, FT_LOAD_RENDER) != 0)
{
return;
}
int advance = round_up_26_6(face->glyph->advance.x);
if (advance > max_advance)
{
max_advance = advance;
}
if ((face->glyph->bitmap.width == 0) ||
(face->glyph->bitmap.rows == 0))
{
return;
}
char_infos[char_code].width = face->glyph->bitmap.width;
char_infos[char_code].height = face->glyph->bitmap.rows;
char_infos[char_code].top = face->glyph->bitmap_top;
if (char_infos[char_code].top > max_top)
{
max_top = char_infos[char_code].top;
}
int bottom = char_infos[char_code].top - char_infos[char_code].height;
if (bottom < min_bottom)
{
min_bottom = bottom;
}
char_infos[char_code].left = face->glyph->bitmap_left;
char_infos[char_code].bitmap = malloc(char_infos[char_code].width * char_infos[char_code].height);
memcpy(char_infos[char_code].bitmap,
face->glyph->bitmap.buffer,
char_infos[char_code].width * char_infos[char_code].height);
}
static const char * bare_header_name(const char * h_file_name)
{
const char * p = rindex(h_file_name, '/');
if (p == NULL)
{
p = h_file_name;
}
else
{
p++;
}
return p;
}
static char * include_guard_name(const char * h_file_name)
{
const char * p = bare_header_name(h_file_name);
char * guard_name = malloc(strlen(p) + 1);
strcpy(guard_name, p);
char * m = guard_name;
while (*m != '\0')
{
if ('a' <= *m && *m <= 'z')
{
*m = toupper(*m);
}
else if (('0' <= *m && *m <= '9') || ('A' <= *m && *m <= 'Z'))
{
/* no change */
}
else
{
*m = '_';
}
m++;
}
return guard_name;
}
static void generate_bytes(FILE * file, const uint8_t * bytes, int count)
{
for (int i = 0; i < count; i++)
{
if (i % 8 == 0)
{
fprintf(file, " ");
}
fprintf(file, "0x%02xu,", bytes[i]);
if ((i + 1) % 8 == 0)
{
fprintf(file, "\n");
}
else if (i < (count - 1))
{
fprintf(file, " ");
}
}
if (count % 8 != 0)
{
fprintf(file, "\n");
}
}
static void generate(const char * c_file_name)
{
char * h_file_name = malloc(strlen(c_file_name) + 1);
strcpy(h_file_name, c_file_name);
h_file_name[strlen(h_file_name) - 1] = 'h';
char * guard = include_guard_name(h_file_name);
FILE * h_file = fopen(h_file_name, "wb");
fprintf(h_file, "#ifndef %s\n", guard);
fprintf(h_file, "#define %s\n\n", guard);
fprintf(h_file, "#include <stdint.h>\n");
fprintf(h_file, "typedef struct {\n int width;\n int height;\n int top;\n int left;\n const uint8_t * bitmap;\n} fontgen_char_info_t;\n");
fprintf(h_file, "typedef struct {\n int line_height;\n int advance;\n int baseline_offset;\n const fontgen_char_info_t ** char_infos;\n} fontgen_font_t;\n");
fprintf(h_file, "extern const fontgen_font_t kfont;\n");
fprintf(h_file, "#endif\n");
fclose(h_file);
FILE * c_file = fopen(c_file_name, "wb");
fprintf(c_file, "#include \"%s\"\n", bare_header_name(h_file_name));
fprintf(c_file, "#include <stddef.h>\n");
for (int i = 0; i < N_CHARS; i++)
{
if (char_infos[i].width > 0)
{
fprintf(c_file, "static const uint8_t char_bitmap_%d[] = {\n", i);
generate_bytes(c_file, char_infos[i].bitmap, char_infos[i].width * char_infos[i].height);
fprintf(c_file, "};\n");
}
fprintf(c_file, "static const fontgen_char_info_t char_%d = {\n", i);
fprintf(c_file, " %d,\n", char_infos[i].width);
fprintf(c_file, " %d,\n", char_infos[i].height);
fprintf(c_file, " %d,\n", char_infos[i].top);
fprintf(c_file, " %d,\n", char_infos[i].left);
if (char_infos[i].width > 0)
{
fprintf(c_file, " char_bitmap_%d,\n", i);
}
else
{
fprintf(c_file, " NULL,\n");
}
fprintf(c_file, "};\n\n");
}
fprintf(c_file, "const fontgen_char_info_t * char_infos[] = {\n");
for (int i = 0; i < N_CHARS; i++)
{
fprintf(c_file, " &char_%d,\n", i);
}
fprintf(c_file, "};\n");
fprintf(c_file, "const fontgen_font_t kfont = {\n");
fprintf(c_file, " %d,\n", line_height);
fprintf(c_file, " %d,\n", max_advance);
fprintf(c_file, " %d,\n", baseline_offset);
fprintf(c_file, " char_infos,\n");
fprintf(c_file, "};\n");
fclose(c_file);
}
int main(int argc, char * argv[])
{
/* Expect: font file, size, out file */
if (argc != 4)
{
fprintf(stderr, "Incorrect arguments\n");
return 1;
}
const char * font_file = argv[1];
int size = atoi(argv[2]);
const char * out_file = argv[3];
FT_Library ft_library;
if (FT_Init_FreeType(&ft_library) != 0)
{
fprintf(stderr, "Could not initialize freetype\n");
return 2;
}
FT_Face face;
if (FT_New_Face(ft_library, font_file, 0, &face) != 0)
{
fprintf(stderr, "Could not open %s\n", font_file);
return 3;
}
FT_Set_Pixel_Sizes(face, 0, size);
for (int i = 0; i < N_CHARS; i++)
{
load_char(face, i);
}
line_height = round_up_26_6(face->size->metrics.height);
baseline_offset = (line_height - (max_top - min_bottom)) / 2 - min_bottom;
generate(out_file);
return 0;
}

View File

@ -1,75 +0,0 @@
binutils_version = "2.35"
binutils_checksum = "1b11659fb49e20e18db460d44485f09442c8c56d5df165de9461eb09c8302f85"
gcc_version = "10.2.0"
gcc_checksum = "b8dd4368bb9c7f0b98188317ee0254dd8cc99d1e3a18d0ff146c855fe16c1d8c"
install_path = File.expand_path("i686-elf-gcc")
target = "i686-elf"
path_prepend "#{install_path}/bin"
configure do
check_c_compiler "gcc"
check_program "make"
check_program "bison"
check_program "flex"
check_program "texi2any", on_fail: "Install the texinfo package"
check_program "wget"
check_lib "gmp", on_fail: "Install the libgmp-dev package"
check_lib "mpc", on_fail: "Install the libmpc-dev package"
check_lib "mpfr", on_fail: "Install the libmpfr-dev package"
end
default do
unless Dir.exist?(install_path)
# Download archives.
download "https://ftp.gnu.org/gnu/binutils/binutils-#{binutils_version}.tar.xz",
"#{build_dir}/binutils-#{binutils_version}.tar.xz",
sha256sum: binutils_checksum
download "https://ftp.gnu.org/gnu/gcc/gcc-#{gcc_version}/gcc-#{gcc_version}.tar.xz",
"#{build_dir}/gcc-#{gcc_version}.tar.xz",
sha256sum: gcc_checksum
# Extract archives.
sh "tar", "xJf", "binutils-#{binutils_version}.tar.xz",
chdir: build_dir
sh "tar", "xJf", "gcc-#{gcc_version}.tar.xz",
chdir: build_dir
# Build binutils.
rm_rf "#{build_dir}/build-binutils"
mkdir_p "#{build_dir}/build-binutils"
cd "#{build_dir}/build-binutils" do
sh %W[../binutils-#{binutils_version}/configure
--target=#{target} --prefix=#{install_path} --with-sysroot --disable-nls
--disable-werror]
sh "make"
sh "make install"
end
# Build gcc.
rm_rf "#{build_dir}/build-gcc"
mkdir_p "#{build_dir}/build-gcc"
cd "#{build_dir}/build-gcc" do
sh %W[../gcc-#{gcc_version}/configure
--target=#{target} --prefix=#{install_path} --disable-nls
--enable-languages=c,c++ --without-headers]
sh "make all-gcc"
sh "make all-target-libgcc"
sh "make install-gcc"
sh "make install-target-libgcc"
end
# Remove archives and build directories if everything succeeded.
rm_f "#{build_dir}/binutils-#{binutils_version}.tar.xz"
rm_rf "#{build_dir}/binutils-#{binutils_version}"
rm_rf "#{build_dir}/build-binutils"
rm_f "#{build_dir}/gcc-#{gcc_version}.tar.xz"
rm_rf "#{build_dir}/gcc-#{gcc_version}"
rm_rf "#{build_dir}/build-gcc"
end
end
distclean do
rm_rf install_path
end

76
kernel/Makefile Normal file
View File

@ -0,0 +1,76 @@
#####################################################################
# Author: Josh Holtrop / Benjamen R. Meyer #
# Date: 02/15/04 Modified: 06/16/04 #
# Purpose: To build Josh Holtrop's OS (HOS) using GNU make #
# Note: This makefile is for use on Linux & other Unix-like systems #
#####################################################################
##############
# Variables: #
##############
# Format of kernel object files:
# Do not change unless you know what you are doing
KERNEL_FORMAT=aout
# Assembler information:
NASM_BIN=nasm
NASM_FLAGS=-f $(KERNEL_FORMAT)
# C++ Compile Information:
CPP=g++
CPP_FLAGS=-fleading-underscore -fno-builtin -nostdlib -nostdinc++ -nostartfiles -fno-rtti -fno-exceptions -nodefaultlibs -I. -Wall
# Linker Information:
LD=ld
LD_FLAGS=-nodefaultlibs -nostdlib --no-demangle -T link.ld
###############################
# Linking the kernel together #
###############################
all: Asm_Kernel Asm_Functions C_Kernel
$(LD) $(LD_FLAGS) -o kernel.bin -Map ./lst/LDout.doc ks.o kernel.o asmfuncs.o fdc.o keyboard.o kio.o mm.o mouse.o stdfont.o video.o vmm.o rtc.o pic.o io.o cstring.o string.o cmos.o hos_defines.o vfs.o devfs.o Mount.o
##########################
# Assembly Kernel Loader #
##########################
Asm_Kernel: kernel.asm
$(NASM_BIN) $(NASM_FLAGS) -o ks.o -l ./lst/kernel.lst kernel.asm
#################################
# Assembly Functions for Kernel #
#################################
Asm_Functions: asmfuncs.asm
$(NASM_BIN) $(NASM_FLAGS) -o asmfuncs.o -l ./lst/asmfuncs.lst asmfuncs.asm
############
# C Kernel #
############
C_Kernel:
$(CPP) $(CPP_FLAGS) -c kernel.cpp -o kernel.o
$(CPP) $(CPP_FLAGS) -c kio.cpp -o kio.o
$(CPP) $(CPP_FLAGS) -c sys/rtc.cpp -o rtc.o
$(CPP) $(CPP_FLAGS) -c sys/pic.cpp -o pic.o
$(CPP) $(CPP_FLAGS) -c sys/io.cpp -o io.o
$(CPP) $(CPP_FLAGS) -c sys/cmos.cpp -o cmos.o
$(CPP) $(CPP_FLAGS) -c lang/cstring.cpp -o cstring.o
$(CPP) $(CPP_FLAGS) -c lang/string.cpp -o string.o
$(CPP) $(CPP_FLAGS) -c video/stdfont.cpp -o stdfont.o
$(CPP) $(CPP_FLAGS) -c video/video.cpp -o video.o
$(CPP) $(CPP_FLAGS) -c block/fdc.cpp -o fdc.o
$(CPP) $(CPP_FLAGS) -c char/keyboard.cpp -o keyboard.o
$(CPP) $(CPP_FLAGS) -c char/mouse.cpp -o mouse.o
$(CPP) $(CPP_FLAGS) -c mm/mm.cpp -o mm.o
$(CPP) $(CPP_FLAGS) -c mm/vmm.cpp -o vmm.o
$(CPP) $(CPP_FLAGS) -c hos_defines.cpp -o hos_defines.o
$(CPP) $(CPP_FLAGS) -c fs/vfs.cpp -o vfs.o
$(CPP) $(CPP_FLAGS) -c fs/devfs.cpp -o devfs.o
$(CPP) $(CPP_FLAGS) -c fs/Mount.cpp -o Mount.o
#################################################
# Clean up the source directory of any binaries #
#################################################
clean:
- rm *.s *.o *.bin *~ block/*~ char/*~ fs/*~ lang/*~ mm/*~ sys/*~ video/*~

510
kernel/asmfuncs.asm Normal file
View File

@ -0,0 +1,510 @@
; asmfuncs.asm
; Josh Holtrop
; Created: 10/23/03
; Modified: 02/26/04
[extern _putc]
[extern _console_memory]
[extern _cursorPosition]
[extern _video_drawConsole]
[extern _videoMode]
%macro jzfar 1
jnz %%skip
jmp %1
%%skip:
%endmacro
;stores the parameter to the CR0 register
;extern dword write_cr0(dword cr0);
[global _write_cr0]
_write_cr0:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr0, eax
pop ebp
ret
;returns the value in the CR0 register
;extern dword read_cr0();
[global _read_cr0]
_read_cr0:
mov eax, cr0;
ret
;stores the parameter to the CR3 register
;extern dword write_cr3(dword cr3);
[global _write_cr3]
_write_cr3:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr3, eax
pop ebp
ret
;returns the value in the CR2 register
;extern dword read_cr2();
[global _read_cr2]
_read_cr2:
mov eax, cr2;
ret
;returns the value in the CR3 register
;extern dword read_cr3();
[global _read_cr3]
_read_cr3:
mov eax, cr3;
ret
;compares one string to another
;returns 0 if the strings are different
;extern dword strcmp(char *str1, char *str2);
[global _strcmp]
_strcmp:
push ebp
mov ebp, esp
push esi
push edi
mov esi, [ebp+8]
mov edi, [ebp+12]
strcmp_loop1:
lodsb
mov ah, [edi]
inc edi
cmp ah, al
jnz strcmp_ne
or al, al
jz strcmp_e
jmp strcmp_loop1
strcmp_e:
mov eax, 1
jmp short strcmp_done
strcmp_ne:
xor eax, eax
strcmp_done:
pop edi
pop esi
pop ebp
ret
;copies a string from the source to the destination parameter
;extern void strcpy(char *dest, char *src);
[global _strcpy]
_strcpy:
push ebp
mov ebp, esp
push esi
push edi
mov edi, [ebp+8]
mov esi, [ebp+12]
strcpyloop:
lodsb
stosb
or al, al
jnz strcpyloop
pop edi
pop esi
pop ebp
ret
;copies memory of n bytes from src to destination
;void memcpy(void *dest, void *src, dword n);
[global _memcpy]
_memcpy:
push ebp
mov ebp, esp
push esi
push edi
push ecx
mov edi, [ebp+8]
mov esi, [ebp+12]
mov ecx, [ebp+16]
cld
rep movsb
pop ecx
pop edi
pop esi
pop ebp
ret
;copies memory of n dwords (n*4 bytes) from src to destination
;void memcpyd(void *dest, void *src, dword n);
[global _memcpyd]
_memcpyd:
push ebp
mov ebp, esp
push esi
push edi
push ecx
mov edi, [ebp+8]
mov esi, [ebp+12]
mov ecx, [ebp+16]
cld
rep movsd
pop ecx
pop edi
pop esi
pop ebp
ret
;sets num bytes at buffer to the value of c
;void *memset(void *buffer, int c, int num);
[global _memset]
_memset:
push ebp
mov ebp, esp
push edi
push ecx
mov edi, [ebp+8]
push edi ;save for return address
mov eax, [ebp+12]
mov ecx, [ebp+16]
rep stosb
pop eax
pop ecx
pop edi
pop ebp
ret
;sets num words at buffer to the value of c
;void *memsetw(void *buffer, int c, int num);
[global _memsetw]
_memsetw:
push ebp
mov ebp, esp
push edi
push ecx
mov edi, [ebp+8]
push edi ;save for return address
mov eax, [ebp+12]
mov ecx, [ebp+16]
rep stosw
pop eax
pop ecx
pop edi
pop ebp
ret
;sets num dwords at buffer to the value of c
;void *memsetd(void *buffer, int c, int num);
[global _memsetd]
_memsetd:
push ebp
mov ebp, esp
push edi
push ecx
mov edi, [ebp+8]
push edi ;save for return address
mov eax, [ebp+12]
mov ecx, [ebp+16]
rep stosd
pop eax
pop ecx
pop edi
pop ebp
ret
;returns the number of characters in a string
;extern dword strlen(char *str);
[global _strlen]
_strlen:
push ebp
mov ebp, esp
push esi
push ebx
mov esi, [ebp+8]
xor ebx, ebx
strlenloop:
lodsb
or al, al
jz strlendone
inc ebx
jmp strlenloop
strlendone:
mov eax, ebx
pop ebx
pop esi
pop ebp
ret
;this function invalidates the page directory/table entry that
; would be used to access the memory address given in the parameter
;extern void invlpg_(dword addr);
[global _invlpg_]
_invlpg_:
mov eax, [esp+4]
invlpg [eax]
ret
;
;void writeCursorPosition(word pos)
;
[global _writeCursorPosition]
_writeCursorPosition:
push ebp
mov ebp, esp
push eax
push ebx
push edx
mov eax, [ebp+8] ;cursor position in ax
mov bl, al
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
mov al, ah
out dx, al
dec dx
mov al, 0x0F
out dx, al
inc dx
mov al, bl
out dx, al
pop edx
pop ebx
pop eax
pop ebp
ret
;
;word getCursorPosition()
;
[global _getCursorPosition]
_getCursorPosition:
push ebx
push edx
xor eax, eax
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
in al, dx
mov bl, al
dec dx
mov al, 0x0F
out dx, al
inc dx
in al, dx
mov ah, bl
pop edx
pop ebx
ret
;
;int puts(char *str)
;
[global _puts]
_puts:
push ebp
mov ebp, esp
push esi
push eax
mov esi, [ebp+8] ;esi = to string
puts_loop:
lodsb
cmp al, 0
jz puts_done
push eax
call _putc
add esp, 4
jmp puts_loop
puts_done:
pop eax
pop esi
pop ebp
ret
[global _putDecu]
_putDecu:
push ebp
mov ebp, esp
sub esp, 24
mov DWORD [ebp-4], 1
mov BYTE [ebp-5], 0
L2:
mov edx, DWORD [ebp+8]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
cmp eax, DWORD [ebp-4]
jae L4
jmp L3
L4:
mov eax, DWORD [ebp-4]
mov edx, eax
sal edx, 2
add edx, eax
lea eax, [edx+edx]
mov DWORD [ebp-4], eax
jmp L2
L3:
nop
L5:
cmp DWORD [ebp-4], 1
ja L7
jmp L6
L7:
mov edx, DWORD [ebp+8]
mov eax, edx
mov edx, 0
div DWORD [ebp-4]
mov DWORD [ebp-12], eax
mov al, BYTE [ebp-12]
mov BYTE [ebp-5], al
mov eax, 0
mov al, BYTE [ebp-5]
imul eax, DWORD [ebp-4]
sub DWORD [ebp+8], eax
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
lea eax, [ebp-5]
add BYTE [eax], 48
sub esp, 12
mov eax, 0
mov al, BYTE [ebp-5]
push eax
call _putc
add esp, 16
jmp L5
L6:
sub esp, 12
mov al, BYTE [ebp+8]
add eax, 48
and eax, 255
push eax
call _putc
add esp, 16
leave
ret
[global _putDec]
_putDec:
push ebp
mov ebp, esp
sub esp, 24
cmp DWORD [ebp+8], 0
jns L9
sub esp, 12
push 45
call _putc
add esp, 16
neg DWORD [ebp+8]
L9:
mov DWORD [ebp-4], 1
mov BYTE [ebp-5], 0
L10:
mov eax, DWORD [ebp+8]
cmp eax, DWORD [ebp-4]
jae L12
jmp L11
L12:
mov eax, DWORD [ebp-4]
mov edx, eax
sal edx, 2
add edx, eax
lea eax, [edx+edx]
mov DWORD [ebp-4], eax
jmp L10
L11:
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
L13:
cmp DWORD [ebp-4], 1
ja L15
jmp L14
L15:
mov edx, DWORD [ebp+8]
mov eax, edx
mov edx, 0
div DWORD [ebp-4]
mov DWORD [ebp-12], eax
mov al, BYTE [ebp-12]
mov BYTE [ebp-5], al
mov eax, 0
mov al, BYTE [ebp-5]
imul eax, DWORD [ebp-4]
sub DWORD [ebp+8], eax
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
lea eax, [ebp-5]
add BYTE [eax], 48
sub esp, 12
mov eax, 0
mov al, BYTE [ebp-5]
push eax
call _putc
add esp, 16
jmp L13
L14:
sub esp, 12
mov al, BYTE [ebp+8]
add eax, 48
and eax, 255
push eax
call _putc
add esp, 16
leave
ret

36
kernel/asmfuncs.h Normal file
View File

@ -0,0 +1,36 @@
// asmfuncs.h
// Author: Josh Holtrop
// Created: 02/26/04
// Modified: 05/21/04
#ifndef __HOS_ASMFUNCS__
#define __HOS_ASMFUNCS__ __HOS_ASMFUNCS__
#include "hos_defines.h"
extern "C" {
dword write_cr0(dword cr0);
dword read_cr0();
dword write_cr3(dword cr3);
dword read_cr2();
dword read_cr3();
void writeCursorPosition(dword pos);
dword getCursorPosition();
int puts(char *str);
int putDec(int number);
int putDecu(dword number);
void strcpy(char *dest, const char *src);
void memcpy(void *dest, const void *src, dword n);
void memcpyd(void *dest, const void *src, dword n);
void *memset(void *buffer, int c, int num);
void *memsetw(void *buffer, int c, int num);
void *memsetd(void *buffer, int c, int num);
dword strlen(const char *str);
void invlpg_(dword addr);
}
#endif

9
kernel/block/fdc.cpp Normal file
View File

@ -0,0 +1,9 @@
//fdc.c
//Author: Josh Holtrop
//Created: 10/30/03
//Modified: 02/26/04
#include "fdc.h"

23
kernel/block/fdc.h Normal file
View File

@ -0,0 +1,23 @@
//fdc.h
//Author: Josh Holtrop
//Date: 10/30/03
//Modified: 02/26/04
#ifndef __HOS_FDC__
#define __HOS_FDC__ __HOS_FDC__
#include "sys/io.h"
#define FDC_DOR 0x3f2
#define FDC_MSR 0x3f4
//inline void fdc_sendDOR(byte dor);
static inline void fdc_sendDOR(byte dor)
{
outportb(FDC_DOR, dor);
}
#endif

22
kernel/block/loop.cpp Normal file
View File

@ -0,0 +1,22 @@
// loop.c
// Author: Josh Holtrop
// Date: 03/16/04
// Provides a loop-back device for mounting files on existing volumes as new volumes
#include "hos_defines.h"
#include "loop.h"
#include "fs/vfs.h"
int loop_readSector(LoopDevice *ld, dword sector, byte *buffer)
{
return vfs_readFileBlock(ld->vol, ld->filePath, sector * LOOP_SECTOR_SIZE, buffer, LOOP_SECTOR_SIZE);
}
int loop_writeSector(LoopDevice *ld, dword sector, byte *buffer)
{
return vfs_writeFileBlock(ld->vol, ld->filePath, sector * LOOP_SECTOR_SIZE, buffer, LOOP_SECTOR_SIZE);
}

22
kernel/block/loop.h Normal file
View File

@ -0,0 +1,22 @@
// loop.h
// Author: Josh Holtrop
// Date: 03/16/04
// Provides a loop-back device for mounting files on existing volumes as new volumes
#ifndef __HOS_LOOP__
#define __HOS_LOOP__ __HOS_LOOP__
#include "hos_includes.h"
typedef struct
{
Volume *vol;
char filePath[256];
} LoopDevice;
int loop_readSector(LoopDevice *ld, dword sector, byte *buffer);
int loop_writeSector(LoopDevice *ld, dword sector, byte *buffer);
#endif

7
kernel/block/rd.cpp Normal file
View File

@ -0,0 +1,7 @@
// rd.c
// Author: Josh Holtrop
// Date: 03/11/04
#include "rd.h"

12
kernel/block/rd.h Normal file
View File

@ -0,0 +1,12 @@
// rd.h
// Author: Josh Holtrop
// Date: 03/11/04
#ifndef __HOS_RD__
#define __HOS_RD__ __HOS_RD__
#endif

252
kernel/char/keyboard.cpp Normal file
View File

@ -0,0 +1,252 @@
// keyboard.c
// Author: Josh Holtrop
// Created: 04/17/03
// Modified: 03/02/04
#include "hos_defines.h"
#include "keyboard.h"
#include "sys/io.h"
#include "sys/pic.h"
#include "functions.h"
#include "kio.h"
#define KBD_BUFFER_LENGTH 64
extern "C" {
byte kbdFlags = 0; //holds current keyboard flags - caps/num/scroll/shift/ctrl/alt
byte kbdAscii = 0; //holds ASCII value of a key pressed
byte kbdScan = 0; //holds the keyboard scan code of a key pressed
dword kbdBuffer[KBD_BUFFER_LENGTH]; //a buffer for all keypresses
int kbdBufferStart = 0; //position of next key in buffer
int kbdBufferLen = 0; //number of keys left in the buffer
byte kbdExt = 0; //# of extended key codes left to input
byte kbdExt2 = 0; //# of 2nd-set-extended key codes left to input
byte ackReason = 0; //used to record the reason why we would get an acknowledge byte (0xFA)
//these arrays convert a keyboard scan code to an ASCII character value
//nul esc bksp tab lctl lsft rsft lalt caps F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 numScrlNumPad------- unknown---- F11 F12 unknown....
const byte SCAN2ASCII[129] = "\000\0331234567890-=\010\011qwertyuiop[]\n\001asdfghjkl;'`\001\\zxcvbnm,./\001*\001 \001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001-\001\001\001+\001\001\001\001\001\002\002\002\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002";
const byte SCAN2ASCIISHIFT[129] = "\000\033!@#$%^&*()_+\010\011QWERTYUIOP{}\n\001ASDFGHJKL:\"~\001|ZXCVBNM<>?\001*\001 \001\001\001\001\001\001\001\001\001\001\001\001\001789-456+1230.\002\002\002\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002";
//====FUNCTIONS:
// The Keyboard Interrupt Service Routine
void isr_keyboard()
{
kbdScan = inportb(0x60);
//printf("\nKEYBOARD INTERRUPT: 0x%x", kbdScan);
byte inState = inportb(0x61);
outportb(0x61, inState|0x80);
outportb(0x61, inState);
//printf("IRQ 1: %x\n", kbdScan);
if (kbdScan == 0xFA) //250 //ACKnowledge
{
//printf("KBD_ACK 0x%x!\n", ackReason);
if (ackReason == 0xED) //reset LEDs
{
outportb(0x60, (kbdFlags & 0x07));
}
ackReason = 0;
}
if (kbdScan == 224) //extended key
{
kbdExt = 1;
pic_eoi();
return;
}
if (kbdScan == 225) //2nd-set-extended key
{
kbdExt2 = 2;
pic_eoi();
return;
}
//====handle control keys::
kbdAscii = 2;
switch (kbdScan) //control keys
{
case KBD_SCAN_LSHIFT:
kbdFlags |= KBD_SHIFT;
kbdAscii = 1;
break;
case KBD_SCAN_RSHIFT:
kbdFlags |= KBD_SHIFT;
kbdAscii = 1;
break;
case KBD_SCAN_LCTRL:
kbdFlags |= KBD_CTRL;
kbdAscii = 1;
break;
case KBD_SCAN_LALT:
kbdFlags |= KBD_ALT;
kbdAscii = 1;
break;
case KBD_SCAN_LSHIFT + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_SHIFT ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_RSHIFT + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_SHIFT ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_LCTRL + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_CTRL ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_LALT + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_ALT ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_CAPS+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_CAPS;
kbdAscii = 1;
kbd_resetLEDs(); //update LEDs
break;
case KBD_SCAN_SCROLL+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_SCROLL;
kbdAscii = 1;
kbd_resetLEDs(); //update LEDs
break;
case KBD_SCAN_NUM+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_NUM;
kbdAscii = 1;
kbd_resetLEDs(); //update LEDs
break;
}
if (kbdAscii == 1)
{
if (kbdExt > 0)
kbdExt--;
pic_eoi();
return;
}
//====determine ASCII value of key::
if (kbdExt > 0) //extended key, kbdScan holds extended key
{
kbdExt--;
kbdAscii = 1;
switch (kbdScan)
{
case KBD_SCANE_ENTER:
kbdAscii = '\n'; break;
case 53: // '/' character (divide on numpad)
kbdAscii = '/'; break;
}
}
else if (kbdExt2 > 0) //extended key 2
{
kbdExt2--;
// if (kbdScan == 69) // (pause|break)
// kbdAscii = 2; //flag ascii value of 1 means control character (pausebreak)
// else
kbdAscii = 2; //flag ascii value of 2 means ignore key (or unknown value)
}
else //not an extended key
{
// if letter key
if (((kbdScan >= 16) && (kbdScan <= 25)) || ((kbdScan >= 30) && (kbdScan <= 38)) || ((kbdScan >= 44) && (kbdScan <= 50)))
{
// if caps and shift are different (either one pressed, not both)
if (((kbdFlags & KBD_SHIFT) != 0) & ((kbdFlags & KBD_CAPS) != 0))
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
else if (((kbdFlags & KBD_SHIFT) == 0) & ((kbdFlags & KBD_CAPS) == 0))
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
else
kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F];
}
// if numpad key
else if ((kbdScan >= 71) && (kbdScan <= 83))
{
// if numlock on
if (kbdFlags & KBD_NUM)
kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F];
else
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
}
// other key
else
{
if ((kbdFlags & KBD_SHIFT) != 0)
kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F];
else
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
}
}
//====do something with key::
// printf("kbdScan == %d\nkbdAscii == %d\nkbdFlags == %d\n", kbdScan, kbdAscii, kbdFlags);
if ((kbdScan == 83) && (kbdFlags & KBD_CTRL) && (kbdFlags & KBD_ALT))
{
printf("Initiating reboot.");
restart();
}
if (kbdAscii == 2) //unknown key / ignore key
{
pic_eoi();
return;
}
if (kbdScan < KBD_SCAN_RELEASED) //a key was pressed, save it
{
if (kbdBufferLen >= KBD_BUFFER_LENGTH) //no key slots available
{
pic_eoi();
return;
}
else
{
kbdBuffer[(kbdBufferStart+kbdBufferLen++)%KBD_BUFFER_LENGTH] = (dword) ((kbdFlags << 16) | (kbdScan << 8) | kbdAscii);
// printf("S:%d\tL:%d\tR:%x\n", kbdBufferStart, kbdBufferLen, kbdBuffer[kbdBufferStart]);
}
}
pic_eoi();
}
//Gets a key from the buffer, returns 0 if no keys available, returns immediately
dword kbdGetKey()
{
if (kbdBufferLen == 0) //buffer empty
return 0;
dword retVal = kbdBuffer[kbdBufferStart];
kbdBufferStart++;
kbdBufferLen--;
if (kbdBufferStart >= KBD_BUFFER_LENGTH)
kbdBufferStart = 0;
return retVal;
}
//Gets a key from the buffer, if no keys available, waits for one to be entered
dword kbdWaitKey()
{
for (;;)
{
if (kbdBufferLen != 0) //buffer empty
break;
}
dword retVal = kbdBuffer[kbdBufferStart];
kbdBufferStart++;
kbdBufferLen--;
if (kbdBufferStart >= KBD_BUFFER_LENGTH)
kbdBufferStart = 0;
return retVal;
}
//Resets the keyboard LEDs to reflect the current state of the num lock, caps lock, and scroll lock bits
void kbd_resetLEDs()
{
outportb(0x60, 0xED);
ackReason = 0xED;
}
}

53
kernel/char/keyboard.h Normal file
View File

@ -0,0 +1,53 @@
// keyboard.h
// Author: Josh Holtrop
// Created: 04/17/03
// Modified: 03/02/04
#include "hos_defines.h"
#ifndef __HOS_KEYBOARD__
#define __HOS_KEYBOARD__ __HOS_KEYBOARD__
#define KBD_SCROLL 0x01
#define KBD_NUM 0x02
#define KBD_CAPS 0x04
#define KBD_SHIFT 0x10
#define KBD_CTRL 0x20
#define KBD_ALT 0x40
#define KBD_SCAN_RELEASED 128
#define KBD_SCAN_LCTRL 29
#define KBD_SCAN_LSHIFT 42
#define KBD_SCAN_RSHIFT 54
#define KBD_SCAN_LALT 56
#define KBD_SCAN_SCROLL 70
#define KBD_SCAN_CAPS 58
#define KBD_SCAN_NUM 69
#define KBD_SCANE_PRINTSCREEN 55
#define KBD_SCANE_INS 82
#define KBD_SCANE_HOME 71
#define KBD_SCANE_PGUP 73
#define KBD_SCANE_DEL 83
#define KBD_SCANE_END 79
#define KBD_SCANE_PGDN 81
#define KBD_SCANE_ENTER 28
#define KBD_SCANE_NULL 42
//====PROTOTYPES:
extern "C" {
void isr_keyboard();
void kbd_resetLEDs();
dword kbdGetKey();
dword kbdWaitKey();
}
#endif

76
kernel/char/mouse.cpp Normal file
View File

@ -0,0 +1,76 @@
// mouse.c
// Author: Josh Holtrop
// Date: 10/03/03
// Modified: 05/21/04
#include "mouse.h"
#include "hos_defines.h"
#include "video/video.h"
#include "sys/io.h"
#define MOUSE_BUFFER_LENGTH 16
extern "C" {
int mouse_x;
int mouse_y;
int mouse_bytesRead;
byte mouse_inbuffer[MOUSE_BUFFER_LENGTH];
//This method initializes the ps/2 mouse
void mouse_init()
{
outportb(0x64, 0x20); //tell keyboard controller we are going to read keyboard controller command byte
byte temp = inportb(0x60); //read keyboard controller command byte
outportb(0x64, 0x60); //tell keyboard controller we are going to write keyboard controller command byte
outportb(0x60, 0x03 | (temp&0x40)); //write keyboard controller command byte: enable mouse/keyboard ints, include original XLATE bit from temp (bit6)
outportb(0x64, 0xA8); //enable mouse port
outportb(0x64, 0xD4); //send command to mouse, not kbd
outportb(0x60, 0xF4); //enable data reporting
mouse_x = video_getWidth() >> 1;
mouse_y = video_getHeight() >> 1;
mouse_bytesRead = 0;
//outportb(0x64, 0xD4);
//outportb(0x60, 0xE7); //scaling 2:1
}
//This method is called when a mouse interrupt occurs
void isr_mouse()
{
byte inb = inportb(0x60); //read mouse byte
if ((inb == 0xFA) && (mouse_bytesRead < 1)) //ACK
return;
mouse_inbuffer[mouse_bytesRead] = inb;
mouse_bytesRead++;
if (mouse_bytesRead == 3) //complete packet received
{
mouse_bytesRead = 0;
int adjx = (char) mouse_inbuffer[1];
int adjy = (char) mouse_inbuffer[2];
mouse_x += adjx;
mouse_y -= adjy; //-= because screen y coordinates are opposite mouse y coordinates
if (mouse_x < 0)
mouse_x = 0;
if (mouse_x >= video_getWidth())
mouse_x = video_getWidth() - 1;
if (mouse_y < 0)
mouse_y = 0;
if (mouse_y >= video_getHeight())
mouse_y = video_getHeight() - 1;
if (mouse_inbuffer[0] & 0x01) //left button
video_pset(mouse_x, mouse_y, 0x00FF9900);
else
video_pset(mouse_x, mouse_y, 0x00FFFFFF);
}
}
}

17
kernel/char/mouse.h Normal file
View File

@ -0,0 +1,17 @@
// mouse.h
// Author: Josh Holtrop
// Date: 10/03/03
// Modified: 03/02/04
#ifndef __HOS_MOUSE__
#define __HOS_MOUSE__ __HOS_MOUSE__
extern "C" {
void mouse_init();
void isr_mouse();
}
#endif

28
kernel/fs/Mount.cpp Normal file
View File

@ -0,0 +1,28 @@
// Mount.cpp
// Author: Josh Holtrop
// Date: 06/16/04
// Modified: 06/16/04
#include "lang/string.h"
#include "Mount.h"
Mount::Mount()
{
}
Mount::Mount(string dev, string mount)
{
mountPoint = mount;
device = dev;
}
bool Mount::operator==(const Mount & second) const
{
/* Match *either* device or mountPoint to signal an invalid mount attempt */
return (device == second.device || mountPoint == second.mountPoint);
}

28
kernel/fs/Mount.h Normal file
View File

@ -0,0 +1,28 @@
// Mount.h
// Author: Josh Holtrop
// Date: 06/16/04
// Modified: 06/16/04
#ifndef __HOS_MOUNT__
#define __HOS_MOUNT__ __HOS_MOUNT__
#include "hos_defines.h"
class Mount
{
public:
string mountPoint;
string device;
dword major;
dword minor;
Mount();
Mount(string dev, string mount);
bool operator==(const Mount & second) const;
};
#endif

25
kernel/fs/devfs.cpp Normal file
View File

@ -0,0 +1,25 @@
// devfs.cpp
// device filesystem for HOS
// Author: Josh Holtrop
// Date: 06/03/04
// Modified: 06/16/04
#include "devfs.h"
#include "kio.h"
#include "lang/string.h"
#include "vfs.h"
void devfs_init(string mountPoint)
{
vfs_mount("devfs ", mountPoint);
vfs_mount("testdev ", "/mnt/win");
vfs_mount("/dev/hda6", "/scratch");
vfs_mount("/dev/rd0 ", "/");
vfs_mount("/dev/sda1", "/mnt/usb");
vfs_mount("sysfs ", "/sys");
vfs_mount("sysfs ", "/tmp");
vfs_mount("otherfs ", "/sys");
}

17
kernel/fs/devfs.h Normal file
View File

@ -0,0 +1,17 @@
// devfs.h
// device filesystem for HOS
// Author: Josh Holtrop
// Date: 06/03/04
// Modified: 06/08/04
#ifndef __HOS_DEVFS__
#define __HOS_DEVFS__ __HOS_DEVFS__
#include "lang/string.h"
void devfs_init(string mountPoint);
#endif

113
kernel/fs/vfat.cpp Normal file
View File

@ -0,0 +1,113 @@
// vfat.c
// Author: Josh Holtrop
// Date: 03/11/04
// Modified: 03/22/04
#include "vfat.h"
#include "hos_defines.h"
#include "fs/vfs.h"
#include "mm/vmm.h"
#include "lang/cstring.h"
//From Microsoft's FAT32 File System Specification
DSKSZTOSECPERCLUS DskTableFAT16 [] =
{
{ 8400, 0}, /* disks up to 4.1 MB, the 0 value for SecPerClusVal trips an error */
{ 32680, 2}, /* disks up to 16 MB, 1k cluster */
{ 262144, 4}, /* disks up to 128 MB, 2k cluster */
{ 524288, 8}, /* disks up to 256 MB, 4k cluster */
{ 1048576, 16}, /* disks up to 512 MB, 8k cluster */
/* The entries after this point are not used unless FAT16 is forced */
// { 2097152, 32}, /* disks up to 1 GB, 16k cluster */
// { 4194304, 64}, /* disks up to 2 GB, 32k cluster */
{ 0xFFFFFFFF, 0} /* any disk greater than 2GB, 0 value for SecPerClusVal trips an error */
};
//From Microsoft's FAT32 File System Specification
DSKSZTOSECPERCLUS DskTableFAT32 [] =
{
{ 66600, 0}, /* disks up to 32.5 MB, the 0 value for SecPerClusVal trips an error */
{ 532480, 1}, /* disks up to 260 MB, .5k cluster */
{ 16777216, 8}, /* disks up to 8 GB, 4k cluster */
{ 33554432, 16}, /* disks up to 16 GB, 8k cluster */
{ 67108864, 32}, /* disks up to 32 GB, 16k cluster */
{ 0xFFFFFFFF, 64}/* disks greater than 32GB, 32k cluster */
};
int vfat_identify(vfat_bpb *bpb)
{
int rootDirSectors = ((bpb->rootEntries * 32) + (bpb->bytesPerSector - 1)) / bpb->bytesPerSector;
int totalSectors = bpb->totalSectors16 ? bpb->totalSectors16 : bpb->totalSectors32;
int fatSectors = bpb->sectorsPerFAT16 ? bpb->sectorsPerFAT16 : bpb->sectorsPerFAT32;
int dataSectors = totalSectors - (bpb->reservedSectors + bpb->numFATs * fatSectors + rootDirSectors);
int clusters = dataSectors / bpb->sectorsPerCluster;
if (clusters < 4085)
return 12;
if (clusters < 65525)
return 16;
return 32;
}
int vfat_format(Volume *vol)
{
}
FILE *vfat_open(char *fileName, dword attributes, Volume *vol)
{
while (*fileName == '/')
++fileName;
if (strlen(fileName) < 1)
return 0;
vfat_bpb *bpb = vfat_getBootSector(vol);
if (!bpb) return 0;
byte *fat = vfat_loadFAT(vol, bpb);
if (!fat)
{
free(bpb);
return 0;
}
int segs = string_split(fileName); //number of sections of path (1=file is in root directory)
int me = vfat_identify(bpb);
if (me != 32)
{
if (segs == 1) //we are looking for the file in the root directory
{
vfat_getEntryInRoot(vol, bpb, fileName, 0);
}
}
else
{
}
}
byte *vfat_loadFAT(Volume *vol, vfat_bpb *bpb)
{
int fatSize = bpb->sectorsPerFAT16 ? bpb->sectorsPerFAT16 : bpb->sectorsPerFAT32;
byte *fat = malloc(fatSize << 9); //512 bytes per sector
if (!fat) return 0;
if (vfs_readSectorn(vol, bpb->reservedSectors, fat, fatSize))
{
free(fat);
return 0;
}
return fat;
}
vfat_bpb *vfat_getBootSector(Volume *vol)
{
vfat_bpb *bs;
if (!(bs = malloc(512)))
return 0;
vfs_readSector(vol, 0, bs);
return bs;
}
int vfat_close(FILE *fp)
{
return free(fp);
}

134
kernel/fs/vfat.h Normal file
View File

@ -0,0 +1,134 @@
// vfat.h
// Author: Josh Holtrop
// Date: 03/11/04
// Modified: 03/22/04
#ifndef __HOS_VFAT__
#define __HOS_VFAT__ __HOS_VFAT__
#include "hos_defines.h"
#include "fs/vfs.h"
#define VFAT_FAT12_EOCL 0x0FF8 // end-of-cluster chain reached if FatValue >= EOCL
#define VFAT_FAT16_EOCL 0xFFF8
#define VFAT_FAT32_EOCL 0x0FFFFFF8
#define VFAT_FAT12_EOC 0x0FFF // end-of-cluster chain value
#define VFAT_FAT16_EOC 0xFFFF
#define VFAT_FAT32_EOC 0x0FFFFFFF
#define VFAT_FAT12_BAD 0x0FF7 // bad cluster mark
#define VFAT_FAT16_BAD 0xFFF7
#define VFAT_FAT32_BAD 0x0FFFFFF7
#define VFAT_DIRENTRY_FREE 0xE5
#define VFAT_DIRENTRY_FREE_LAST 0x00
typedef struct
{
byte jmpBoot[3]; // {0xEB, 0x??, 0x90} or {0xE9, 0x??, 0x??}
char OEMName[8]; // any 8-char string (def. "MSWIN4.1")
word bytesPerSector; // 512 (default), 1024, 2048, 4096
byte sectorsPerCluster; // 1 (default), 2, 4, 8, 16, 32, 64, 128
word reservedSectors; // 1 (fat12/16), 32 (fat32)
byte numFATs; // 2
word rootEntries; // number of 32-byte root directory entries (224 for 1440k floppy) - 0 for fat32
word totalSectors16; // total number of sectors in volume (2880 for floppy) - 0 for fat32
byte media; // >= 0xF0 valid, 0xF8 (default non-removable), 0xF0 (default removable), must match lsb of FAT[0]
word sectorsPerFAT16; // number of sectors in FAT (9 for floppy)
word sectorsPerTrack; // (18 for floppy)
word numHeads; // number of heads (2 for floppy)
dword hiddenSectors; // 0
dword totalSectors32; // 0, non-zero for fat32 volumes
/* FAT32 specific members */
dword sectorsPerFAT32; // number of sectors in a fat for fat32 volumes
word extFlags; // bits 0-3 active fat, bit 7 {0 = mirror all FATs, 1 = only use 1 FAT}
word fsVersion; // fat32 version (0:0)
dword rootCluster; // first cluster of root directory (default 2)
word fsInfo; // sector number of FSINFO block (default 1)
word bootCopy; // sector of backup boot record (default 6)
} __attribute__ ((packed)) vfat_bpb;
typedef struct
{
dword leadSignature; // 0x41615252
byte reserved1[480];
dword structSignature; // 0x61417272
dword lastFree; // last known free cluster (0xFFFFFFFF == unknown)
dword nextFree; // start looking for free clusters here (0xFFFFFFFF == unknown)
byte reserved2[12];
dword trailSignature; // 0xAA550000
} __attribute__ ((packed)) vfat_fsinfo;
typedef struct
{
char fileName[8]; // file name, 8 char. max, pad w/ spaces
char fileExt[3]; // file extension, 3 char. max, pad w/ spaces
byte attributes; // file attributes, read-only, etc.
byte reserved; // 0
byte timeTenths; // 0-199
word time; // time of creation
word date; // date of creation
word adate; // last accessed date
word clusterHigh; // 0 for fat12/16
word wtime; // last write time
word wdate; // last write date
word clusterLow; // LSW of first cluster of file data
dword fileSize;
} __attribute__ ((packed)) vfat_dirEntry;
typedef struct
{
byte order;
word name0_4[5]; // filename - first 5 characters (unicode)
byte attributes; // must be VFAT_LONG_NAME
byte type; // 0 = part of long name
byte checksum; // checksum of short entry at end of long entry set
word name5_10[6]; // filename - next 6 characters (unicode)
word clusterLow; // 0
word name11_12[2]; // filename - next 2 characters
} __attribute__ ((packed)) vfat_lfnEntry;
#define VFAT_READ_ONLY 0x01
#define VFAT_HIDDEN 0x02
#define VFAT_SYSTEM 0x04
#define VFAT_VOLUME 0x08
#define VFAT_DIRECTORY 0x10
#define VFAT_ARCHIVE 0x20
#define VFAT_LONG_NAME 0x0F // VFAT_READ_ONLY | VFAT_HIDDEN | VFAT_SYSTEM | VFAT_VOLUME
#define VFAT_ATTR_MASK 0x3F // VFAT_READ_ONLY | VFAT_HIDDEN | VFAT_SYSTEM | VFAT_VOLUME | VFAT_DIRECTORY | VFAT_ARCHIVE
#define VFAT_ORDER_MASK 0x40
/*
* Illegal file name characters:
* Values less than 0x20 except for 0x05. 0x05 signifies that the actual filename character is 0xE5
* 0x22 ("), 0x2A (*)
* 0x2E (.), 0x2F (/), 0x3A (:)
* 0x3C (<), 0x3E (>), 0x3F (?), 0x5C (\), 0x7C (|)
* The following are illegal in 8.3 but legal in LFN:
* 0x2B (+), 0x2C (,), 0x3B (;), 0x3D (=), 0x5B ([), 0x5D (])
*/
//From Microsoft's FAT32 File System Specification
typedef struct
{
dword diskSize;
byte sectorsPerCluster;
} DSKSZTOSECPERCLUS;
// sector[510] == 0x55
// sector[511] == 0xAA
int vfat_identify(vfat_bpb *bpb);
int vfat_format(Volume *vol);
FILE *vfat_open(char *fileName, dword attributes, Volume *vol);
vfat_bpb *vfat_getBootSector(Volume *vol);
int vfat_close(FILE *fp);
byte *vfat_loadFAT(Volume *vol, vfat_bpb *bpb)
#endif

55
kernel/fs/vfs.cpp Normal file
View File

@ -0,0 +1,55 @@
// vfs.cpp
// Author: Josh Holtrop
// Date: 03/11/04
// Modified: 04/16/04
#include "hos_defines.h"
#include "vfs.h"
//#include "fs/vfat.h"
//#include "block/rd.h"
//#include "block/loop.h"
#include "lang/LinkedList.h"
#include "lang/string.h"
#include "devfs.h"
#include "kio.h"
#include "Mount.h"
LinkedList<Mount> *mounts;
void vfs_init()
{
mounts = new LinkedList<Mount>;
}
void list()
{
LinkedList<Mount>::iterator it = mounts->begin();
while (it != mounts->end())
{
printf("%s\t%s\n", (*it).device.data(), (*it).mountPoint.data());
++it;
}
}
int vfs_mount(string device, string mountPoint)
{
Mount mount(device, mountPoint);
LinkedList<Mount>::iterator it = mounts->begin();
int i = 0;
while (it != mounts->end() && (*it).mountPoint <= mount.mountPoint)
{
if (*it == mount)
return 1; //device already mounted or mount point already taken
i++;
++it;
}
mounts->insert(i, mount);
return 0;
}

19
kernel/fs/vfs.h Normal file
View File

@ -0,0 +1,19 @@
// vfs.h
// Author: Josh Holtrop
// Date: 03/11/04
// Modified: 06/16/04
#ifndef __HOS_VFS__
#define __HOS_VFS__ __HOS_VFS__
#include "hos_defines.h"
#include "lang/string.h"
void vfs_init();
int vfs_mount(string device, string mountPoint);
void list();
#endif

94
kernel/functions.h Normal file
View File

@ -0,0 +1,94 @@
//functions.h
//05/07/03 Josh Holtrop
//for HOS
//Modified: 02/26/04
#ifndef __HOS_FUNCTIONS__
#define __HOS_FUNCTIONS__ __HOS_FUNCTIONS__
#include "hos_defines.h"
#include "sys/io.h"
extern dword _code;
extern dword _bss;
extern dword _end;
//Enables (SeTs) Interrupt Flag on the processor
static inline void enable_ints()
{
asm("sti");
}
//Disables (CLears) Interrupt Flag on the processor
static inline void disable_ints()
{
asm("cli");
}
//Restarts the computer
static inline void restart()
{
enable_ints();
byte temp;
do
{
temp = inportb(0x64);
if (temp & 1)
inportb(0x60);
} while(temp & 2);
outportb (0x64, 0xfe);
for (;;) {}
}
//Halts (freezes) the computer
static inline void halt()
{
asm("cli");
asm("hlt");
while (1);
}
//Initializes 8253 Programmable Interrupt Timer
static inline void timer_init()
{
//set timer : 2e9c = 100hz
outportb(0x43, 0x34);
outportb(0x40, 0x9c); //lsb
outportb(0x40, 0x2e); //msb
}
//Returns the size of the kernel (code & data)
// - this does include the bss section
// - this should be 4kb aligned per the linker script
// - this is the amount of RAM the kernel code, data, & bss take
static inline dword kernel_size_used()
{
return (dword)(&_end)-(dword)(&_code);
}
//Returns the size of the kernel (code & data)
// - this does not include the bss section
// - this should be 4kb aligned per the linker script
// - this should be the size of kernel.bin
static inline dword kernel_size()
{
return (dword)(&_bss)-(dword)(&_code);
}
//converts a binary-coded-decimal byte to its decimal equivalent
static inline byte bcd2byte(byte bcd)
{
return (10 * ((bcd & 0xF0) >> 4)) + (bcd & 0x0F);
}
//converts a binary-coded-decimal byte to its decimal equivalent
static inline byte byte2bcd(byte bite)
{
return ((bite / 10) << 4) | (bite % 10);
}
#endif

71
kernel/gdt.inc Normal file
View File

@ -0,0 +1,71 @@
;gdt.inc
;Author: Josh Holtrop
;Date: 10/30/03
;Modified: 03/02/04
gdtr:
dw gdt_end-gdt-1
dd GDT_V
gdt:
dd 0
dd 0
KERNEL_CODE equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0x9A ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
KERNEL_DATA equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
USER_CODE equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0xFA ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
USER_DATA equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0xF2 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
gVESA_CODE equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0x9A ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
VESA_DATA equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
VIDEO_TEXT equ $-gdt
dw 0x7FFF ;limit 15:0
dw 0x8000 ;base 15:0
db 0x0B ;base 23:16
db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
VIDEO_GRAPHICS equ $-gdt
dw 0xFFFF ;limit 15:0
dw 0x0000 ;base 15:0
db 0x0A ;base 23:16
db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
gdt_end:

27
kernel/hos_defines.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "mm/vmm.h"
//overload the operator "new"
void * operator new (dword size)
{
return malloc(size);
}
//overload the operator "new[]"
void * operator new[] (dword size)
{
return malloc(size);
}
//overload the operator "delete"
void operator delete (void *p)
{
free(p);
}
//overload the operator "delete[]"
void operator delete[] (void *p)
{
free(p);
}

48
kernel/hos_defines.h Normal file
View File

@ -0,0 +1,48 @@
//hos_defines.h
//03/17/03 Josh Holtrop
//Modified: 03/02/04
#ifndef __HOS_HOS_DEFINES__
#define __HOS_HOS_DEFINES__ __HOS_HOS_DEFINES__
#define FREERAM_START 0x368000 // 0x368000 is first available byte (this is right after the initrd @ 2mb, 1440kb.
#define MAX_RAM 0x40000000 //1gb maximum RAM supported
#define PID_KERNEL 0x02 //kernel's PID
#define PID_VMM 0x03
#define PID_USER 0x10000 //user processes' start PID
//these defines are the memory locations of values saved by the stage 2 bootloader
#define BOOT_MEMMAP_ENTRIES 0xC009040A
#define BOOT_FIRST_MEMMAP 0xC0092000
#define BOOT_VIDEO_MODE 0xC0090002
#define BOOT_VIDEO_MODE_INFO_BLOCK 0xC0090306
#define BOOT_HASRD 0xC0090000
#define NULL 0
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;
typedef struct {
dword lowdword;
dword highdword;
} __attribute__((packed)) qword;
//overload the operator "new"
void * operator new (dword size);
//overload the operator "new[]"
void * operator new[] (dword size);
//overload the operator "delete"
void operator delete (void *p);
//overload the operator "delete[]"
void operator delete[] (void *p);
#endif

117
kernel/idt.inc Normal file
View File

@ -0,0 +1,117 @@
;idt.inc
;Author: Josh Holtrop
;Date: 10/30/03
;Modified: 03/02/04
idtr:
dw 50*8-1 ;size of idt
dd IDT_V ;address of idt
%macro isr_label 1
isr_%1:
push eax
mov eax, %1
jmp isr_main
%endmacro
isr_label 0
isr_label 1
isr_label 2
isr_label 3
isr_label 4
isr_label 5
isr_label 6
isr_label 7
isr_label 8
isr_label 9
isr_label 10
isr_label 11
isr_label 12
isr_label 13
isr_label 14
isr_label 15
isr_label 16
isr_label 17
isr_label 18
isr_label 19
isr_label 20
isr_label 21
isr_label 22
isr_label 23
isr_label 24
isr_label 25
isr_label 26
isr_label 27
isr_label 28
isr_label 29
isr_label 30
isr_label 31
isr_label 32
isr_label 33
isr_label 34
isr_label 35
isr_label 36
isr_label 37
isr_label 38
isr_label 39
isr_label 40
isr_label 41
isr_label 42
isr_label 43
isr_label 44
isr_label 45
isr_label 46
isr_label 47
isr_label 48
isr_label 49
isr_main:
cmp eax, 0x30
jz isr_syscall
pusha
push ds
push es
push eax
call _isr
add esp, 4
pop es
pop ds
popa
pop eax
iret
isr_syscall:
pop eax ;syscall function number
pusha
push ds
push es
sc1:
cmp eax, 1 ;syscall 1 - putc
jnz sc2
push ebx
call _putc
add esp, 4
jmp scdone
sc2:
scdone:
pop es
pop ds
popa
iret

102
kernel/kernel.asm Normal file
View File

@ -0,0 +1,102 @@
;kernel.asm
;Author: Josh Holtrop
;Date: 10/30/03
;Modified: 10/30/03
%define GDT_P 0x100000; ;1mb physical - Global Descriptor Table space
%define GDT_V GDT_P+0xC0000000
%define IDT_P 0x102000 ;1mb+8kb - Interrupt Descriptor Table space
%define IDT_V IDT_P+0xC0000000
%define PDBR_P 0x104000 ;1mb+16kb - Page Directory Base Register (first PD)
%define PDBR_V PDBR_P+0xC0000000
%define LOPT_P 0x105000 ;1mb+20kb - LOw Page Table for mapping first 4mb
%define LOPT_V LOPT_P+0xC0000000
%define KERNEL_P 0x106000 ;1mb+24kb - the kernel's physical address
%define KERNEL_V KERNEL_P+0xC0000000 ;3gb+1mb+24kb, the virtual address of the kernel
[global _start]
[extern _isr]
[extern _k_init]
[extern _putc]
bits 32
;This is where the kernel begins execution
;At this point, the temporary gdt is set up to "map" 0xC000_0000 to 0x0.
;We must enable paging with the first 4mb mapped 1:1 virtual:physical
; and with the 4mb starting at 0xC000_0000 mapped to the first 4mb physical.
;Then we can start using our "real" gdt, then unmap the lower 4mb.
_start:
cli ;if they weren't already off
xor eax, eax
mov edi, PDBR_V
mov ecx, 1024 ;clear the PDBR
rep stosd
mov [PDBR_V], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
mov [PDBR_V+0xC00], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
mov edi, LOPT_V
mov ecx, 1024
mov eax, 0x03 ;starting physical address = 0x0 (read/write, present flags)
fill_lopt_loop: ;fill the page table
stosd
add eax, 4096 ;increment next phsyical address by 4kb
loop fill_lopt_loop
mov eax, PDBR_P
mov cr3, eax ;store the Page Directory Base Address
mov eax, cr0
or eax, 0x80000000 ;set page enable bit
mov cr0, eax ;now paging is active!
mov edi, GDT_V
mov esi, gdt
mov ecx, gdt_end-gdt
copy_gdt:
lodsb
stosb
loop copy_gdt
mov edi, IDT_V ;destination
mov esi, isr_0 ;address of isr0
mov edx, isr_1-isr_0 ;distance between isr labels
mov ecx, 50 ;number of isrlabels
fill_idt:
mov ebx, esi
mov ax, si
stosw ;0 offset 15:0
mov ax, KERNEL_CODE
stosw ;2 selector 15:0
mov ax, 0x8E00
stosw ;4 [P][DPL][0][TYPE][0][0][0][0][0][0][0][0]
shr esi, 16
mov ax, si
stosw ;6 offset 31:16
mov esi, ebx
add esi, edx
loop fill_idt
mov word [IDT_V+0x30*8+4], 0xEE00 ;interrupt 0x30 has user priviledges
lgdt [gdtr] ;load gdt
jmp KERNEL_CODE:newgdtcontinue
newgdtcontinue:
mov ax, KERNEL_DATA
mov es, ax
mov ds, ax
mov gs, ax
mov fs, ax
mov ss, ax
mov esp, 0xc0200000 ;stack just under 3gb+2mb, moves downward
lidt [idtr] ;load idt
call _k_init
haltit:
hlt ;halt processor when k_init is done
jmp haltit ;shouldn't get here...
%include "gdt.inc"
%include "idt.inc"

129
kernel/kernel.cpp Normal file
View File

@ -0,0 +1,129 @@
// kernel.c
// Author: Josh Holtrop
// Date: 08/13/03
// Holtrop's Operating System - Version 0.13
// Modified: 03/08/04
#include "hos_defines.h" //#DEFINE's for kernel
#include "functions.h" //general functions
#include "asmfuncs.h" //assembly functions
#include "kio.h" //kernel input/output functions
#include "mm/mm.h" //physical memory management functions
#include "mm/vmm.h" //virtual memory management & paging functions
#include "char/keyboard.h" //generic keyboard driver & functions
#include "char/mouse.h" //generic ps/2 mouse driver & functions
#include "block/fdc.h" //Floppy Disk Controller functions
#include "sys/cmos.h" //CMOS interface functions
#include "sys/io.h" //port i/o functions
#include "sys/pic.h" //Programmable Interrupt Controller functions
#include "sys/rtc.h" //Real Time Clock functions
#include "video/video.h" //video functions
#include "fs/vfs.h" //Virtual File System layer
#include "fs/devfs.h" //Device filesystem
extern "C" {
void isr(dword num);
void k_init();
dword timer = 0;
//Main kernel initialization method
void k_init()
{
// ===== Initialization
fdc_sendDOR(0x0C); //turn off floppy motor!!
mm_init();
vmm_init();
video_init();
kio_init();
kio_console_cls();
pic_remap(0x20, 0x28);
timer_init();
mouse_init();
pic_mask1(0); //unmask IRQ's 0-7
pic_mask2(0); //unmask IRQ's 8-15
enable_ints();
kbd_resetLEDs(); //after enabling interrupts!!
if (video_Mode())
{
int w = video_getWidth(), h = video_getHeight();
int p = w * h - 1;
for (; p >= 0; p--)
video_pseti(p, 0x00000075);
int x = w >> 1, y = h >> 1, sz = h >> 1;
for (p = 0; p <= sz; p += 24)
{
video_line(x + p, y, x, y + sz - p, 0x0000FF00);
video_line(x + p, y, x, y - sz + p, 0x0000FF00);
video_line(x - p, y, x, y + sz - p, 0x0000FF00);
video_line(x - p, y, x, y - sz + p, 0x0000FF00);
}
kio_drawConsole();
}
printf("HOS 0.14 - Kernel File Size: %uKb Mem Used: %uKb\n", kernel_size()>>10, kernel_size_used()>>10);
printf("Memory available to OS: %u MB (%u bytes)\n", mm_getTotalMegs(), mm_getTotalMem());
printf("Free memory: %u bytes (%u pages)\n", mm_freemem(), mm_freemem()>>12);
printf("Built on %s at %s\n", __DATE__, __TIME__);
printf("%b/%b/%b %b:%b:%b\n", rtc_readMonth(), rtc_readDay(), rtc_readYear(), rtc_readHour(), rtc_readMinute(), rtc_readSecond());
vfs_init();
devfs_init("/dev");
list();
printf("Done.\n");
dword key = 0;
for (;;)
{
key = kbdWaitKey();
if ((key & 0xFF) > 2) //key is not a control key
putc(key);
}
}
// main Interrupt Service Routine - handles all interrupts unless caught by kernel.asm
void isr(dword num)
{
switch(num)
{
case 14:
printf("Page fault, CR2 = 0x%x\n", read_cr2());
{
enable_ints();
for (;;) ; //infinetly loop so that my KVM will still work :) 06/10/04
}
// halt();
break;
case 0x20: // IRQ0 - timer interrupt
timer++;
(*(byte *)(0xc00b8000))++;
if (!(timer % 100))
{
dword curPos = kio_getCursorPosition();
kio_writeCursorPosition(72);
printf("%b:%b:%b\n", rtc_readHour(), rtc_readMinute(), rtc_readSecond());
kio_writeCursorPosition(curPos);
}
pic_eoi();
break;
case 0x21: // IRQ1 - keyboard interrupt
isr_keyboard(); //isr_keybard() takes care of calling eoi()
break;
case 0x2C: // IRQ12 - PS/2 mouse
isr_mouse();
pic_eoi2();
break;
default:
printf("Interrupt %d (0x%x) Unhandled!!\n", num, num);
halt();
break;
}
}
}

227
kernel/kio.cpp Normal file
View File

@ -0,0 +1,227 @@
// kio.c
// Author: Josh Holtrop
// Created: 12/25/03
// Modified: 04/06/04
#include "hos_defines.h"
#include "kio.h"
#include "asmfuncs.h"
#include "video/video.h"
dword graphical;
dword cursorPosition; //Caches the current cursor position
word console_memory[2000]; //holds a copy of the console's memory
// This is the main output routine, it uses a format string and a variable
// number of arguments to print formatted text
extern "C" {
void kio_init()
{
graphical = video_Mode();
cursorPosition = 0;
writeCursorPosition(0);
}
void printf(char *fmt, ...)
{
dword *params = ((dword *)(&fmt)) + 1; //points to the first paramater
int i;
int special = 0;
for (i = 0; ; i++)
{
if (special)
{
special = 0;
switch (fmt[i])
{
case 0:
return;
case '%':
putc('%');
break;
case 's': case 'S':
puts((char *)*params);
params++;
break;
case 'c': case 'C':
putc(*params);
params++;
break;
case 'd': case 'D': case 'i': case 'I':
putDec(*params);
params++;
break;
case 'u': case 'U':
putDecu(*params);
params++;
break;
case 'x': case 'X':
putHex(*params);
params++;
break;
case 'b': case 'B':
kio_putBCD(*params);
params++;
break;
}
}
else
{
switch (fmt[i])
{
case '%':
special = 1;
break;
case 0:
return;
default:
putc(fmt[i]);
}
}
}
}
// This function draws a single character
void putc(dword chr)
{
char charac = (char)chr;
word *vidmem = (word *)0xC00B8000;
if (charac == '\n')
{
if (cursorPosition % 80)
cursorPosition = cursorPosition + 80 - (cursorPosition % 80);
else
cursorPosition += 80;
}
else if (charac == '\t')
{
if (cursorPosition % 8)
cursorPosition = cursorPosition + 8 - (cursorPosition % 8);
else
cursorPosition += 8;
}
else
{
if (graphical)
{
console_memory[cursorPosition] = charac | 0x0700;
kio_drawConsoleChar(cursorPosition);
}
else
{
console_memory[cursorPosition] = charac | 0x0700;
vidmem[cursorPosition] = charac | 0x0700;
}
cursorPosition++;
}
if (cursorPosition >= 2000)
{
kio_console_scroll();
cursorPosition = 2000-80;
}
if (!graphical)
writeCursorPosition(cursorPosition);
}
// This function displays a number in hexadecimal
void putHex(dword number)
{
int hitNum = 0;
int i;
for (i = 7; i >= 0; i--)
{
dword val = (number >> (i*4)) & 0xF;
if ((val != 0) || (i == 0))
hitNum = 1;
if (hitNum)
{
val = val + '0';
if (val > '9')
val = val + ('A' - '9' - 1);
putc(val);
}
}
}
void kio_putBCD(dword bcd)
{
putc(((bcd & 0xF0) >> 4) + '0');
putc((bcd & 0xF) + '0');
}
void kio_console_scroll()
{
memcpyd(console_memory, console_memory + 80, 960);
memsetw(console_memory + 1920, 0x0720, 80);
if (graphical)
kio_drawConsole();
else
memcpyd((void *)0xC00B8000, console_memory, 1000);
}
void kio_console_cls()
{
memsetw(console_memory, 0x0720, 2000);
if (graphical)
kio_drawConsole();
else
memcpyd((void *)0xC00B8000, console_memory, 1000);
writeCursorPosition(0);
}
// This function draws a simple "console" window in graphical mode to display text
void kio_drawConsole()
{
video_rectf(8, 8, 491, 261, 0);
video_rect(7, 7, 492, 262, 0x00777777);
int x, y;
x = 250, y = 135;
int s = 100, p = 0;
for (p = 0; p <= s; p += 16)
{
video_line(x + p, y, x, y + s - p, 0x00008800);
video_line(x + p, y, x, y - s + p, 0x00008800);
video_line(x - p, y, x, y + s - p, 0x00008800);
video_line(x - p, y, x, y - s + p, 0x00008800);
}
for (x = 0; x < 80; x++)
{
for (y = 0; y < 25; y++)
{
video_renderChar(x*6+10, y*10+10, console_memory[y*80+x], 0, 0x00FFFFFF, 0, 0);
}
}
}
// This function draws a "console" character to the graphical video screen
void kio_drawConsoleChar(dword position)
{
int x = position % 80;
int y = position / 80;
video_renderChar(x*6+10, y*10+10, console_memory[y*80+x], 0, 0x00FFFFFF, 1, 0);
}
dword kio_getCursorPosition()
{
return cursorPosition;
}
void kio_writeCursorPosition(dword position)
{
cursorPosition = position;
if (!graphical)
writeCursorPosition(position);
}
}

29
kernel/kio.h Normal file
View File

@ -0,0 +1,29 @@
// kio.h
// Author: Josh Holtrop
// Created: 12/25/03
// Modified: 05/21/04
#ifndef __HOS_KIO__
#define __HOS_KIO__ __HOS_KIO__
#include "hos_defines.h"
extern "C" {
void kio_init();
void printf(char *fmt, ...);
void putc(dword chr);
void putHex(dword number);
void kio_drawConsole();
void kio_drawConsoleChar(dword position);
void kio_console_scroll();
void kio_console_cls();
void kio_putBCD(dword bcd);
dword kio_getCursorPosition();
void kio_writeCursorPosition(dword position);
}
#endif

210
kernel/lang/LinkedList.h Normal file
View File

@ -0,0 +1,210 @@
// LinkedList.h
// implements a LinkedList container for HOS
// Author: Josh Holtrop
// Date: 05/22/04
// Modified: 06/09/04
#ifndef __HOS_LINKEDLIST__
#define __HOS_LINKEDLIST__ __HOS_LINKEDLIST__
template <typename Element>
class LinkedList
{
private:
class LinkedNode
{
public:
LinkedNode()
{
prev = next = 0;
}
LinkedNode(Element dataElement)
{
data = dataElement;
prev = next = 0;
}
Element data;
LinkedNode *next;
LinkedNode *prev;
};
LinkedNode *firstNode;
LinkedNode *lastNode;
int count;
public:
class iterator
{
private:
LinkedNode *theNode;
public:
iterator(LinkedNode & node)
{
theNode = &node;
}
iterator(LinkedNode *node)
{
theNode = node;
}
Element & operator*()
{
return theNode->data;
}
void operator++() //prefix
{
theNode = theNode->next;
}
void operator++(int dum) //postfix
{
theNode = theNode->next;
}
bool operator==(const iterator & second) const
{ return theNode == second.theNode; }
bool operator!=(const iterator & second) const
{ return theNode != second.theNode; }
};
class reverse_iterator
{
private:
LinkedNode *theNode;
public:
reverse_iterator(LinkedNode & node)
{
theNode = &node;
}
reverse_iterator(LinkedNode *node)
{
theNode = node;
}
Element & operator*()
{
return theNode->data;
}
void operator++() //prefix
{
theNode = theNode->prev;
}
void operator++(int dum) //postfix
{
theNode = theNode->prev;
}
bool operator==(const reverse_iterator & second) const
{ return theNode == second.theNode; }
bool operator!=(const reverse_iterator & second) const
{ return theNode != second.theNode; }
};
/* Basic constructor */
LinkedList();
/* How many elements in the list */
int size() { return count; }
/* Return some iterators for traversing the list */
iterator begin() { return iterator(firstNode->next); }
iterator end() { return iterator(lastNode->next); }
reverse_iterator rbegin() { return reverse_iterator(lastNode); }
reverse_iterator rend() { return reverse_iterator(firstNode); }
/* Insert an element, its position will be index */
LinkedList & insert(int index, Element e);
/* Append an element to the end of the list */
LinkedList & push_back(Element e);
/* Remove an element at position index */
LinkedList & remove(int index);
/* Pop an element from the end of the list */
LinkedList & pop_back();
/* Direct access to an element in the list */
Element & operator[](int index);
};
template <typename T>
LinkedList<T>::LinkedList()
{
firstNode = lastNode = new LinkedNode(); //head node
count = 0;
}
template <typename Element>
LinkedList<Element> & LinkedList<Element>::insert(int index, Element e)
{
if (index == count)
push_back(e);
else if (index >= 0 && index < count)
{
LinkedNode *nptr = firstNode;
for (int i = 0; i <= index; i++)
nptr = nptr->next;
LinkedNode *newptr = new LinkedNode(e);
newptr->next = nptr;
newptr->prev = nptr->prev;
newptr->prev->next = newptr;
nptr->prev = newptr;
count++;
}
return *this;
}
template <typename Element>
LinkedList<Element> & LinkedList<Element>::push_back(Element e)
{
lastNode->next = new LinkedNode(e);
lastNode->next->prev = lastNode;
lastNode = lastNode->next;
count++;
return *this;
}
template <typename Element>
LinkedList<Element> & LinkedList<Element>::remove(int index)
{
if (index == count-1)
pop_back();
else if (index >= 0 && index < count)
{
LinkedNode *nptr = firstNode;
for (int i = 0; i <= index; i++)
nptr = nptr->next;
nptr->prev->next = nptr->next;
nptr->next->prev = nptr->prev;
delete nptr;
count--;
}
return *this;
}
template <typename Element>
LinkedList<Element> & LinkedList<Element>::pop_back()
{
if (count)
{
lastNode = lastNode->prev;
delete lastNode->next;
lastNode->next = 0;
count--;
}
return *this;
}
template <typename Element>
Element & LinkedList<Element>::operator[](int index)
{
if (index >= 0 && index < count)
{
LinkedNode *nptr = firstNode;
for (int i = 0; i <= index; i++)
nptr = nptr->next;
return nptr->data;
}
return firstNode->data;
}
#endif

91
kernel/lang/cstring.cpp Normal file
View File

@ -0,0 +1,91 @@
// cstring.c
// Author: Josh Holtrop
// Created: 02/26/04
// Modified: 06/01/04
// Implements c string functions
#include "string.h"
#include "asmfuncs.h"
char *strcat(char *dest, const char *src)
{
strcpy(dest+strlen(dest), src);
return dest;
}
//Splits a string into multiple strings by turning all characters
// equal to delim into null values (string termination character)
//Returns the number of strings after the split, 1 if no delim chars
int string_split(char *str, char delim)
{
if (strlen(str) < 1)
return 0; //empty string
int count = 1;
for (; *str; str++)
{
if (*str == delim)
{
count++;
*str = 0;
}
}
return count;
}
//Advances a char pointer to the byte after the current string's
// null-terminating character
//Useful after calling string_split()
//Returns a pointer to the following string
char *string_advance(char *str)
{
for (; *str; str++);
return str+1;
}
void rtrim(char *str)
{
str += strlen(str); //now points to the null character at the end of the string
str--;
for (;;)
{
if ((*str == ' ') || (*str == '\t') || (*str == '\n'))
*str-- = 0;
else
break;
}
}
char *ucase(char *str)
{
char *ret = str;
for (;;)
{
if (*str == 0)
break;
if ((*str >= 'a') && (*str <= 'z'))
*str = (*str) - 32;
str++;
}
return ret;
}
char *lcase(char *str)
{
char *ret = str;
for (;;)
{
if (*str == 0)
break;
if ((*str >= 'A') && (*str <= 'Z'))
*str = (*str) + 32;
str++;
}
return ret;
}

19
kernel/lang/cstring.h Normal file
View File

@ -0,0 +1,19 @@
// cstring.h
// Author: Josh Holtrop
// Created: 02/26/04
// Modified: 06/01/04
// Implements c string functions
#ifndef __HOS_CSTRING__
#define __HOS_CSTRING__ __HOS_CSTRING__
char *strcat(char *dest, const char *src);
int string_split(char *str, char delim);
char *string_advance(char *str);
void rtrim(char *str);
char *ucase(char *str);
char *lcase(char *str);
#endif

279
kernel/lang/string.cpp Normal file
View File

@ -0,0 +1,279 @@
// string.cpp
// implements c++ string object for HOS
// Author: Josh Holtrop
// Date: 06/01/04
// Modified: 06/07/04
#include "string.h" //string class declaration
#include "asmfuncs.h" //memcpy(void *dest, void *src, int n), strlen(char *str)
string::string()
{
myLength = 0;
myChars = new char; //myChars must be a valid pointer at all times
*myChars = 0;
}
string::~string()
{
delete[] myChars;
}
string::string(const string & orig)
{
myLength = orig.myLength;
myChars = new char[myLength + 1];
memcpy(myChars, orig.myChars, myLength + 1);
}
string::string(const char *cstring)
{
myLength = strlen(cstring);
myChars = new char[myLength + 1];
memcpy(myChars, cstring, myLength + 1);
}
string & string::operator=(const string & orig)
{
if (this != &orig)
{
delete[] myChars;
myLength = orig.myLength;
myChars = new char[myLength + 1];
memcpy(myChars, orig.myChars, myLength + 1);
}
return *this;
}
string & string::operator=(const char *cstring)
{
if (myChars != cstring)
{
delete[] myChars;
myLength = strlen(cstring);
myChars = new char[myLength + 1];
memcpy(myChars, cstring, myLength + 1);
}
return *this;
}
char * string::data() const { return myChars; }
int string::size() const { return myLength; }
string & string::operator+=(const string & str)
{
char *newStr = new char[myLength + str.myLength + 1];
memcpy(newStr, myChars, myLength);
memcpy(newStr + myLength, str.myChars, str.myLength + 1);
delete[] myChars;
myChars = newStr;
myLength += str.myLength;
return *this;
}
string & string::operator+=(const char *cstring)
{
char *newStr = new char[myLength + strlen(cstring) + 1];
memcpy(newStr, myChars, myLength);
memcpy(newStr + myLength, cstring, strlen(cstring) + 1);
delete[] myChars;
myChars = newStr;
myLength += strlen(cstring);
return *this;
}
string & string::operator-=(const string & str)
{
char *newStr = new char[myLength + str.myLength + 1];
memcpy(newStr, str.myChars, str.myLength);
memcpy(newStr + str.myLength, myChars, myLength + 1);
delete[] myChars;
myChars = newStr;
myLength += str.myLength;
return *this;
}
string & string::operator-=(const char *cstring)
{
char *newStr = new char[myLength + strlen(cstring) + 1];
memcpy(newStr, cstring, strlen(cstring));
memcpy(newStr + strlen(cstring), myChars, myLength + 1);
delete[] myChars;
myChars = newStr;
myLength += strlen(cstring);
return *this;
}
string & string::operator+=(char chr)
{
myLength++;
char *newStr = new char[myLength + 1];
memcpy(newStr, myChars, myLength);
newStr[myLength - 1] = chr;
newStr[myLength] = 0;
delete[] myChars;
myChars = newStr;
return *this;
}
string & string::operator-=(char chr)
{
myLength++;
char *newStr = new char[myLength + 1];
memcpy(newStr + 1, myChars, myLength);
*newStr = chr;
delete[] myChars;
myChars = newStr;
return *this;
}
string::string(const string & str1, const string & str2)
{
myLength = str1.myLength + str2.myLength;
myChars = new char[myLength + 1];
memcpy(myChars, str1.myChars, str1.myLength);
memcpy(myChars + str1.myLength, str2.myChars, str2.myLength + 1);
}
string::string(const string & str1, const char *cstring)
{
myLength = str1.myLength + strlen(cstring);
myChars = new char[myLength + 1];
memcpy(myChars, str1.myChars, str1.myLength);
memcpy(myChars + str1.myLength, cstring, strlen(cstring) + 1);
}
string::string(const char *cstring, const string & str)
{
myLength = str.myLength + strlen(cstring);
myChars = new char[myLength + 1];
memcpy(myChars, cstring, strlen(cstring));
memcpy(myChars + strlen(cstring), str.myChars, str.myLength + 1);
}
string::string(const string & str1, char chr)
{
myLength = str1.myLength + 1;
myChars = new char[myLength + 1];
memcpy(myChars, str1.myChars, myLength);
myChars[myLength - 1] = chr;
myChars[myLength] = 0;
}
string::string(char chr, const string & str1)
{
myLength = str1.myLength + 1;
myChars = new char[myLength + 1];
memcpy(myChars + 1, str1.myChars, myLength + 1);
*myChars = chr;
}
const char & string::operator[](unsigned int index) const
{
if (index < myLength)
return myChars[index];
return *myChars; //if index is invalid, return a pointer to the trailing 0
}
char & string::operator[](unsigned int index)
{
if (index < myLength)
return myChars[index];
return *myChars; //if index is invalid, return a pointer to the trailing 0
}
bool string::operator==(const string & second) const
{
if (myLength != second.myLength)
return false;
for (unsigned int i = 0; i < myLength; i++)
{
if (myChars[i] != second.myChars[i])
return false;
}
return true;
}
bool string::operator==(const char *cstring) const
{
if (myLength != strlen(cstring))
return false;
for (unsigned int i = 0; i < myLength; i++)
{
if (myChars[i] != cstring[i])
return false;
}
return true;
}
bool string::operator!=(const string & second) const
{ return !operator==(second); }
bool string::operator!=(const char *cstring) const
{ return !operator==(cstring); }
bool string::operator<(const string & second) const
{
char *c1 = myChars, *c2 = second.myChars;
while (*c1 == *c2 && *c1)
{
c1++;
c2++;
}
return *c1 < *c2;
}
bool string::operator>(const string & second) const
{
char *c1 = myChars, *c2 = second.myChars;
while (*c1 == *c2 && *c1)
{
c1++;
c2++;
}
return *c1 > *c2;
}
bool string::operator<(const char *cstring) const
{
char *c1 = myChars;
while (*c1 == *cstring && *c1)
{
c1++;
cstring++;
}
return *c1 < *cstring;
}
bool string::operator>(const char *cstring) const
{
char *c1 = myChars;
while (*c1 == *cstring && *c1)
{
c1++;
cstring++;
}
return *c1 > *cstring;
}
bool string::operator<=(const string & second) const
{ return !operator>(second); }
bool string::operator>=(const string & second) const
{ return !operator<(second); }
bool string::operator<=(const char *cstring) const
{ return operator<(cstring) || operator==(cstring); }
bool string::operator>=(const char *cstring) const
{ return operator>(cstring) || operator==(cstring); }

145
kernel/lang/string.h Normal file
View File

@ -0,0 +1,145 @@
// string.h
// implements c++ string object for HOS
// Author: Josh Holtrop
// Date: 06/01/04
// Modified: 06/09/04
#ifndef __HOS_STRING__
#define __HOS_STRING__ __HOS_STRING__
class string
{
private:
/* myChars is a pointer to a character array
* It will always be a valid pointer, not null.
* The constructor is responsible for initializing
* it to point to a 1-char array with myChars[0] == 0 */
char * myChars;
/* myLength holds how many characters are in the
* string, not including the trailing null value
* (ASCII 0 character) */
unsigned int myLength;
public:
/* Basic constructors */
string();
~string();
/* Copy constructor */
string(const string & orig);
/* Construct strings from c-style strings:
* Allows declarations like string s = "data"; */
string(const char *cstring);
/* Assignment operators */
string & operator=(const string & orig);
string & operator=(const char *cstring);
/* Boolean comparison operators */
bool operator==(const string & second) const;
bool operator==(const char *cstring) const;
bool operator!=(const string & second) const;
bool operator!=(const char *cstring) const;
bool operator<(const string & second) const;
bool operator>(const string & second) const;
bool operator<(const char *cstring) const;
bool operator>(const char *cstring) const;
bool operator<=(const string & second) const;
bool operator>=(const string & second) const;
bool operator<=(const char *cstring) const;
bool operator>=(const char *cstring) const;
/* Construct strings made up of combinations of other
* strings, c-style strings, and characters */
string(const string & str1, const string & str2);
string(const string & str1, const char *cstring);
string(const char *cstring, const string & str);
string(const string & str1, char chr);
string(char chr, const string & str1);
/* Append and prepend operators */
string & operator+=(const string & str);
string & operator+=(const char *cstring);
string & operator-=(const string & str);
string & operator-=(const char *cstring);
string & operator+=(char chr);
string & operator-=(char chr);
/* Direct character-access operators */
const char & operator[](unsigned int index) const;
char & operator[](unsigned int index);
/* Returns handle to actual character-array for programs
* that need raw data instead of a string object */
char * data() const;
/* Returns the size of the string. This is myLength
* and is the number of characters in the string
* not counting the trailing null (ASCII 0) character */
int size() const;
};
static inline bool operator==(char *cstring, const string & str)
{ return str == cstring; }
static inline bool operator!=(char *cstring, const string & str)
{ return str != cstring; }
static inline bool operator<(const char *cstring, const string & str)
{ return str > cstring; }
static inline bool operator>(const char *cstring, const string & str)
{ return str < cstring; }
static inline bool operator<=(const char *cstring, const string & str)
{ return str >= cstring; }
static inline bool operator>=(const char *cstring, const string & str)
{ return str <= cstring; }
static inline string & operator+=(const char *cstring, string & str)
{ return str -= cstring; }
static inline string & operator-=(const char *cstring, string & str)
{ return str += cstring; }
static inline string & operator+=(char chr, string & str)
{ return str -= chr; }
static inline string & operator-=(char chr, string & str)
{ return str += chr; }
static inline string operator+(const string & str1, const string & str2)
{ return string(str1, str2); }
static inline string operator+(const string & str1, const char *cstring)
{ return string(str1, cstring); }
static inline string operator-(const string & str1, const string & str2)
{ return string(str2, str1); }
static inline string operator-(const string & str1, const char *cstring)
{ return string(cstring, str1); }
static inline string operator+(const string & str1, char chr)
{ return string(str1, chr); }
static inline string operator-(const string & str1, char chr)
{ return string(chr, str1); }
static inline string operator+(char chr, const string & str1)
{ return string(chr, str1); }
static inline string operator-(char chr, const string & str1)
{ return string(str1, chr); }
#endif

26
kernel/link.ld Normal file
View File

@ -0,0 +1,26 @@
OUTPUT_FORMAT("binary")
ENTRY(_start)
SECTIONS
{
.text 0xC0106000 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data : {
data = .; _data = .; __data = .;
*(.data)
. = ALIGN(4096);
}
.rodata : {
rodata = .; _rodata = .; __rodata = .;
*(.rodata)
. = ALIGN(4096);
}
.bss : {
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .; _end = .; __end = .;
}

22
kernel/link.ms Normal file
View File

@ -0,0 +1,22 @@
OUTPUT_FORMAT("pe-i386")
ENTRY(_start)
SECTIONS
{
.text 0xC0106000 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data : {
data = .; _data = .; __data = .;
*(.data)
. = ALIGN(4096);
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .; _end = .; __end = .;
}

422
kernel/lst/LDout.doc Normal file
View File

@ -0,0 +1,422 @@
Memory Configuration
Name Origin Length Attributes
*default* 0x0000000000000000 0xffffffffffffffff
Linker script and memory map
.text 0x00000000c0106000 0x5000
0x00000000c0106000 code = .
0x00000000c0106000 _code = .
0x00000000c0106000 __code = .
*(.text)
.text 0x00000000c0106000 0x384 ks.o
0x00000000c0106000 _start
.text 0x00000000c0106384 0x55b kernel.o
0x00000000c0106384 _k_init
0x00000000c0106694 _isr
*fill* 0x00000000c01068df 0x1 00
.text 0x00000000c01068e0 0x308 asmfuncs.o
0x00000000c01068fe _read_cr3
0x00000000c0106902 _strcmp
0x00000000c0106a11 _puts
0x00000000c0106998 _memsetd
0x00000000c01069c6 _invlpg_
0x00000000c0106a30 _putDecu
0x00000000c0106954 _memcpyd
0x00000000c010693d _memcpy
0x00000000c010696b _memset
0x00000000c01068fa _read_cr2
0x00000000c01069ce _writeCursorPosition
0x00000000c0106981 _memsetw
0x00000000c0106af8 _putDec
0x00000000c0106928 _strcpy
0x00000000c01069ae _strlen
0x00000000c01069f4 _getCursorPosition
0x00000000c01068e0 _write_cr0
0x00000000c01068ef _write_cr3
0x00000000c01068eb _read_cr0
.text 0x00000000c0106be8 0x69a keyboard.o
0x00000000c010711c _kbdGetKey
0x00000000c01071b2 _kbd_resetLEDs
0x00000000c0106be8 _isr_keyboard
0x00000000c010716e _kbdWaitKey
*fill* 0x00000000c0107282 0x2 00
.text 0x00000000c0107284 0x665 kio.o
0x00000000c0107834 _kio_drawConsoleChar
0x00000000c01073ee _putc
0x00000000c010763a _kio_console_cls
0x00000000c010752a _putHex
0x00000000c01078c2 _kio_writeCursorPosition
0x00000000c01075d6 _kio_console_scroll
0x00000000c0107694 _kio_drawConsole
0x00000000c01078b8 _kio_getCursorPosition
0x00000000c0107284 _kio_init
0x00000000c01072ae _printf
0x00000000c010759e _kio_putBCD
*fill* 0x00000000c01078e9 0x3 00
.text 0x00000000c01078ec 0x350 mm.o
0x00000000c01078ec __Z7mm_initv
0x00000000c0107ace __Z8mm_pfreej
0x00000000c0107a90 __Z9mm_pfreenjj
0x00000000c0107c28 __Z14mm_getTotalMemv
0x00000000c0107b18 __Z9mm_pallocv
0x00000000c0107bc0 __Z10mm_freememv
0x00000000c0107c32 __Z15mm_getTotalMegsv
.text 0x00000000c0107c3c 0x201 mouse.o
0x00000000c0107c3c _mouse_init
0x00000000c0107ce6 _isr_mouse
*fill* 0x00000000c0107e3d 0x3 00
.text 0x00000000c0107e40 0x8f stdfont.o
0x00000000c0107ea0 __Z17stdfont_getBitmapj
0x00000000c0107e40 __Z20stdfont_getFontWidthj
0x00000000c0107e70 __Z21stdfont_getFontHeightj
*fill* 0x00000000c0107ecf 0x1 00
.text 0x00000000c0107ed0 0x669 video.o
0x00000000c01083b0 __Z13video_psetp32ij
0x00000000c01081c4 __Z10video_vertiiij
0x00000000c01083cc __Z15video_psetpnullij
0x00000000c01080a8 __Z11video_horiziiij
0x00000000c01083e2 __Z15video_getHeightv
0x00000000c0108402 __Z20video_getPhysBasePtrv
0x00000000c0107ed0 __Z10video_initv
0x00000000c010827c __Z10video_rectiiiij
0x00000000c0108416 __Z10video_lineiiiij
0x00000000c01083d2 __Z14video_getWidthv
0x00000000c01083f2 __Z21video_getBitsPerPixelv
0x00000000c01081a8 __Z11video_psetiij
0x00000000c010831c __Z13video_psetp16ij
0x00000000c01082d4 __Z11video_rectfiiiij
0x00000000c0108150 __Z10video_psetiij
0x00000000c0108362 __Z13video_psetp24ij
0x00000000c0107fc2 __Z16video_renderChariiiijij
0x00000000c010840c __Z10video_Modev
*fill* 0x00000000c0108539 0x3 00
.text 0x00000000c010853c 0x8b8 vmm.o
0x00000000c0108ae2 __Z21vmm_addHeapEntryBlockv
0x00000000c0108ba4 __Z20vmm_getLastHeapEntryv
0x00000000c0108904 __Z21vmm_coalesceHeapEntryP9HeapEntry
0x00000000c0108d12 __Z7reallocPvj
0x00000000c0108cd6 __Z22vmm_getHeapEntryByBasej
0x00000000c0108856 __Z16vmm_getFreeChunkj
0x00000000c0108c8c __Z4freePv
0x00000000c01089ce __Z12vmm_moreCorej
0x00000000c01087e2 __Z6mallocj
0x00000000c0108c54 __Z19vmm_heapEntriesLeftv
0x00000000c010853c __Z8vmm_initv
0x00000000c0108da6 __Z6callocjj
0x00000000c0108bd4 __Z25vmm_getFirstHoleHeapEntryj
0x00000000c01085e4 __Z12vmm_heb_initP14HeapEntryBlock
0x00000000c0108ac6 __Z17vmm_nextHeapEntryv
0x00000000c0108660 __Z8vmm_map1jj
0x00000000c0108738 __Z8vmm_mapnjjj
0x00000000c01087b4 __Z10vmm_unmapnjj
0x00000000c0108772 __Z10vmm_unmap1j
0x00000000c0108c1a __Z27vmm_getFirstUnusedHeapEntryv
.text 0x00000000c0108df4 0x269 rtc.o
0x00000000c0108e1e __Z13rtc_readMonthv
0x00000000c0108ff4 __Z11rtc_setHourh
0x00000000c0108df4 __Z11rtc_readDayv
0x00000000c0108f24 __Z12rtc_setMonthh
0x00000000c0108fc0 __Z13rtc_setMinuteh
0x00000000c0108ef0 __Z10rtc_setDayh
0x00000000c0108ec6 __Z12rtc_readHourv
0x00000000c0108e48 __Z12rtc_readYearv
0x00000000c0108e72 __Z14rtc_readSecondv
0x00000000c0108f58 __Z11rtc_setYearh
0x00000000c0108e9c __Z14rtc_readMinutev
0x00000000c0108f8c __Z13rtc_setSecondh
*fill* 0x00000000c010905d 0x3 00
.text 0x00000000c0109060 0x121 pic.o
0x00000000c0109060 __Z9pic_remapii
*fill* 0x00000000c0109181 0x3 00
.text 0x00000000c0109184 0x15d cstring.o
0x00000000c01091ac __Z12string_splitPcc
0x00000000c0109184 __Z6strcatPcPKc
0x00000000c010920a __Z14string_advancePc
0x00000000c0109266 __Z5ucasePc
0x00000000c0109224 __Z5rtrimPc
0x00000000c01092a4 __Z5lcasePc
*fill* 0x00000000c01092e1 0x3 00
.text 0x00000000c01092e4 0xed9 string.o
0x00000000c01099f2 __ZN6stringC1ERKS_S1_
0x00000000c01097c6 __ZN6stringmIEPKc
0x00000000c0109474 __ZN6stringC1EPKc
0x00000000c0109d6c __ZN6stringC2EcRKS_
0x00000000c0109aec __ZN6stringC1ERKS_PKc
0x00000000c0109384 __ZN6stringC2ERKS_
0x00000000c01094c8 __ZN6stringaSERKS_
0x00000000c0109420 __ZN6stringC2EPKc
0x00000000c010a132 __ZNK6stringleEPKc
0x00000000c010a0ee __ZNK6stringleERKS_
0x00000000c01092e4 __ZN6stringC2Ev
0x00000000c0109668 __ZN6stringpLEPKc
0x00000000c010997c __ZN6stringC2ERKS_S1_
0x00000000c0109e5a __ZN6stringixEj
0x00000000c0109c84 __ZN6stringC2ERKS_c
0x00000000c01095b0 __ZNK6string4dataEv
0x00000000c0109cf8 __ZN6stringC1ERKS_c
0x00000000c0109dcc __ZN6stringC1EcRKS_
0x00000000c010a096 __ZNK6stringgtEPKc
0x00000000c0109e2c __ZNK6stringixEj
0x00000000c0109364 __ZN6stringD1Ev
0x00000000c0109ff2 __ZNK6stringgtERKS_
0x00000000c0109b70 __ZN6stringC2EPKcRKS_
0x00000000c0109724 __ZN6stringmIERKS_
0x00000000c0109ef0 __ZNK6stringeqEPKc
0x00000000c0109344 __ZN6stringD2Ev
0x00000000c0109f62 __ZNK6stringneERKS_
0x00000000c01095ba __ZNK6string4sizeEv
0x00000000c010a178 __ZNK6stringgeEPKc
0x00000000c0109a68 __ZN6stringC2ERKS_PKc
0x00000000c010a110 __ZNK6stringgeERKS_
0x00000000c010990c __ZN6stringmIEc
0x00000000c01093d2 __ZN6stringC1ERKS_
0x00000000c0109fa6 __ZNK6stringltERKS_
0x00000000c0109f84 __ZNK6stringneEPKc
0x00000000c0109bfa __ZN6stringC1EPKcRKS_
0x00000000c0109e88 __ZNK6stringeqERKS_
0x00000000c010a03e __ZNK6stringltEPKc
0x00000000c0109888 __ZN6stringpLEc
0x00000000c01095c6 __ZN6stringpLERKS_
0x00000000c0109538 __ZN6stringaSEPKc
0x00000000c0109314 __ZN6stringC1Ev
*fill* 0x00000000c010a1bd 0x3 00
.text 0x00000000c010a1c0 0xe5 cmos.o
0x00000000c010a218 __Z11cmos_gethd0v
0x00000000c010a1c0 __Z11cmos_getfd0v
0x00000000c010a1ec __Z11cmos_getfd1v
0x00000000c010a244 __Z11cmos_gethd1v
*fill* 0x00000000c010a2a5 0x3 00
.text 0x00000000c010a2a8 0x58 hos_defines.o
0x00000000c010a2d4 __ZdlPv
0x00000000c010a2be __Znaj
0x00000000c010a2a8 __Znwj
0x00000000c010a2ea __ZdaPv
.text 0x00000000c010a300 0x24d vfs.o
0x00000000c010a32e __Z4listv
0x00000000c010a3d0 __Z9vfs_mount6stringS_
0x00000000c010a300 __Z8vfs_initv
*fill* 0x00000000c010a54d 0x3 00
.text 0x00000000c010a550 0x2b7 devfs.o
0x00000000c010a550 __Z10devfs_init6string
*fill* 0x00000000c010a807 0x1 00
.text 0x00000000c010a808 0x145 Mount.o
0x00000000c010a858 __ZN5MountC2E6stringS0_
0x00000000c010a8ac __ZN5MountC1E6stringS0_
0x00000000c010a900 __ZNK5MounteqERKS_
0x00000000c010a830 __ZN5MountC1Ev
0x00000000c010a808 __ZN5MountC2Ev
0x00000000c010b000 . = ALIGN (0x1000)
*fill* 0x00000000c010a94d 0x80b2310000006b3 00
.gnu.linkonce.t._ZN10LinkedListI5MountEC1Ev
0x00000000c010b000 0x43
.gnu.linkonce.t._ZN10LinkedListI5MountEC1Ev
0x00000000c010b000 0x43 vfs.o
0x00000000c010b000 __ZN10LinkedListI5MountEC1Ev
.gnu.linkonce.t._ZN10LinkedListI5MountE5beginEv
0x00000000c010b044 0x27
.gnu.linkonce.t._ZN10LinkedListI5MountE5beginEv
0x00000000c010b044 0x27 vfs.o
0x00000000c010b044 __ZN10LinkedListI5MountE5beginEv
.gnu.linkonce.t._ZN10LinkedListI5MountE3endEv
0x00000000c010b06c 0x28
.gnu.linkonce.t._ZN10LinkedListI5MountE3endEv
0x00000000c010b06c 0x28 vfs.o
0x00000000c010b06c __ZN10LinkedListI5MountE3endEv
.gnu.linkonce.t._ZNK10LinkedListI5MountE8iteratorneERKS2_
0x00000000c010b094 0x17
.gnu.linkonce.t._ZNK10LinkedListI5MountE8iteratorneERKS2_
0x00000000c010b094 0x17 vfs.o
0x00000000c010b094 __ZNK10LinkedListI5MountE8iteratorneERKS2_
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratordeEv
0x00000000c010b0ac 0xa
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratordeEv
0x00000000c010b0ac 0xa vfs.o
0x00000000c010b0ac __ZN10LinkedListI5MountE8iteratordeEv
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratorppEv
0x00000000c010b0b6 0x12
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratorppEv
0x00000000c010b0b6 0x12 vfs.o
0x00000000c010b0b6 __ZN10LinkedListI5MountE8iteratorppEv
.gnu.linkonce.t._ZN10LinkedListI5MountE6insertEiS0_
0x00000000c010b0c8 0x101
.gnu.linkonce.t._ZN10LinkedListI5MountE6insertEiS0_
0x00000000c010b0c8 0x101 vfs.o
0x00000000c010b0c8 __ZN10LinkedListI5MountE6insertEiS0_
.gnu.linkonce.t._ZN10LinkedListI5MountE10LinkedNodeC1Ev
0x00000000c010b1ca 0x2a
.gnu.linkonce.t._ZN10LinkedListI5MountE10LinkedNodeC1Ev
0x00000000c010b1ca 0x2a vfs.o
0x00000000c010b1ca __ZN10LinkedListI5MountE10LinkedNodeC1Ev
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratorC1EPNS1_10LinkedNodeE
0x00000000c010b1f4 0xd
.gnu.linkonce.t._ZN10LinkedListI5MountE8iteratorC1EPNS1_10LinkedNodeE
0x00000000c010b1f4 0xd vfs.o
0x00000000c010b1f4 __ZN10LinkedListI5MountE8iteratorC1EPNS1_10LinkedNodeE
.gnu.linkonce.t._ZN10LinkedListI5MountE9push_backES0_
0x00000000c010b202 0x82
.gnu.linkonce.t._ZN10LinkedListI5MountE9push_backES0_
0x00000000c010b202 0x82 vfs.o
0x00000000c010b202 __ZN10LinkedListI5MountE9push_backES0_
.gnu.linkonce.t._ZN10LinkedListI5MountE10LinkedNodeC1ES0_
0x00000000c010b284 0x40
.gnu.linkonce.t._ZN10LinkedListI5MountE10LinkedNodeC1ES0_
0x00000000c010b284 0x40 vfs.o
0x00000000c010b284 __ZN10LinkedListI5MountE10LinkedNodeC1ES0_
.gnu.linkonce.t._ZN5MountaSERKS_
0x00000000c010b2c4 0x4d
.gnu.linkonce.t._ZN5MountaSERKS_
0x00000000c010b2c4 0x4d vfs.o
0x00000000c010b2c4 __ZN5MountaSERKS_
.gnu.linkonce.t._ZN5MountC1ERKS_
0x00000000c010b312 0x4a
.gnu.linkonce.t._ZN5MountC1ERKS_
0x00000000c010b312 0x4a vfs.o
0x00000000c010b312 __ZN5MountC1ERKS_
.gnu.linkonce.t._ZN5MountD1Ev
0x00000000c010b35c 0x28
.gnu.linkonce.t._ZN5MountD1Ev
0x00000000c010b35c 0x28 vfs.o
0x00000000c010b35c __ZN5MountD1Ev
.data 0x00000000c010b388 0xc78
0x00000000c010b388 data = .
0x00000000c010b388 _data = .
0x00000000c010b388 __data = .
*(.data)
.data 0x00000000c010b388 0x18 stdfont.o
0x00000000c010b388 _fonts
.data 0x00000000c010b3a0 0x10 video.o
0x00000000c010b3a0 _vid_ptr16
0x00000000c010b3ac _video_psetp
0x00000000c010b3a8 _vid_ptr32
0x00000000c010b3a4 _vid_ptr24
.data 0x00000000c010b3b0 0x4 vmm.o
0x00000000c010b3b0 _firstHeapEntry
0x00000000c010c000 . = ALIGN (0x1000)
*fill* 0x00000000c010b3b4 0x8116e3800000c4c 00
.rodata 0x00000000c010c000 0x2000
0x00000000c010c000 rodata = .
0x00000000c010c000 _rodata = .
0x00000000c010c000 __rodata = .
*(.rodata)
.rodata 0x00000000c010c000 0x141 kernel.o
*fill* 0x00000000c010c141 0x1f 00
.rodata 0x00000000c010c160 0x141 keyboard.o
*fill* 0x00000000c010c2a1 0x3 00
.rodata 0x00000000c010c2a4 0x1e4 kio.o
*fill* 0x00000000c010c488 0x18 00
.rodata 0x00000000c010c4a0 0x1200 stdfont.o
.rodata 0x00000000c010d6a0 0x7 vfs.o
.rodata 0x00000000c010d6a7 0x6d devfs.o
0x00000000c010e000 . = ALIGN (0x1000)
*fill* 0x00000000c010d714 0x8116e9c000008ec 00
.bss 0x00000000c010e000 0x22000
0x00000000c010e000 bss = .
0x00000000c010e000 _bss = .
0x00000000c010e000 __bss = .
*(.bss)
.bss 0x00000000c010e000 0x4 kernel.o
0x00000000c010e000 _timer
*fill* 0x00000000c010e004 0x4 00
*fill* 0x00000000c010e008 0x18 00
.bss 0x00000000c010e020 0x12b keyboard.o
0x00000000c010e040 _kbdBuffer
0x00000000c010e148 _kbdExt
0x00000000c010e021 _kbdAscii
0x00000000c010e149 _kbdExt2
0x00000000c010e14a _ackReason
0x00000000c010e140 _kbdBufferStart
0x00000000c010e022 _kbdScan
0x00000000c010e144 _kbdBufferLen
0x00000000c010e020 _kbdFlags
*fill* 0x00000000c010e14b 0x15 00
.bss 0x00000000c010e160 0xfc0 kio.o
0x00000000c010e180 _console_memory
0x00000000c010e160 _graphical
0x00000000c010e164 _cursorPosition
.bss 0x00000000c010f120 0x20020 mm.o
0x00000000c010f124 _mm_megabytes
0x00000000c010f140 _page_bitmap
0x00000000c010f120 _mm_totalmem
.bss 0x00000000c012f140 0x1c mouse.o
0x00000000c012f144 _mouse_y
0x00000000c012f148 _mouse_bytesRead
0x00000000c012f140 _mouse_x
0x00000000c012f14c _mouse_inbuffer
*fill* 0x00000000c012f15c 0x4 00
.bss 0x00000000c012f160 0x104 video.o
0x00000000c012f160 _video_mode
0x00000000c012f260 _videoMode
.bss 0x00000000c012f264 0x4 vfs.o
0x00000000c012f264 _mounts
0x00000000c0130000 . = ALIGN (0x1000)
*fill* 0x00000000c012f268 0x8116ff000000d98 00
0x00000000c0130000 end = .
0x00000000c0130000 _end = .
0x00000000c0130000 __end = .
LOAD ks.o
LOAD kernel.o
LOAD asmfuncs.o
LOAD fdc.o
LOAD keyboard.o
LOAD kio.o
LOAD mm.o
LOAD mouse.o
LOAD stdfont.o
LOAD video.o
LOAD vmm.o
LOAD rtc.o
LOAD pic.o
LOAD io.o
LOAD cstring.o
LOAD string.o
LOAD cmos.o
LOAD hos_defines.o
LOAD vfs.o
LOAD devfs.o
LOAD Mount.o
OUTPUT(kernel.bin binary)
.note.GNU-stack
0x0000000000000000 0x0
.comment 0x0000000000000000 0x3c9
.comment 0x0000000000000000 0x33 kernel.o
.comment 0x0000000000000033 0x33 fdc.o
.comment 0x0000000000000066 0x33 keyboard.o
.comment 0x0000000000000099 0x33 kio.o
.comment 0x00000000000000cc 0x33 mm.o
.comment 0x00000000000000ff 0x33 mouse.o
.comment 0x0000000000000132 0x33 stdfont.o
.comment 0x0000000000000165 0x33 video.o
.comment 0x0000000000000198 0x33 vmm.o
.comment 0x00000000000001cb 0x33 rtc.o
.comment 0x00000000000001fe 0x33 pic.o
.comment 0x0000000000000231 0x33 io.o
.comment 0x0000000000000264 0x33 cstring.o
.comment 0x0000000000000297 0x33 string.o
.comment 0x00000000000002ca 0x33 cmos.o
.comment 0x00000000000002fd 0x33 hos_defines.o
.comment 0x0000000000000330 0x33 vfs.o
.comment 0x0000000000000363 0x33 devfs.o
.comment 0x0000000000000396 0x33 Mount.o

510
kernel/lst/asmfuncs.lst Normal file
View File

@ -0,0 +1,510 @@
1 ; asmfuncs.asm
2 ; Josh Holtrop
3 ; Created: 10/23/03
4 ; Modified: 02/26/04
5
6 [extern _putc]
7 [extern _console_memory]
8 [extern _cursorPosition]
9 [extern _video_drawConsole]
10 [extern _videoMode]
11
12 %macro jzfar 1
13 jnz %%skip
14 jmp %1
15 %%skip:
16
17 %endmacro
18
19 ;stores the parameter to the CR0 register
20 ;extern dword write_cr0(dword cr0);
21 [global _write_cr0]
22 _write_cr0:
23 00000000 55 push ebp
24 00000001 89E5 mov ebp, esp
25 00000003 8B4508 mov eax, [ebp+8]
26 00000006 0F22C0 mov cr0, eax
27 00000009 5D pop ebp
28 0000000A C3 ret
29
30 ;returns the value in the CR0 register
31 ;extern dword read_cr0();
32 [global _read_cr0]
33 _read_cr0:
34 0000000B 0F20C0 mov eax, cr0;
35 0000000E C3 ret
36
37 ;stores the parameter to the CR3 register
38 ;extern dword write_cr3(dword cr3);
39 [global _write_cr3]
40 _write_cr3:
41 0000000F 55 push ebp
42 00000010 89E5 mov ebp, esp
43 00000012 8B4508 mov eax, [ebp+8]
44 00000015 0F22D8 mov cr3, eax
45 00000018 5D pop ebp
46 00000019 C3 ret
47
48
49 ;returns the value in the CR2 register
50 ;extern dword read_cr2();
51 [global _read_cr2]
52 _read_cr2:
53 0000001A 0F20D0 mov eax, cr2;
54 0000001D C3 ret
55
56
57
58 ;returns the value in the CR3 register
59 ;extern dword read_cr3();
60 [global _read_cr3]
61 _read_cr3:
62 0000001E 0F20D8 mov eax, cr3;
63 00000021 C3 ret
64
65
66 ;compares one string to another
67 ;returns 0 if the strings are different
68 ;extern dword strcmp(char *str1, char *str2);
69 [global _strcmp]
70 _strcmp:
71 00000022 55 push ebp
72 00000023 89E5 mov ebp, esp
73 00000025 56 push esi
74 00000026 57 push edi
75
76 00000027 8B7508 mov esi, [ebp+8]
77 0000002A 8B7D0C mov edi, [ebp+12]
78 strcmp_loop1:
79 0000002D AC lodsb
80 0000002E 8A27 mov ah, [edi]
81 00000030 47 inc edi
82 00000031 38C4 cmp ah, al
83 00000033 750D jnz strcmp_ne
84 00000035 08C0 or al, al
85 00000037 7402 jz strcmp_e
86 00000039 EBF2 jmp strcmp_loop1
87 strcmp_e:
88 0000003B B801000000 mov eax, 1
89 00000040 EB02 jmp short strcmp_done
90 strcmp_ne:
91 00000042 31C0 xor eax, eax
92 strcmp_done:
93
94 00000044 5F pop edi
95 00000045 5E pop esi
96 00000046 5D pop ebp
97 00000047 C3 ret
98
99 ;copies a string from the source to the destination parameter
100 ;extern void strcpy(char *dest, char *src);
101 [global _strcpy]
102 _strcpy:
103 00000048 55 push ebp
104 00000049 89E5 mov ebp, esp
105 0000004B 56 push esi
106 0000004C 57 push edi
107 0000004D 8B7D08 mov edi, [ebp+8]
108 00000050 8B750C mov esi, [ebp+12]
109 strcpyloop:
110 00000053 AC lodsb
111 00000054 AA stosb
112 00000055 08C0 or al, al
113 00000057 75FA jnz strcpyloop
114 00000059 5F pop edi
115 0000005A 5E pop esi
116 0000005B 5D pop ebp
117 0000005C C3 ret
118
119 ;copies memory of n bytes from src to destination
120 ;void memcpy(void *dest, void *src, dword n);
121 [global _memcpy]
122 _memcpy:
123 0000005D 55 push ebp
124 0000005E 89E5 mov ebp, esp
125 00000060 56 push esi
126 00000061 57 push edi
127 00000062 51 push ecx
128 00000063 8B7D08 mov edi, [ebp+8]
129 00000066 8B750C mov esi, [ebp+12]
130 00000069 8B4D10 mov ecx, [ebp+16]
131
132 0000006C FC cld
133 0000006D F3A4 rep movsb
134
135 0000006F 59 pop ecx
136 00000070 5F pop edi
137 00000071 5E pop esi
138 00000072 5D pop ebp
139 00000073 C3 ret
140
141
142 ;copies memory of n dwords (n*4 bytes) from src to destination
143 ;void memcpyd(void *dest, void *src, dword n);
144 [global _memcpyd]
145 _memcpyd:
146 00000074 55 push ebp
147 00000075 89E5 mov ebp, esp
148 00000077 56 push esi
149 00000078 57 push edi
150 00000079 51 push ecx
151 0000007A 8B7D08 mov edi, [ebp+8]
152 0000007D 8B750C mov esi, [ebp+12]
153 00000080 8B4D10 mov ecx, [ebp+16]
154
155 00000083 FC cld
156 00000084 F3A5 rep movsd
157
158 00000086 59 pop ecx
159 00000087 5F pop edi
160 00000088 5E pop esi
161 00000089 5D pop ebp
162 0000008A C3 ret
163
164
165 ;sets num bytes at buffer to the value of c
166 ;void *memset(void *buffer, int c, int num);
167 [global _memset]
168 _memset:
169 0000008B 55 push ebp
170 0000008C 89E5 mov ebp, esp
171 0000008E 57 push edi
172 0000008F 51 push ecx
173 00000090 8B7D08 mov edi, [ebp+8]
174 00000093 57 push edi ;save for return address
175 00000094 8B450C mov eax, [ebp+12]
176 00000097 8B4D10 mov ecx, [ebp+16]
177
178 0000009A F3AA rep stosb
179
180 0000009C 58 pop eax
181 0000009D 59 pop ecx
182 0000009E 5F pop edi
183 0000009F 5D pop ebp
184 000000A0 C3 ret
185
186
187 ;sets num words at buffer to the value of c
188 ;void *memsetw(void *buffer, int c, int num);
189 [global _memsetw]
190 _memsetw:
191 000000A1 55 push ebp
192 000000A2 89E5 mov ebp, esp
193 000000A4 57 push edi
194 000000A5 51 push ecx
195 000000A6 8B7D08 mov edi, [ebp+8]
196 000000A9 57 push edi ;save for return address
197 000000AA 8B450C mov eax, [ebp+12]
198 000000AD 8B4D10 mov ecx, [ebp+16]
199
200 000000B0 F366AB rep stosw
201
202 000000B3 58 pop eax
203 000000B4 59 pop ecx
204 000000B5 5F pop edi
205 000000B6 5D pop ebp
206 000000B7 C3 ret
207
208
209 ;sets num dwords at buffer to the value of c
210 ;void *memsetd(void *buffer, int c, int num);
211 [global _memsetd]
212 _memsetd:
213 000000B8 55 push ebp
214 000000B9 89E5 mov ebp, esp
215 000000BB 57 push edi
216 000000BC 51 push ecx
217 000000BD 8B7D08 mov edi, [ebp+8]
218 000000C0 57 push edi ;save for return address
219 000000C1 8B450C mov eax, [ebp+12]
220 000000C4 8B4D10 mov ecx, [ebp+16]
221
222 000000C7 F3AB rep stosd
223
224 000000C9 58 pop eax
225 000000CA 59 pop ecx
226 000000CB 5F pop edi
227 000000CC 5D pop ebp
228 000000CD C3 ret
229
230
231 ;returns the number of characters in a string
232 ;extern dword strlen(char *str);
233 [global _strlen]
234 _strlen:
235 000000CE 55 push ebp
236 000000CF 89E5 mov ebp, esp
237 000000D1 56 push esi
238 000000D2 53 push ebx
239 000000D3 8B7508 mov esi, [ebp+8]
240 000000D6 31DB xor ebx, ebx
241 strlenloop:
242 000000D8 AC lodsb
243 000000D9 08C0 or al, al
244 000000DB 7403 jz strlendone
245 000000DD 43 inc ebx
246 000000DE EBF8 jmp strlenloop
247 strlendone:
248 000000E0 89D8 mov eax, ebx
249 000000E2 5B pop ebx
250 000000E3 5E pop esi
251 000000E4 5D pop ebp
252 000000E5 C3 ret
253
254 ;this function invalidates the page directory/table entry that
255 ; would be used to access the memory address given in the parameter
256 ;extern void invlpg_(dword addr);
257 [global _invlpg_]
258 _invlpg_:
259 000000E6 8B442404 mov eax, [esp+4]
260 000000EA 0F0138 invlpg [eax]
261 000000ED C3 ret
262
263
264 ;
265 ;void writeCursorPosition(word pos)
266 ;
267 [global _writeCursorPosition]
268 _writeCursorPosition:
269 000000EE 55 push ebp
270 000000EF 89E5 mov ebp, esp
271
272 000000F1 50 push eax
273 000000F2 53 push ebx
274 000000F3 52 push edx
275
276 000000F4 8B4508 mov eax, [ebp+8] ;cursor position in ax
277
278 000000F7 88C3 mov bl, al
279 000000F9 66BAD403 mov dx, 0x03D4
280 000000FD B00E mov al, 0x0E
281 000000FF EE out dx, al
282
283 00000100 6642 inc dx
284 00000102 88E0 mov al, ah
285 00000104 EE out dx, al
286
287 00000105 664A dec dx
288 00000107 B00F mov al, 0x0F
289 00000109 EE out dx, al
290
291 0000010A 6642 inc dx
292 0000010C 88D8 mov al, bl
293 0000010E EE out dx, al
294
295 0000010F 5A pop edx
296 00000110 5B pop ebx
297 00000111 58 pop eax
298 00000112 5D pop ebp
299
300 00000113 C3 ret
301
302
303 ;
304 ;word getCursorPosition()
305 ;
306 [global _getCursorPosition]
307 _getCursorPosition:
308 00000114 53 push ebx
309 00000115 52 push edx
310
311 00000116 31C0 xor eax, eax
312 00000118 66BAD403 mov dx, 0x03D4
313 0000011C B00E mov al, 0x0E
314 0000011E EE out dx, al
315
316 0000011F 6642 inc dx
317 00000121 EC in al, dx
318 00000122 88C3 mov bl, al
319
320 00000124 664A dec dx
321 00000126 B00F mov al, 0x0F
322 00000128 EE out dx, al
323
324 00000129 6642 inc dx
325 0000012B EC in al, dx
326 0000012C 88DC mov ah, bl
327
328 0000012E 5A pop edx
329 0000012F 5B pop ebx
330
331 00000130 C3 ret
332
333
334 ;
335 ;int puts(char *str)
336 ;
337 [global _puts]
338 _puts:
339 00000131 55 push ebp
340 00000132 89E5 mov ebp, esp
341 00000134 56 push esi
342 00000135 50 push eax
343 00000136 8B7508 mov esi, [ebp+8] ;esi = to string
344 puts_loop:
345 00000139 AC lodsb
346 0000013A 3C00 cmp al, 0
347 0000013C 740E jz puts_done
348 0000013E 50 push eax
349 0000013F E8(00000000) call _putc
350 00000144 81C404000000 add esp, 4
351 0000014A EBED jmp puts_loop
352
353 puts_done:
354 0000014C 58 pop eax
355 0000014D 5E pop esi
356 0000014E 5D pop ebp
357 0000014F C3 ret
358
359
360
361
362 [global _putDecu]
363 _putDecu:
364 00000150 55 push ebp
365 00000151 89E5 mov ebp, esp
366 00000153 81EC18000000 sub esp, 24
367 00000159 C745FC01000000 mov DWORD [ebp-4], 1
368 00000160 C645FB00 mov BYTE [ebp-5], 0
369 L2:
370 00000164 8B5508 mov edx, DWORD [ebp+8]
371 00000167 B8CDCCCCCC mov eax, -858993459
372 0000016C F7E2 mul edx
373 0000016E 89D0 mov eax, edx
374 00000170 C1E803 shr eax, 3
375 00000173 3B45FC cmp eax, DWORD [ebp-4]
376 00000176 7305 jae L4
377 00000178 E912000000 jmp L3
378 L4:
379 0000017D 8B45FC mov eax, DWORD [ebp-4]
380 00000180 89C2 mov edx, eax
381 00000182 C1E202 sal edx, 2
382 00000185 01C2 add edx, eax
383 00000187 8D0412 lea eax, [edx+edx]
384 0000018A 8945FC mov DWORD [ebp-4], eax
385 0000018D EBD5 jmp L2
386 L3:
387 0000018F 90 nop
388 L5:
389 00000190 817DFC01000000 cmp DWORD [ebp-4], 1
390 00000197 7705 ja L7
391 00000199 E959000000 jmp L6
392 L7:
393 0000019E 8B5508 mov edx, DWORD [ebp+8]
394 000001A1 89D0 mov eax, edx
395 000001A3 BA00000000 mov edx, 0
396 000001A8 F775FC div DWORD [ebp-4]
397 000001AB 8945F4 mov DWORD [ebp-12], eax
398 000001AE 8A45F4 mov al, BYTE [ebp-12]
399 000001B1 8845FB mov BYTE [ebp-5], al
400 000001B4 B800000000 mov eax, 0
401 000001B9 8A45FB mov al, BYTE [ebp-5]
402 000001BC 0FAF45FC imul eax, DWORD [ebp-4]
403 000001C0 294508 sub DWORD [ebp+8], eax
404 000001C3 8B55FC mov edx, DWORD [ebp-4]
405 000001C6 B8CDCCCCCC mov eax, -858993459
406 000001CB F7E2 mul edx
407 000001CD 89D0 mov eax, edx
408 000001CF C1E803 shr eax, 3
409 000001D2 8945FC mov DWORD [ebp-4], eax
410 000001D5 8D45FB lea eax, [ebp-5]
411 000001D8 800030 add BYTE [eax], 48
412 000001DB 81EC0C000000 sub esp, 12
413 000001E1 B800000000 mov eax, 0
414 000001E6 8A45FB mov al, BYTE [ebp-5]
415 000001E9 50 push eax
416 000001EA E8(00000000) call _putc
417 000001EF 81C410000000 add esp, 16
418 000001F5 EB99 jmp L5
419 L6:
420 000001F7 81EC0C000000 sub esp, 12
421 000001FD 8A4508 mov al, BYTE [ebp+8]
422 00000200 0530000000 add eax, 48
423 00000205 25FF000000 and eax, 255
424 0000020A 50 push eax
425 0000020B E8(00000000) call _putc
426 00000210 81C410000000 add esp, 16
427 00000216 C9 leave
428 00000217 C3 ret
429
430
431
432
433 [global _putDec]
434 _putDec:
435 00000218 55 push ebp
436 00000219 89E5 mov ebp, esp
437 0000021B 81EC18000000 sub esp, 24
438 00000221 817D0800000000 cmp DWORD [ebp+8], 0
439 00000228 7919 jns L9
440 0000022A 81EC0C000000 sub esp, 12
441 00000230 682D000000 push 45
442 00000235 E8(00000000) call _putc
443 0000023A 81C410000000 add esp, 16
444 00000240 F75D08 neg DWORD [ebp+8]
445 L9:
446 00000243 C745FC01000000 mov DWORD [ebp-4], 1
447 0000024A C645FB00 mov BYTE [ebp-5], 0
448 L10:
449 0000024E 8B4508 mov eax, DWORD [ebp+8]
450 00000251 3B45FC cmp eax, DWORD [ebp-4]
451 00000254 7305 jae L12
452 00000256 E912000000 jmp L11
453 L12:
454 0000025B 8B45FC mov eax, DWORD [ebp-4]
455 0000025E 89C2 mov edx, eax
456 00000260 C1E202 sal edx, 2
457 00000263 01C2 add edx, eax
458 00000265 8D0412 lea eax, [edx+edx]
459 00000268 8945FC mov DWORD [ebp-4], eax
460 0000026B EBE1 jmp L10
461 L11:
462 0000026D 8B55FC mov edx, DWORD [ebp-4]
463 00000270 B8CDCCCCCC mov eax, -858993459
464 00000275 F7E2 mul edx
465 00000277 89D0 mov eax, edx
466 00000279 C1E803 shr eax, 3
467 0000027C 8945FC mov DWORD [ebp-4], eax
468 L13:
469 0000027F 817DFC01000000 cmp DWORD [ebp-4], 1
470 00000286 7705 ja L15
471 00000288 E959000000 jmp L14
472 L15:
473 0000028D 8B5508 mov edx, DWORD [ebp+8]
474 00000290 89D0 mov eax, edx
475 00000292 BA00000000 mov edx, 0
476 00000297 F775FC div DWORD [ebp-4]
477 0000029A 8945F4 mov DWORD [ebp-12], eax
478 0000029D 8A45F4 mov al, BYTE [ebp-12]
479 000002A0 8845FB mov BYTE [ebp-5], al
480 000002A3 B800000000 mov eax, 0
481 000002A8 8A45FB mov al, BYTE [ebp-5]
482 000002AB 0FAF45FC imul eax, DWORD [ebp-4]
483 000002AF 294508 sub DWORD [ebp+8], eax
484 000002B2 8B55FC mov edx, DWORD [ebp-4]
485 000002B5 B8CDCCCCCC mov eax, -858993459
486 000002BA F7E2 mul edx
487 000002BC 89D0 mov eax, edx
488 000002BE C1E803 shr eax, 3
489 000002C1 8945FC mov DWORD [ebp-4], eax
490 000002C4 8D45FB lea eax, [ebp-5]
491 000002C7 800030 add BYTE [eax], 48
492 000002CA 81EC0C000000 sub esp, 12
493 000002D0 B800000000 mov eax, 0
494 000002D5 8A45FB mov al, BYTE [ebp-5]
495 000002D8 50 push eax
496 000002D9 E8(00000000) call _putc
497 000002DE 81C410000000 add esp, 16
498 000002E4 EB99 jmp L13
499 L14:
500 000002E6 81EC0C000000 sub esp, 12
501 000002EC 8A4508 mov al, BYTE [ebp+8]
502 000002EF 0530000000 add eax, 48
503 000002F4 25FF000000 and eax, 255
504 000002F9 50 push eax
505 000002FA E8(00000000) call _putc
506 000002FF 81C410000000 add esp, 16
507 00000305 C9 leave
508 00000306 C3 ret
509
510

492
kernel/lst/kernel.lst Normal file
View File

@ -0,0 +1,492 @@
1 ;kernel.asm
2 ;Author: Josh Holtrop
3 ;Date: 10/30/03
4 ;Modified: 10/30/03
5
6 %define GDT_P 0x100000; ;1mb physical - Global Descriptor Table space
7 %define GDT_V GDT_P+0xC0000000
8 %define IDT_P 0x102000 ;1mb+8kb - Interrupt Descriptor Table space
9 %define IDT_V IDT_P+0xC0000000
10 %define PDBR_P 0x104000 ;1mb+16kb - Page Directory Base Register (first PD)
11 %define PDBR_V PDBR_P+0xC0000000
12 %define LOPT_P 0x105000 ;1mb+20kb - LOw Page Table for mapping first 4mb
13 %define LOPT_V LOPT_P+0xC0000000
14 %define KERNEL_P 0x106000 ;1mb+24kb - the kernel's physical address
15 %define KERNEL_V KERNEL_P+0xC0000000 ;3gb+1mb+24kb, the virtual address of the kernel
16
17 [global _start]
18 [extern _isr]
19 [extern _k_init]
20 [extern _putc]
21
22 bits 32
23
24 ;This is where the kernel begins execution
25 ;At this point, the temporary gdt is set up to "map" 0xC000_0000 to 0x0.
26 ;We must enable paging with the first 4mb mapped 1:1 virtual:physical
27 ; and with the 4mb starting at 0xC000_0000 mapped to the first 4mb physical.
28 ;Then we can start using our "real" gdt, then unmap the lower 4mb.
29 _start:
30 00000000 FA cli ;if they weren't already off
31
32 00000001 31C0 xor eax, eax
33 00000003 BF004010C0 mov edi, PDBR_V
34 00000008 B900040000 mov ecx, 1024 ;clear the PDBR
35 0000000D F3AB rep stosd
36 0000000F C705004010C0035010- mov [PDBR_V], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
37 00000018 00
38 00000019 C705004C10C0035010- mov [PDBR_V+0xC00], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
39 00000022 00
40
41 00000023 BF005010C0 mov edi, LOPT_V
42 00000028 B900040000 mov ecx, 1024
43 0000002D B803000000 mov eax, 0x03 ;starting physical address = 0x0 (read/write, present flags)
44 fill_lopt_loop: ;fill the page table
45 00000032 AB stosd
46 00000033 0500100000 add eax, 4096 ;increment next phsyical address by 4kb
47 00000038 E2F8 loop fill_lopt_loop
48
49 0000003A B800401000 mov eax, PDBR_P
50 0000003F 0F22D8 mov cr3, eax ;store the Page Directory Base Address
51 00000042 0F20C0 mov eax, cr0
52 00000045 0D00000080 or eax, 0x80000000 ;set page enable bit
53 0000004A 0F22C0 mov cr0, eax ;now paging is active!
54
55
56 0000004D BF000010C0 mov edi, GDT_V
57 00000052 BE[D4000000] mov esi, gdt
58 00000057 B948000000 mov ecx, gdt_end-gdt
59 copy_gdt:
60 0000005C AC lodsb
61 0000005D AA stosb
62 0000005E E2FC loop copy_gdt
63
64 00000060 BF002010C0 mov edi, IDT_V ;destination
65 00000065 BE[22010000] mov esi, isr_0 ;address of isr0
66 0000006A BA0B000000 mov edx, isr_1-isr_0 ;distance between isr labels
67 0000006F B932000000 mov ecx, 50 ;number of isrlabels
68 fill_idt:
69 00000074 89F3 mov ebx, esi
70 00000076 6689F0 mov ax, si
71 00000079 66AB stosw ;0 offset 15:0
72 0000007B 66B80800 mov ax, KERNEL_CODE
73 0000007F 66AB stosw ;2 selector 15:0
74 00000081 66B8008E mov ax, 0x8E00
75 00000085 66AB stosw ;4 [P][DPL][0][TYPE][0][0][0][0][0][0][0][0]
76 00000087 C1EE10 shr esi, 16
77 0000008A 6689F0 mov ax, si
78 0000008D 66AB stosw ;6 offset 31:16
79 0000008F 89DE mov esi, ebx
80 00000091 01D6 add esi, edx
81 00000093 E2DF loop fill_idt
82 00000095 66C705842110C000EE mov word [IDT_V+0x30*8+4], 0xEE00 ;interrupt 0x30 has user priviledges
83
84 0000009E 0F0115[CE000000] lgdt [gdtr] ;load gdt
85 000000A5 EA[AC000000]0800 jmp KERNEL_CODE:newgdtcontinue
86 newgdtcontinue:
87 000000AC 66B81000 mov ax, KERNEL_DATA
88 000000B0 8EC0 mov es, ax
89 000000B2 8ED8 mov ds, ax
90 000000B4 8EE8 mov gs, ax
91 000000B6 8EE0 mov fs, ax
92 000000B8 8ED0 mov ss, ax
93 000000BA BC000020C0 mov esp, 0xc0200000 ;stack just under 3gb+2mb, moves downward
94 000000BF 0F011D[1C010000] lidt [idtr] ;load idt
95
96 000000C6 E8(00000000) call _k_init
97 haltit:
98 000000CB F4 hlt ;halt processor when k_init is done
99 000000CC EBFD jmp haltit ;shouldn't get here...
100
101 %include "gdt.inc"
102 <1> ;gdt.inc
103 <1> ;Author: Josh Holtrop
104 <1> ;Date: 10/30/03
105 <1> ;Modified: 03/02/04
106 <1>
107 <1> gdtr:
108 000000CE 4700 <1> dw gdt_end-gdt-1
109 000000D0 000010C0 <1> dd GDT_V
110 <1> gdt:
111 000000D4 00000000 <1> dd 0
112 000000D8 00000000 <1> dd 0
113 <1> KERNEL_CODE equ $-gdt
114 000000DC FFFF <1> dw 0xffff ;limit 15:0
115 000000DE 0000 <1> dw 0x0000 ;base 15:0
116 000000E0 00 <1> db 0x00 ;base 23:16
117 000000E1 9A <1> db 0x9A ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
118 000000E2 CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
119 000000E3 00 <1> db 0x00 ;base 31:24
120 <1> KERNEL_DATA equ $-gdt
121 000000E4 FFFF <1> dw 0xffff ;limit 15:0
122 000000E6 0000 <1> dw 0x0000 ;base 15:0
123 000000E8 00 <1> db 0x00 ;base 23:16
124 000000E9 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
125 000000EA CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
126 000000EB 00 <1> db 0x00 ;base 31:24
127 <1> USER_CODE equ $-gdt
128 000000EC FFFF <1> dw 0xffff ;limit 15:0
129 000000EE 0000 <1> dw 0x0000 ;base 15:0
130 000000F0 00 <1> db 0x00 ;base 23:16
131 000000F1 FA <1> db 0xFA ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
132 000000F2 CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
133 000000F3 00 <1> db 0x00 ;base 31:24
134 <1> USER_DATA equ $-gdt
135 000000F4 FFFF <1> dw 0xffff ;limit 15:0
136 000000F6 0000 <1> dw 0x0000 ;base 15:0
137 000000F8 00 <1> db 0x00 ;base 23:16
138 000000F9 F2 <1> db 0xF2 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
139 000000FA CF <1> db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
140 000000FB 00 <1> db 0x00 ;base 31:24
141 <1> gVESA_CODE equ $-gdt
142 000000FC FFFF <1> dw 0xffff ;limit 15:0
143 000000FE 0000 <1> dw 0x0000 ;base 15:0
144 00000100 00 <1> db 0x00 ;base 23:16
145 00000101 9A <1> db 0x9A ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
146 00000102 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
147 00000103 00 <1> db 0x00 ;base 31:24
148 <1> VESA_DATA equ $-gdt
149 00000104 FFFF <1> dw 0xffff ;limit 15:0
150 00000106 0000 <1> dw 0x0000 ;base 15:0
151 00000108 00 <1> db 0x00 ;base 23:16
152 00000109 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
153 0000010A 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
154 0000010B 00 <1> db 0x00 ;base 31:24
155 <1> VIDEO_TEXT equ $-gdt
156 0000010C FF7F <1> dw 0x7FFF ;limit 15:0
157 0000010E 0080 <1> dw 0x8000 ;base 15:0
158 00000110 0B <1> db 0x0B ;base 23:16
159 00000111 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
160 00000112 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
161 00000113 00 <1> db 0x00 ;base 31:24
162 <1> VIDEO_GRAPHICS equ $-gdt
163 00000114 FFFF <1> dw 0xFFFF ;limit 15:0
164 00000116 0000 <1> dw 0x0000 ;base 15:0
165 00000118 0A <1> db 0x0A ;base 23:16
166 00000119 92 <1> db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
167 0000011A 40 <1> db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
168 0000011B 00 <1> db 0x00 ;base 31:24
169 <1> gdt_end:
170 <1>
171 <1>
172 <1>
173 %include "idt.inc"
174 <1> ;idt.inc
175 <1> ;Author: Josh Holtrop
176 <1> ;Date: 10/30/03
177 <1> ;Modified: 03/02/04
178 <1>
179 <1> idtr:
180 0000011C 8F01 <1> dw 50*8-1 ;size of idt
181 0000011E 002010C0 <1> dd IDT_V ;address of idt
182 <1>
183 <1>
184 <1> %macro isr_label 1
185 <1> isr_%1:
186 <1> push eax
187 <1> mov eax, %1
188 <1> jmp isr_main
189 <1> %endmacro
190 <1>
191 <1> isr_label 0
192 <2> isr_%1:
193 00000122 50 <2> push eax
194 00000123 B800000000 <2> mov eax, %1
195 00000128 E91B020000 <2> jmp isr_main
196 <1> isr_label 1
197 <2> isr_%1:
198 0000012D 50 <2> push eax
199 0000012E B801000000 <2> mov eax, %1
200 00000133 E910020000 <2> jmp isr_main
201 <1> isr_label 2
202 <2> isr_%1:
203 00000138 50 <2> push eax
204 00000139 B802000000 <2> mov eax, %1
205 0000013E E905020000 <2> jmp isr_main
206 <1> isr_label 3
207 <2> isr_%1:
208 00000143 50 <2> push eax
209 00000144 B803000000 <2> mov eax, %1
210 00000149 E9FA010000 <2> jmp isr_main
211 <1> isr_label 4
212 <2> isr_%1:
213 0000014E 50 <2> push eax
214 0000014F B804000000 <2> mov eax, %1
215 00000154 E9EF010000 <2> jmp isr_main
216 <1> isr_label 5
217 <2> isr_%1:
218 00000159 50 <2> push eax
219 0000015A B805000000 <2> mov eax, %1
220 0000015F E9E4010000 <2> jmp isr_main
221 <1> isr_label 6
222 <2> isr_%1:
223 00000164 50 <2> push eax
224 00000165 B806000000 <2> mov eax, %1
225 0000016A E9D9010000 <2> jmp isr_main
226 <1> isr_label 7
227 <2> isr_%1:
228 0000016F 50 <2> push eax
229 00000170 B807000000 <2> mov eax, %1
230 00000175 E9CE010000 <2> jmp isr_main
231 <1> isr_label 8
232 <2> isr_%1:
233 0000017A 50 <2> push eax
234 0000017B B808000000 <2> mov eax, %1
235 00000180 E9C3010000 <2> jmp isr_main
236 <1> isr_label 9
237 <2> isr_%1:
238 00000185 50 <2> push eax
239 00000186 B809000000 <2> mov eax, %1
240 0000018B E9B8010000 <2> jmp isr_main
241 <1> isr_label 10
242 <2> isr_%1:
243 00000190 50 <2> push eax
244 00000191 B80A000000 <2> mov eax, %1
245 00000196 E9AD010000 <2> jmp isr_main
246 <1> isr_label 11
247 <2> isr_%1:
248 0000019B 50 <2> push eax
249 0000019C B80B000000 <2> mov eax, %1
250 000001A1 E9A2010000 <2> jmp isr_main
251 <1> isr_label 12
252 <2> isr_%1:
253 000001A6 50 <2> push eax
254 000001A7 B80C000000 <2> mov eax, %1
255 000001AC E997010000 <2> jmp isr_main
256 <1> isr_label 13
257 <2> isr_%1:
258 000001B1 50 <2> push eax
259 000001B2 B80D000000 <2> mov eax, %1
260 000001B7 E98C010000 <2> jmp isr_main
261 <1> isr_label 14
262 <2> isr_%1:
263 000001BC 50 <2> push eax
264 000001BD B80E000000 <2> mov eax, %1
265 000001C2 E981010000 <2> jmp isr_main
266 <1> isr_label 15
267 <2> isr_%1:
268 000001C7 50 <2> push eax
269 000001C8 B80F000000 <2> mov eax, %1
270 000001CD E976010000 <2> jmp isr_main
271 <1> isr_label 16
272 <2> isr_%1:
273 000001D2 50 <2> push eax
274 000001D3 B810000000 <2> mov eax, %1
275 000001D8 E96B010000 <2> jmp isr_main
276 <1> isr_label 17
277 <2> isr_%1:
278 000001DD 50 <2> push eax
279 000001DE B811000000 <2> mov eax, %1
280 000001E3 E960010000 <2> jmp isr_main
281 <1> isr_label 18
282 <2> isr_%1:
283 000001E8 50 <2> push eax
284 000001E9 B812000000 <2> mov eax, %1
285 000001EE E955010000 <2> jmp isr_main
286 <1> isr_label 19
287 <2> isr_%1:
288 000001F3 50 <2> push eax
289 000001F4 B813000000 <2> mov eax, %1
290 000001F9 E94A010000 <2> jmp isr_main
291 <1> isr_label 20
292 <2> isr_%1:
293 000001FE 50 <2> push eax
294 000001FF B814000000 <2> mov eax, %1
295 00000204 E93F010000 <2> jmp isr_main
296 <1> isr_label 21
297 <2> isr_%1:
298 00000209 50 <2> push eax
299 0000020A B815000000 <2> mov eax, %1
300 0000020F E934010000 <2> jmp isr_main
301 <1> isr_label 22
302 <2> isr_%1:
303 00000214 50 <2> push eax
304 00000215 B816000000 <2> mov eax, %1
305 0000021A E929010000 <2> jmp isr_main
306 <1> isr_label 23
307 <2> isr_%1:
308 0000021F 50 <2> push eax
309 00000220 B817000000 <2> mov eax, %1
310 00000225 E91E010000 <2> jmp isr_main
311 <1> isr_label 24
312 <2> isr_%1:
313 0000022A 50 <2> push eax
314 0000022B B818000000 <2> mov eax, %1
315 00000230 E913010000 <2> jmp isr_main
316 <1> isr_label 25
317 <2> isr_%1:
318 00000235 50 <2> push eax
319 00000236 B819000000 <2> mov eax, %1
320 0000023B E908010000 <2> jmp isr_main
321 <1> isr_label 26
322 <2> isr_%1:
323 00000240 50 <2> push eax
324 00000241 B81A000000 <2> mov eax, %1
325 00000246 E9FD000000 <2> jmp isr_main
326 <1> isr_label 27
327 <2> isr_%1:
328 0000024B 50 <2> push eax
329 0000024C B81B000000 <2> mov eax, %1
330 00000251 E9F2000000 <2> jmp isr_main
331 <1> isr_label 28
332 <2> isr_%1:
333 00000256 50 <2> push eax
334 00000257 B81C000000 <2> mov eax, %1
335 0000025C E9E7000000 <2> jmp isr_main
336 <1> isr_label 29
337 <2> isr_%1:
338 00000261 50 <2> push eax
339 00000262 B81D000000 <2> mov eax, %1
340 00000267 E9DC000000 <2> jmp isr_main
341 <1> isr_label 30
342 <2> isr_%1:
343 0000026C 50 <2> push eax
344 0000026D B81E000000 <2> mov eax, %1
345 00000272 E9D1000000 <2> jmp isr_main
346 <1> isr_label 31
347 <2> isr_%1:
348 00000277 50 <2> push eax
349 00000278 B81F000000 <2> mov eax, %1
350 0000027D E9C6000000 <2> jmp isr_main
351 <1> isr_label 32
352 <2> isr_%1:
353 00000282 50 <2> push eax
354 00000283 B820000000 <2> mov eax, %1
355 00000288 E9BB000000 <2> jmp isr_main
356 <1> isr_label 33
357 <2> isr_%1:
358 0000028D 50 <2> push eax
359 0000028E B821000000 <2> mov eax, %1
360 00000293 E9B0000000 <2> jmp isr_main
361 <1> isr_label 34
362 <2> isr_%1:
363 00000298 50 <2> push eax
364 00000299 B822000000 <2> mov eax, %1
365 0000029E E9A5000000 <2> jmp isr_main
366 <1> isr_label 35
367 <2> isr_%1:
368 000002A3 50 <2> push eax
369 000002A4 B823000000 <2> mov eax, %1
370 000002A9 E99A000000 <2> jmp isr_main
371 <1> isr_label 36
372 <2> isr_%1:
373 000002AE 50 <2> push eax
374 000002AF B824000000 <2> mov eax, %1
375 000002B4 E98F000000 <2> jmp isr_main
376 <1> isr_label 37
377 <2> isr_%1:
378 000002B9 50 <2> push eax
379 000002BA B825000000 <2> mov eax, %1
380 000002BF E984000000 <2> jmp isr_main
381 <1> isr_label 38
382 <2> isr_%1:
383 000002C4 50 <2> push eax
384 000002C5 B826000000 <2> mov eax, %1
385 000002CA E979000000 <2> jmp isr_main
386 <1> isr_label 39
387 <2> isr_%1:
388 000002CF 50 <2> push eax
389 000002D0 B827000000 <2> mov eax, %1
390 000002D5 E96E000000 <2> jmp isr_main
391 <1> isr_label 40
392 <2> isr_%1:
393 000002DA 50 <2> push eax
394 000002DB B828000000 <2> mov eax, %1
395 000002E0 E963000000 <2> jmp isr_main
396 <1> isr_label 41
397 <2> isr_%1:
398 000002E5 50 <2> push eax
399 000002E6 B829000000 <2> mov eax, %1
400 000002EB E958000000 <2> jmp isr_main
401 <1> isr_label 42
402 <2> isr_%1:
403 000002F0 50 <2> push eax
404 000002F1 B82A000000 <2> mov eax, %1
405 000002F6 E94D000000 <2> jmp isr_main
406 <1> isr_label 43
407 <2> isr_%1:
408 000002FB 50 <2> push eax
409 000002FC B82B000000 <2> mov eax, %1
410 00000301 E942000000 <2> jmp isr_main
411 <1> isr_label 44
412 <2> isr_%1:
413 00000306 50 <2> push eax
414 00000307 B82C000000 <2> mov eax, %1
415 0000030C E937000000 <2> jmp isr_main
416 <1> isr_label 45
417 <2> isr_%1:
418 00000311 50 <2> push eax
419 00000312 B82D000000 <2> mov eax, %1
420 00000317 E92C000000 <2> jmp isr_main
421 <1> isr_label 46
422 <2> isr_%1:
423 0000031C 50 <2> push eax
424 0000031D B82E000000 <2> mov eax, %1
425 00000322 E921000000 <2> jmp isr_main
426 <1> isr_label 47
427 <2> isr_%1:
428 00000327 50 <2> push eax
429 00000328 B82F000000 <2> mov eax, %1
430 0000032D E916000000 <2> jmp isr_main
431 <1> isr_label 48
432 <2> isr_%1:
433 00000332 50 <2> push eax
434 00000333 B830000000 <2> mov eax, %1
435 00000338 E90B000000 <2> jmp isr_main
436 <1> isr_label 49
437 <2> isr_%1:
438 0000033D 50 <2> push eax
439 0000033E B831000000 <2> mov eax, %1
440 00000343 E900000000 <2> jmp isr_main
441 <1>
442 <1> isr_main:
443 00000348 3D30000000 <1> cmp eax, 0x30
444 0000034D 7414 <1> jz isr_syscall
445 <1>
446 0000034F 60 <1> pusha
447 00000350 1E <1> push ds
448 00000351 06 <1> push es
449 <1>
450 00000352 50 <1> push eax
451 <1>
452 00000353 E8(00000000) <1> call _isr
453 <1>
454 00000358 81C404000000 <1> add esp, 4
455 <1>
456 0000035E 07 <1> pop es
457 0000035F 1F <1> pop ds
458 00000360 61 <1> popa
459 00000361 58 <1> pop eax
460 <1>
461 00000362 CF <1> iret
462 <1>
463 <1>
464 <1> isr_syscall:
465 00000363 58 <1> pop eax ;syscall function number
466 00000364 60 <1> pusha
467 00000365 1E <1> push ds
468 00000366 06 <1> push es
469 <1>
470 <1> sc1:
471 00000367 3D01000000 <1> cmp eax, 1 ;syscall 1 - putc
472 0000036C 7511 <1> jnz sc2
473 0000036E 53 <1> push ebx
474 0000036F E8(00000000) <1> call _putc
475 00000374 81C404000000 <1> add esp, 4
476 0000037A E900000000 <1> jmp scdone
477 <1> sc2:
478 <1>
479 <1> scdone:
480 0000037F 07 <1> pop es
481 00000380 1F <1> pop ds
482 00000381 61 <1> popa
483 00000382 CF <1> iret
484 <1>
485 <1>
486 <1>
487 <1>
488 <1>
489 <1>
490 <1>
491
492

132
kernel/mm/mm.cpp Normal file
View File

@ -0,0 +1,132 @@
// mm.c
// Author: Josh Holtrop
// Created: 09/01/03
// Modified: 03/08/04
#include "hos_defines.h"
#include "mm.h"
//The total amount of physical memory available (bytes, 1 bit per page)
#define BITMAP_SIZE 0x20000
dword mm_totalmem = 0;
dword mm_megabytes = 0;
byte page_bitmap[BITMAP_SIZE]; //used to store a bit for each page that is used, 0 if available
//0x20000*(8 bits/byte)=0x100000 pages in 4gb total
//This function initializes the memory manager's linked list, filling it with the
// memory areas returned by bios interrupt 0x8E20
void mm_init()
{
dword memmap_entries = *(dword *)BOOT_MEMMAP_ENTRIES;
memmap_entry *maps = (memmap_entry *) BOOT_FIRST_MEMMAP;
dword a;
for (a = 0; a < BITMAP_SIZE; a++)
{
page_bitmap[a] = 0xFF; //all pages used
}
for (a = 0; a < memmap_entries; a++)
{
if (maps[a].attributes == 1) // (1) mem free to OS
{
mm_totalmem += maps[a].limit.lowdword;
if ((maps[a].base.lowdword + maps[a].limit.lowdword) >= (FREERAM_START+4096)) //goes past where we start freeram
{
if (maps[a].base.lowdword < FREERAM_START)
{
mm_pfreen(FREERAM_START, (maps[a].limit.lowdword - (FREERAM_START - maps[a].base.lowdword)) >> 12);
}
else
{
mm_pfreen(maps[a].base.lowdword, maps[a].limit.lowdword >> 12); //set the appropriate bits as "free" in the page bitmap
}
}
}
}
if (mm_totalmem % 0x100000)
mm_megabytes = (mm_totalmem >> 20) + 1;
else
mm_megabytes = mm_totalmem >> 20;
}
// This function frees a certain number of pages starting at the address
// specified in base for a length of pages pages
void mm_pfreen(dword base, dword pages)
{
dword a;
dword max = base + (pages << 12);
for (a = base; a < max; a += 4096)
{
mm_pfree(a);
}
}
// This function frees a single page
void mm_pfree(dword base)
{
// dword pageNumber = base >> 12; // >>12 == /4096
dword byteNumber = base >> 15; //pageNumber >> 3; //pageNumber/8
dword bitNumber = (base >> 12) % 8; //pageNumber % 8;
page_bitmap[byteNumber] = page_bitmap[byteNumber] & ((0x01 << bitNumber) ^ 0xFF);
}
// This function allocates a single page, returning its physical address
void *mm_palloc()
{
dword bite;
for (bite = 0; bite < BITMAP_SIZE; bite++)
{
if (page_bitmap[bite] != 0xFF) //there is an available page within this 8-page region
{
int bit;
for (bit = 0; bit < 8; bit++)
{
if (!(page_bitmap[bite] & (1 << bit))) //this bite/bit combination is available
{
page_bitmap[bite] = page_bitmap[bite] | (1 << bit); //set page as used
return (void *)((bite << 15) | (bit << 12));
}
}
}
}
return 0; //no free page
}
// This function reports the number of bytes of free physical memory
dword mm_freemem()
{
dword a;
dword pages = 0;
for (a = 0; a < BITMAP_SIZE; a++)
{
int bit;
for (bit = 0; bit < 8; bit++)
{
if (!(page_bitmap[a] & (1 << bit)))
pages++;
}
}
return pages << 12;
}
dword mm_getTotalMem()
{
return mm_totalmem;
}
dword mm_getTotalMegs()
{
return mm_megabytes;
}

28
kernel/mm/mm.h Normal file
View File

@ -0,0 +1,28 @@
// mm.c
// Author: Josh Holtrop
// Created: 09/01/03
// Modified: 03/08/04
#ifndef __HOS_MM__
#define __HOS_MM__ __HOS_MM__
#include "hos_defines.h"
typedef struct {
qword base;
qword limit;
dword attributes;
} __attribute__((packed)) memmap_entry;
void mm_init();
void mm_pfreen(dword base, dword pages);
void mm_pfree(dword base);
void *mm_palloc();
dword mm_freemem();
dword mm_getTotalMem();
dword mm_getTotalMegs();
#endif

380
kernel/mm/vmm.cpp Normal file
View File

@ -0,0 +1,380 @@
// vmm.c
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03
// Modified: 03/02/04
#include "hos_defines.h"
#include "vmm.h"
#include "asmfuncs.h"
#include "mm/mm.h"
HeapEntry *firstHeapEntry = (HeapEntry *)0xD0000000; //this is where heap memory starts
// This is the initialization procedure for the Virtual Memory Manager
// It sets up the final page directory/page table setup and maps video memory, if present
void vmm_init()
{
unsigned int *pageTables = (unsigned int *)0xC0104000; //this is the location of the page directory
pageTables[0x3FF] = 0x104000|0x03; //the last page directory entry points to the page directory itself
pageTables[0] = 0;
invlpg_(0);
unsigned int firstHeapEntryBlock = (unsigned int)mm_palloc();
vmm_map1((unsigned int)firstHeapEntry, firstHeapEntryBlock);
HeapEntryBlock *heb = (HeapEntryBlock *)firstHeapEntry;
vmm_heb_init(heb);
heb->entry[0].base = (unsigned int)firstHeapEntry; //start of kernel's heap memory
heb->entry[0].size = 4096; //the first HeapEntryBlock is 1 page long
heb->entry[0].attributes = VMM_HE_HEB; //this is a HeapEntryBlock
heb->entry[1].base = (unsigned int)firstHeapEntry+4096; //this is the start of the rest of the kernel's heap memory
heb->entry[1].size = 0x10000000-4096; //the rest of the kernel's heap memory: 256mb - 4kb
heb->entry[1].attributes = VMM_HE_HOLE; //this is a hole - an unmapped section of heap memory
}
// This function initialzes a Heap Entry Block to unused entries linked together
void vmm_heb_init(HeapEntryBlock *heb)
{
int a;
for (a = 0; a < 256; a++)
{
heb->entry[a].base = 0;
heb->entry[a].size = 0;
heb->entry[a].attributes = VMM_HE_UNUSED;
heb->entry[a].link = (unsigned int)&(heb->entry[a+1]);
}
heb->entry[255].link = 0;
}
// This function maps a virtual address to a physical address using the page directory / page table
void vmm_map1(unsigned int virt, unsigned int physical)
{
unsigned int pde = virt >> 22;
unsigned int pte = (virt & 0x003FF000) >> 12;
unsigned int *pageTables = (unsigned int *)0xC0104000; //this is the location of the page directory
if (!(pageTables[pde] & 0x01)) //the page directory entry does not exist, we must allocate a page for it
{
unsigned int *newpagetable = (dword *)mm_palloc();
pageTables[pde] = ((unsigned int)newpagetable) | 0x03;
invlpg_(virt);
unsigned int *newpteptr = (unsigned int *)(0xFFC00000 | (pde << 12)); //points to first unsigned int of newly allocated page table
int a;
for (a = 0; a < 1024; a++)
{
newpteptr[a] = 0;
}
}
unsigned int *pteptr = (unsigned int *)(0xFFC00000 | (pde << 12) | (pte << 2));
*pteptr = physical | 0x03;
invlpg_(virt);
}
// This function maps a variable number of pages in a row
void vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n)
{
for (; n > 0; n--)
{
vmm_map1(virt, physical);
virt += 4096;
physical += 4096;
}
}
// This function removes the virtual address's entry in the page directory / page table
void vmm_unmap1(unsigned int virt)
{
unsigned int *pteptr = (unsigned int *)(0xFFC00000 | ((virt & 0xFFC00000) >> 10) | ((virt & 0x003FF000) >> 10));
*pteptr = 0;
invlpg_(virt);
}
// This function removes multiple pages' entries
void vmm_unmapn(unsigned int virt, unsigned int n)
{
for (; n > 0; n--)
{
vmm_unmap1(virt);
virt += 4096;
}
}
// Virtual Memory allocator function
void *malloc(unsigned int bytes)
{
if (bytes % VMM_MALLOC_GRANULARITY)
bytes = bytes + VMM_MALLOC_GRANULARITY - (bytes % VMM_MALLOC_GRANULARITY);
void *attempt = vmm_getFreeChunk(bytes);
if (attempt)
return attempt;
if(vmm_moreCore(bytes))
return NULL; //we could not get any more heap memory
return vmm_getFreeChunk(bytes);
}
// This function returns a pointer if a free chunk of memory exists
void *vmm_getFreeChunk(unsigned int bytes)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->attributes == VMM_HE_FREE)
{
if (he->size > bytes)
{
HeapEntry *nhe = vmm_nextHeapEntry();
nhe->base = he->base;
nhe->size = bytes;
nhe->attributes = VMM_HE_USED;
he->base += bytes;
he->size -= bytes;
return (void *)(nhe->base);
}
if (he->size == bytes)
{
he->attributes = VMM_HE_USED;
return (void *)(he->base);
}
}
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function coalesces any two adjacent heap entries into one entry
void vmm_coalesceHeapEntry(HeapEntry *he)
{
if (!(he->attributes == VMM_HE_FREE || he->attributes == VMM_HE_HOLE))
return;
if (he->size == 0)
{
he->attributes = VMM_HE_UNUSED;
return;
}
HeapEntry *hec = firstHeapEntry;
for (;;)
{
if (hec->attributes == he->attributes)
{
if ((hec->base + hec->size) == he->base) //hec ends where he begins
{
he->base = hec->base;
he->size += hec->size;
hec->attributes = VMM_HE_UNUSED;
}
if ((he->base + he->size) == hec->base) //he ends where hec begins
{
he->size += hec->size;
hec->attributes = VMM_HE_UNUSED;
}
}
hec = (HeapEntry *)hec->link;
if (!hec)
break;
}
}
// This function retrieves more physical memory for the heap
int vmm_moreCore(unsigned int bytes)
{
unsigned int pages = (bytes >> 12) + 1;
bytes = pages << 12;
HeapEntry *he = vmm_getFirstHoleHeapEntry(bytes);
unsigned int virt = he->base;
for (; pages > 0; pages--)
{
unsigned int phys = (unsigned int)mm_palloc();
if (!phys)
return 1;
vmm_map1(virt, phys);
virt += 4096;
}
if (he->size == bytes)
{
he->attributes = VMM_HE_FREE;
vmm_coalesceHeapEntry(he);
}
else
{
HeapEntry *nhe = vmm_nextHeapEntry();
nhe->base = he->base;
nhe->size = bytes;
nhe->attributes = VMM_HE_FREE;
he->base += bytes;
he->size -= bytes;
vmm_coalesceHeapEntry(nhe);
}
return 0;
}
// This function returns the next available heap entry, creates more entries if we are running low
HeapEntry *vmm_nextHeapEntry()
{
if (vmm_heapEntriesLeft() < 10)
vmm_addHeapEntryBlock();
return vmm_getFirstUnusedHeapEntry();
}
// This function creates a new block (page) of heap entries (256)
void vmm_addHeapEntryBlock()
{
HeapEntry *he = vmm_getFirstHoleHeapEntry(4096);
HeapEntry *newBlock = vmm_getFirstUnusedHeapEntry();
unsigned int heb = (unsigned int)mm_palloc();
vmm_map1(he->base, heb);
vmm_heb_init((HeapEntryBlock *)he->base);
HeapEntry *lhe = vmm_getLastHeapEntry();
if (he->size == 4096)
{
he->attributes = VMM_HE_HEB;
lhe->link = (unsigned int)he->base;
}
else
{
newBlock->base = he->base;
newBlock->size = 4096;
newBlock->attributes = VMM_HE_HEB;
he->base += 4096;
he->size -= 4096;
lhe->link = (unsigned int)newBlock->base;
}
return;
}
// This function returns the last heap entry in the linked list, useful for setting
// its link field to point to the first entry of a newly allocated list
HeapEntry *vmm_getLastHeapEntry()
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->link == 0)
return he;
he = (HeapEntry *)he->link;
}
}
// This function returns the first heap entry corresponding to a memory "hole"
HeapEntry *vmm_getFirstHoleHeapEntry(unsigned int minBytes)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if ((he->attributes == VMM_HE_HOLE) && (he->size >= minBytes))
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function returns the first heap entry that is not being used
HeapEntry *vmm_getFirstUnusedHeapEntry()
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->attributes == VMM_HE_UNUSED)
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function returns the number of heap entries available for use
unsigned int vmm_heapEntriesLeft()
{
HeapEntry *he = firstHeapEntry;
unsigned int entries = 0;
for (;;)
{
if (he->attributes == VMM_HE_UNUSED)
entries++;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return entries;
}
// This function "frees" an area of memory previously allocated with malloc()
int free(void *ptr)
{
HeapEntry *he = vmm_getHeapEntryByBase((unsigned int)ptr);
if (!he)
return 1; //a heap entry starting at the given address was not found
he->attributes = VMM_HE_FREE;
vmm_coalesceHeapEntry(he);
return 0;
}
// This function scans the heap entry linked list for an entry that begins at the given address
HeapEntry *vmm_getHeapEntryByBase(unsigned int base)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->base == base)
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return NULL;
}
// This function re-allocates memory already allocated, preserving the old contents
// (as long as newSize is greater than oldSize)
void *realloc(void *orig, unsigned int newSize)
{
void *newMem;
if ((newMem = malloc(newSize)))
{
HeapEntry *he = vmm_getHeapEntryByBase((unsigned int) orig);
if (!he)
return NULL; //old chunk not found / nonexistent
memcpy(newMem, orig, (he->size < newSize ? he->size : newSize));
free(orig);
return newMem;
}
else
return NULL; //could not get mem for new chunk
}
// This function allocates and zeros memory for the given number of objects,
// given the size of each object
void *calloc(unsigned int number, unsigned int size)
{
void *mem = malloc(number * size);
if (!mem)
return NULL; //could not get memory
memset(mem, 0, number * size);
return mem;
}

56
kernel/mm/vmm.h Normal file
View File

@ -0,0 +1,56 @@
// vmm.h
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03
// Modified: 03/02/04
#include "hos_defines.h"
#ifndef __HOS_VMM__
#define __HOS_VMM__ __HOS_VMM__
#define VMM_HE_UNUSED 0 //available entry
#define VMM_HE_FREE 1 //free section of memory
#define VMM_HE_USED 2 //used section of memory
#define VMM_HE_HOLE 3 //a "hole" (unmapped) section of virtual memory
#define VMM_HE_HEB 4 //HeapEntryBlock
#define VMM_MALLOC_GRANULARITY 4 //granularity for all memory requests
typedef struct {
unsigned int base; //virtual base address
unsigned int size; //size in bytes
unsigned int attributes; //free/used/hole
unsigned int link; //link to next HeapEntry
} __attribute__((packed)) HeapEntry;
typedef struct {
HeapEntry entry[256]; //256 HeapEntry objects = 4kb (1 page)
} __attribute__((packed)) HeapEntryBlock;
void vmm_init();
void *malloc(unsigned int bytes);
int free(void *ptr);
void vmm_map1(unsigned int virt, unsigned int physical);
void vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n);
void vmm_unmap1(unsigned int virt);
void vmm_unmapn(unsigned int virt, unsigned int n);
void vmm_heb_init(HeapEntryBlock *heb);
void *vmm_getFreeChunk(unsigned int bytes);
HeapEntry *vmm_nextHeapEntry();
unsigned int vmm_heapEntriesLeft();
HeapEntry *vmm_getLastHeapEntry();
HeapEntry *vmm_getFirstUnusedHeapEntry();
HeapEntry *vmm_getFirstHoleHeapEntry(unsigned int minBytes);
void vmm_addHeapEntryBlock();
int vmm_moreCore(unsigned int bytes);
void vmm_coalesceHeapEntry(HeapEntry *he);
HeapEntry *vmm_getHeapEntryByBase(unsigned int base);
void *realloc(void *orig, unsigned int newSize);
void *calloc(unsigned int number, unsigned int size);
#endif

1
kernel/search.bat Executable file
View File

@ -0,0 +1 @@
grep -R -n -i %1 *

2
kernel/search.sh Normal file
View File

@ -0,0 +1,2 @@
#!/bin/sh
grep -R -n -i $1 *

42
kernel/sys/cmos.cpp Normal file
View File

@ -0,0 +1,42 @@
// cmos.c
// Author: Josh Holtrop
// Created: 02/26/04
// Implements various CMOS function calls
#include "hos_defines.h"
#include "cmos.h"
#include "sys/io.h"
//Returns the cmos type of floppy disk drive 0 (0 = not present)
unsigned char cmos_getfd0()
{
outportb(0x70, 0x10);
return (inportb(0x71) >> 4);
}
//Returns the cmos type of floppy disk drive 1 (0 = not present)
unsigned char cmos_getfd1()
{
outportb(0x70, 0x10);
return (inportb(0x71) & 0x0F);
}
//Returns the cmos type of hard disk drive 0 (0 = not present)
unsigned char cmos_gethd0()
{
outportb(0x70, 0x12);
return (inportb(0x71) >> 4);
}
//Returns the cmos type of hard disk drive 1 (0 = not present)
unsigned char cmos_gethd1()
{
outportb(0x70, 0x12);
return (inportb(0x71) & 0x0F);
}

18
kernel/sys/cmos.h Normal file
View File

@ -0,0 +1,18 @@
// cmos.h
// Author: Josh Holtrop
// Created: 02/26/04
// Implements various CMOS function calls
#include "hos_defines.h"
#ifndef __HOS_CMOS__
#define __HOS_CMOS__ __HOS_CMOS__
unsigned char cmos_getfd0();
unsigned char cmos_getfd1();
unsigned char cmos_gethd0();
unsigned char cmos_gethd1();
#endif

8
kernel/sys/io.cpp Normal file
View File

@ -0,0 +1,8 @@
// io.c
// Author: Josh Holtrop
// Created: 02/26/04
// Implements basic port input/output functions
#include "io.h"

40
kernel/sys/io.h Normal file
View File

@ -0,0 +1,40 @@
// io.h
// Author: Josh Holtrop
// Created: 02/26/04
// Implements basic port input/output functions
#ifndef __HOS_IO__
#define __HOS_IO__ __HOS_IO__
#include "hos_defines.h"
//void outportb(unsigned int port, unsigned char value);
//inline void outportw(unsigned int port, unsigned int value);
//inline unsigned char inportb(unsigned short port);
//Writes a byte out to a port
static inline void outportb(unsigned int port, unsigned char value) // Output a byte to a port
{
asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value));
}
//Writes a word out to a port
static inline void outportw(unsigned int port, unsigned int value) // Output a word to a port
{
asm volatile ("outw %%ax,%%dx"::"d" (port), "a" (value));
}
//Reads a byte from a port
static inline unsigned char inportb(unsigned short port)
{
unsigned char ret_val;
asm volatile("inb %w1,%b0"
: "=a"(ret_val)
: "d"(port));
return ret_val;
}
#endif

30
kernel/sys/pic.cpp Normal file
View File

@ -0,0 +1,30 @@
// pic.c
// Author: Josh Holtrop
// Created: 02/26/04
#include "hos_defines.h"
#include "pic.h"
#include "sys/io.h"
//Re-maps the Programmable Interrupr Controllers so IRQ0->pic1 base address, IRG8->pic2 base address
void pic_remap(int pic1, int pic2)
{
byte a1, a2;
a1 = inportb(PIC1_DATA); //0x21
a2 = inportb(PIC2_DATA); //0xA1
outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); //0x20, 0x10+0x01 00010001b
outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4); //0xA0, 0x10+0x01 00010001b
outportb(PIC1_DATA, pic1); //0x21, pic1
outportb(PIC2_DATA, pic2); //0xA1, pic2
outportb(PIC1_DATA, 4); //0x21, 0x04 00000100b
outportb(PIC2_DATA, 2); //0xA1, 0x02 00000010b
outportb(PIC1_DATA, ICW4_8086); //0x21, 0x01 00000001b
outportb(PIC2_DATA, ICW4_8086); //0xA1, 0x01 00000001b
outportb(PIC1_DATA, a1); //0x21
outportb(PIC2_DATA, a2); //0xA1
}

65
kernel/sys/pic.h Normal file
View File

@ -0,0 +1,65 @@
// pic.h
// Author: Josh Holtrop
// Created: 02/26/04
#ifndef __HOS_PIC__
#define __HOS_PIC__ __HOS_PIC__
#include "hos_defines.h"
#include "sys/io.h"
#define PIC1 0x20
#define PIC2 0xA0
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1+1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2+1)
#define PIC_EOI 0x20
#define ICW1_ICW4 0x01 /* ICW4 (not) needed */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
void pic_remap(int pic1, int pic2);
//inline void pic_mask1(byte mask);
//inline void pic_mask2(byte mask);
//inline void pic_eoi();
//inline void pic_eoi2();
//Masks interrupts on first Programmable Interrupt Controller
static inline void pic_mask1(byte mask)
{
outportb(PIC1_DATA, mask); //0x21, maskfield *OCW1*
}
//Masks interrupts on second Programmable Interrupt Controller
static inline void pic_mask2(byte mask)
{
outportb(PIC2_DATA, mask); //0xA1, maskfield *OCW1*
}
//Signals an End Of Interrupt signal to the first PIC
static inline void pic_eoi()
{
outportb(0x20, 0x20);
}
//Signals an End Of Interrupt signal to both the second and first PIC unit
static inline void pic_eoi2()
{
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
#endif

83
kernel/sys/rtc.cpp Normal file
View File

@ -0,0 +1,83 @@
// rtc.c
// Author: Josh Holtrop
// Created: 02/26/04
// Implements Real-Time Clock function calls
// These functions are for reading and writing various values stored on the CMOS Real Time Clock
// Parameters / return values are in BCD format
#include "hos_defines.h"
#include "rtc.h"
#include "sys/io.h"
unsigned char rtc_readDay()
{
outportb(0x70, 7);
return inportb(0x71);
}
unsigned char rtc_readMonth()
{
outportb(0x70, 8);
return inportb(0x71);
}
unsigned char rtc_readYear()
{
outportb(0x70, 9);
return inportb(0x71);
}
unsigned char rtc_readSecond()
{
outportb(0x70, 0);
return inportb(0x71);
}
unsigned char rtc_readMinute()
{
outportb(0x70, 2);
return inportb(0x71);
}
unsigned char rtc_readHour()
{
outportb(0x70, 4);
return inportb(0x71);
}
void rtc_setDay(unsigned char day)
{
outportb(0x70, 7);
outportb(0x71, day);
}
void rtc_setMonth(unsigned char month)
{
outportb(0x70, 8);
outportb(0x71, month);
}
void rtc_setYear(unsigned char year)
{
outportb(0x70, 9);
outportb(0x71, year);
}
void rtc_setSecond(unsigned char second)
{
outportb(0x70, 0);
outportb(0x71, second);
}
void rtc_setMinute(unsigned char minute)
{
outportb(0x70, 2);
outportb(0x71, minute);
}
void rtc_setHour(unsigned char hour)
{
outportb(0x70, 4);
outportb(0x71, hour);
}

28
kernel/sys/rtc.h Normal file
View File

@ -0,0 +1,28 @@
// rtc.h
// Author: Josh Holtrop
// Created: 02/26/04
// Implements Real-Time Clock function calls
// These functions are for reading and writing various values stored on the CMOS Real Time Clock
// Parameters / return values are in BCD format
#ifndef __HOS_RTC__
#define __HOS_RTC__ __HOS_RTC__
#include "hos_defines.h"
unsigned char rtc_readDay();
unsigned char rtc_readMonth();
unsigned char rtc_readYear();
unsigned char rtc_readSecond();
unsigned char rtc_readMinute();
unsigned char rtc_readHour();
void rtc_setDay(unsigned char dat);
void rtc_setMonth(unsigned char month);
void rtc_setYear(unsigned char year);
void rtc_setSecond(unsigned char second);
void rtc_setMinute(unsigned char minute);
void rtc_setHour(unsigned char hour);
#endif

551
kernel/video/stdfont.cpp Normal file
View File

@ -0,0 +1,551 @@
// stdfont.c
// Author: Josh Holtrop
// Created: 02/26/04
#include "stdfont.h"
const unsigned char stdfont8x5[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xE0, 0xC0, 0x80,
0x00, 0x08, 0x18, 0x38, 0x78, 0x38, 0x18, 0x08,
0x00, 0x20, 0x70, 0xA8, 0x20, 0xA8, 0x70, 0x20,
0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0x00, 0xA0, 0xA0,
0x00, 0x78, 0xA8, 0xA8, 0x78, 0x28, 0x28, 0x68,
0x00, 0x78, 0x80, 0x70, 0x88, 0x70, 0x08, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8,
0x00, 0x20, 0x70, 0xA8, 0x20, 0xA8, 0x70, 0xF8,
0x00, 0x20, 0x70, 0xA8, 0x20, 0x20, 0x20, 0x20,
0x00, 0x20, 0x20, 0x20, 0x20, 0xA8, 0x70, 0x20,
0x00, 0x00, 0x20, 0x10, 0xF8, 0x10, 0x20, 0x00,
0x00, 0x00, 0x20, 0x40, 0xF8, 0x40, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x60, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x70, 0xF8, 0xF8, 0x00, 0x00,
0x00, 0x00, 0xF8, 0xF8, 0x70, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x20,
0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x50, 0xF8, 0x50, 0x50, 0x50, 0xF8, 0x50,
0x00, 0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20,
0x00, 0x00, 0x08, 0x90, 0x20, 0x48, 0x80, 0x00,
0x00, 0x20, 0x50, 0x50, 0x20, 0x58, 0x90, 0x68,
0x00, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20,
0x00, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40,
0x00, 0x00, 0xA8, 0x70, 0xF8, 0x70, 0xA8, 0x00,
0x00, 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40,
0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60,
0x00, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x20, 0x60, 0xA0, 0x20, 0x20, 0x20, 0x20,
0x00, 0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8,
0x00, 0x70, 0x88, 0x08, 0x10, 0x08, 0x88, 0x70,
0x00, 0x30, 0x50, 0x90, 0x90, 0xF8, 0x10, 0x10,
0x00, 0xF8, 0x80, 0x80, 0xF8, 0x08, 0x88, 0x70,
0x00, 0x38, 0x40, 0x80, 0xF0, 0x88, 0x88, 0x70,
0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40,
0x00, 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70,
0x00, 0x70, 0x88, 0x88, 0x78, 0x08, 0x10, 0x60,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x40,
0x00, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10,
0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00,
0x00, 0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80,
0x00, 0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20,
0x00, 0x70, 0x88, 0x88, 0xB8, 0xB0, 0x80, 0x78,
0x00, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70,
0x00, 0xF0, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF0,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x80, 0xB8, 0x88, 0x88, 0x70,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60,
0x00, 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88,
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8,
0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x88,
0x00, 0x88, 0xC8, 0xE8, 0xB8, 0x98, 0x88, 0x88,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x88, 0x88, 0xA8, 0x98, 0x70,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88,
0x00, 0x70, 0x88, 0x80, 0x70, 0x08, 0x88, 0x70,
0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0xA8, 0x50,
0x00, 0x88, 0x50, 0x20, 0x20, 0x50, 0x88, 0x88,
0x00, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20,
0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8,
0x00, 0x70, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70,
0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, 0x00,
0x00, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xE0,
0x00, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0xF0,
0x00, 0x00, 0x00, 0x70, 0x88, 0x80, 0x88, 0x70,
0x00, 0x08, 0x08, 0x78, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x30, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40,
0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x70,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x88,
0x00, 0x20, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x90, 0x60,
0x00, 0x80, 0x80, 0x90, 0xA0, 0xC0, 0xA0, 0x90,
0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0,
0x00, 0x00, 0x00, 0xD0, 0xA8, 0xA8, 0xA8, 0xA8,
0x00, 0x00, 0x00, 0xF0, 0x88, 0x88, 0x88, 0x88,
0x00, 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70,
0x00, 0x00, 0x00, 0xF0, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x38,
0x00, 0x00, 0x00, 0x70, 0x48, 0x40, 0x40, 0x40,
0x00, 0x00, 0x00, 0x78, 0x80, 0x70, 0x08, 0xF0,
0x00, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x20,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x50, 0x20,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0xA8, 0x50,
0x00, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88,
0x00, 0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0xF0,
0x00, 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8,
0x00, 0x30, 0x40, 0x40, 0x80, 0x40, 0x40, 0x30,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0xC0, 0x20, 0x20, 0x10, 0x20, 0x20, 0xC0,
0x00, 0x00, 0x68, 0x90, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0xF8, 0x88, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0xF8, 0x48, 0x40, 0x40, 0x40, 0x40, 0xE0,
0x00, 0xF0, 0x50, 0x50, 0x50, 0x50, 0x78, 0x88,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8,
0x00, 0xA8, 0xA8, 0x70, 0x20, 0x70, 0xA8, 0xA8,
0x00, 0x70, 0x88, 0x08, 0x30, 0x08, 0x88, 0x70,
0x00, 0x88, 0x98, 0xA8, 0xA8, 0xA8, 0xC8, 0x88,
0x00, 0xA8, 0xC8, 0x98, 0xA8, 0xA8, 0xC8, 0x88,
0x00, 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88,
0x00, 0xF8, 0x50, 0x50, 0x50, 0x50, 0x50, 0x90,
0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x88,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70,
0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x88, 0x88, 0x50, 0x20, 0x40, 0x80,
0x00, 0x70, 0x20, 0xF8, 0xA8, 0xF8, 0x20, 0x70,
0x00, 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF8, 0x08,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x08, 0x08, 0x38,
0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8,
0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8, 0x08,
0x00, 0xC0, 0x40, 0x40, 0x78, 0x48, 0x48, 0x78,
0x00, 0x88, 0x88, 0xC8, 0xA8, 0xA8, 0xA8, 0xE8,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0xF0,
0x00, 0xF0, 0x88, 0x08, 0x78, 0x08, 0x88, 0xF0,
0x00, 0x90, 0xA8, 0xA8, 0xE8, 0xA8, 0xA8, 0x90,
0x00, 0x78, 0x88, 0x88, 0x78, 0x28, 0x48, 0x88,
0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x88, 0x78,
0x00, 0x00, 0xF8, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0xF0, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0xF8, 0x48, 0x48, 0x40, 0x40, 0xE0,
0x00, 0x00, 0x78, 0x50, 0x50, 0x50, 0x70, 0x88,
0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x88, 0x70,
0x00, 0x00, 0xA8, 0x70, 0x20, 0x70, 0xA8, 0xA8,
0x00, 0x00, 0x00, 0xF0, 0x88, 0x30, 0x88, 0x70,
0x00, 0x00, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x88,
0x00, 0x50, 0x20, 0x88, 0x98, 0xA8, 0xC8, 0x88,
0x00, 0x00, 0x88, 0x90, 0xA0, 0xE0, 0x90, 0x88,
0x00, 0x00, 0xF8, 0x48, 0x48, 0x48, 0x48, 0xC8,
0x00, 0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88,
0x00, 0x00, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x00, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x50, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x88, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x88, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x90, 0x00, 0xF0, 0x80, 0xE0, 0x80, 0xF0,
0x00, 0x00, 0x70, 0x48, 0x70, 0x48, 0x48, 0xF0,
0x00, 0x88, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x70, 0x50, 0x70, 0x88, 0xF8, 0x88, 0x88,
0x00, 0x88, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88,
0x00, 0x88, 0x70, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x88, 0xF8, 0x80, 0xE0, 0x80, 0x80, 0xF8,
0x00, 0x40, 0x20, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x10, 0x20, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x20, 0x50, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x40, 0x20, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x20, 0x50, 0x00, 0x20, 0x20, 0x20, 0x20,
0x00, 0x20, 0x10, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x70, 0x80, 0x80, 0x70, 0x20,
0x00, 0x70, 0x88, 0x40, 0xF0, 0x40, 0x40, 0xF8,
0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x88, 0x88, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x70, 0x88, 0x80, 0x80, 0x88, 0x70,
0x00, 0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x00, 0x88, 0x88, 0x50, 0x20, 0x40, 0x80,
0x00, 0x00, 0x70, 0x20, 0xF8, 0xF8, 0x20, 0x70,
0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88,
0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0xF8, 0x08,
0x00, 0x00, 0x88, 0x88, 0x88, 0xF8, 0x08, 0x38,
0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8,
0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8, 0x08,
0x00, 0x00, 0xC0, 0x40, 0x70, 0x48, 0x48, 0x70,
0x00, 0x00, 0x88, 0x88, 0xC8, 0xA8, 0xA8, 0xE8,
0x00, 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0x70, 0x88, 0x38, 0x08, 0x88, 0x70,
0x00, 0x00, 0x90, 0xA8, 0xA8, 0xE8, 0xA8, 0x90,
0x00, 0x00, 0x38, 0x48, 0x48, 0x38, 0x28, 0x48,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const unsigned char stdfont10x7[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xE0, 0xF0, 0xFC, 0xF0, 0xE0, 0x80, 0x00, 0x00,
0x00, 0x02, 0x0E, 0x1E, 0x7E, 0x1E, 0x0E, 0x02, 0x00, 0x00,
0x00, 0x10, 0x7C, 0x92, 0x10, 0x92, 0x7C, 0x10, 0x00, 0x00,
0x00, 0x90, 0x90, 0x90, 0x90, 0x00, 0x90, 0x90, 0x00, 0x00,
0x00, 0x7E, 0x92, 0x92, 0x7E, 0x12, 0x12, 0x72, 0x00, 0x00,
0x00, 0x7E, 0x80, 0x7C, 0x82, 0x7C, 0x02, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
0x00, 0x10, 0x7C, 0x92, 0x10, 0x92, 0x7C, 0xFE, 0x00, 0x00,
0x00, 0x10, 0x7C, 0x92, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x10, 0x10, 0x10, 0x10, 0x92, 0x7C, 0x10, 0x00, 0x00,
0x00, 0x00, 0x08, 0x04, 0xFE, 0x04, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x40, 0xFE, 0x40, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,
0x00, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x44, 0xFE, 0x44, 0x44, 0x44, 0xFE, 0x44, 0x00, 0x00,
0x00, 0x10, 0x7E, 0x90, 0x7C, 0x12, 0xFC, 0x10, 0x00, 0x00,
0x00, 0x00, 0x04, 0x88, 0x10, 0x22, 0x40, 0x00, 0x00, 0x00,
0x00, 0x38, 0x44, 0x44, 0x78, 0x86, 0x84, 0x7A, 0x00, 0x00,
0x00, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x20, 0x40, 0x40, 0x40, 0x20, 0x10, 0x00, 0x00,
0x00, 0x40, 0x20, 0x10, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
0x00, 0x00, 0x10, 0x54, 0x38, 0x54, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x10, 0x30, 0x50, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x02, 0x7C, 0x80, 0x80, 0xFE, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x02, 0x0C, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x38, 0x48, 0x88, 0x88, 0xFE, 0x08, 0x08, 0x00, 0x00,
0x00, 0xFE, 0x80, 0x80, 0xFE, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x3E, 0x40, 0x80, 0xFC, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFE, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x7C, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x7E, 0x02, 0x02, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x60, 0x00, 0x00,
0x00, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x02, 0x0C, 0x10, 0x00, 0x10, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x9A, 0x9C, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0xFE, 0x80, 0x80, 0xFC, 0x80, 0x80, 0xFE, 0x00, 0x00,
0x00, 0xFE, 0x80, 0x80, 0xFC, 0x80, 0x80, 0x80, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x80, 0x9E, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x84, 0x88, 0x90, 0xE0, 0x90, 0x88, 0x84, 0x00, 0x00,
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFE, 0x00, 0x00,
0x00, 0x82, 0xEE, 0x92, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x82, 0xC2, 0xA2, 0x92, 0x8A, 0x86, 0x82, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0xFC, 0x80, 0x80, 0x80, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x82, 0x92, 0x8A, 0x7C, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0xFC, 0x88, 0x84, 0x82, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x80, 0x7C, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0x82, 0x92, 0x92, 0x6C, 0x00, 0x00,
0x00, 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00,
0x00, 0x82, 0x82, 0x44, 0x28, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0xFE, 0x02, 0x0C, 0x10, 0x60, 0x80, 0xFE, 0x00, 0x00,
0x00, 0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0x78, 0x00, 0x00,
0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00,
0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x00, 0x00,
0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00,
0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x02, 0x7E, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x80, 0x80, 0xFC, 0x82, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x82, 0x80, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x02, 0x02, 0x7E, 0x82, 0x82, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x82, 0xFE, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x30, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7E, 0x82, 0x82, 0x82, 0x7E, 0x02, 0x7C,
0x00, 0x80, 0x80, 0xF8, 0x84, 0x84, 0x84, 0x84, 0x00, 0x00,
0x00, 0x40, 0x00, 0xC0, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00,
0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60,
0x00, 0x80, 0x80, 0x88, 0xB0, 0xC0, 0xB0, 0x88, 0x00, 0x00,
0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00,
0x00, 0x00, 0x00, 0xEC, 0x92, 0x92, 0x92, 0x92, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF8, 0x84, 0x84, 0x84, 0x84, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x82, 0x82, 0x82, 0xFC, 0x80, 0x80,
0x00, 0x00, 0x00, 0x7C, 0x84, 0x84, 0x84, 0x7C, 0x04, 0x3C,
0x00, 0x00, 0x00, 0xB8, 0x44, 0x40, 0x40, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x80, 0x78, 0x04, 0xF8, 0x00, 0x00,
0x00, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x84, 0x84, 0x84, 0x84, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x82, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x82, 0x82, 0x82, 0x92, 0x6C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00, 0x00,
0x00, 0x00, 0x00, 0x84, 0x84, 0x84, 0x84, 0x7C, 0x04, 0xF8,
0x00, 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8, 0x00, 0x00,
0x00, 0x18, 0x20, 0x20, 0x40, 0x20, 0x20, 0x18, 0x00, 0x00,
0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x60, 0x10, 0x10, 0x08, 0x10, 0x10, 0x60, 0x00, 0x00,
0x00, 0x00, 0x72, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0xFE, 0x82, 0x80, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0xFE, 0x62, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00,
0x00, 0xFC, 0x6C, 0x6C, 0x6C, 0x6C, 0x7E, 0x82, 0x00, 0x00,
0x00, 0xFE, 0x80, 0x80, 0xFC, 0x80, 0x80, 0xFE, 0x00, 0x00,
0x00, 0x92, 0x92, 0x7C, 0x10, 0x7C, 0x92, 0x92, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x02, 0x1C, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x8E, 0x92, 0x92, 0x92, 0xE2, 0x82, 0x00, 0x00,
0x00, 0x92, 0xE2, 0x8E, 0x92, 0x92, 0xE2, 0x82, 0x00, 0x00,
0x00, 0x82, 0x8C, 0x90, 0xE0, 0x90, 0x8C, 0x82, 0x00, 0x00,
0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x8C, 0x00, 0x00,
0x00, 0x82, 0xEE, 0x92, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFE, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x82, 0xFC, 0x80, 0x80, 0x80, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7C, 0x00, 0x00,
0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0x6C, 0x10, 0x60, 0x80, 0x00, 0x00,
0x00, 0x7C, 0x10, 0xFE, 0x92, 0xFE, 0x10, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x82, 0x6C, 0x10, 0x6C, 0x82, 0x82, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x02, 0x00, 0x00,
0x00, 0x82, 0x82, 0x82, 0xFE, 0x02, 0x02, 0x1E, 0x00, 0x00,
0x00, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00,
0x00, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x02, 0x00, 0x00,
0x00, 0xE0, 0x60, 0x60, 0x7E, 0x62, 0x62, 0x7E, 0x00, 0x00,
0x00, 0x82, 0x82, 0xE2, 0x92, 0x92, 0x92, 0xF2, 0x00, 0x00,
0x00, 0x80, 0x80, 0xFC, 0x82, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0xFC, 0x82, 0x02, 0x7E, 0x02, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x8C, 0x92, 0x92, 0xF2, 0x92, 0x92, 0x8C, 0x00, 0x00,
0x00, 0x7E, 0x82, 0x82, 0x7E, 0x12, 0x62, 0x82, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x02, 0x7E, 0x82, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x80, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x82, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x7E, 0x6C, 0x6C, 0x6C, 0x7C, 0x82, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x82, 0xFE, 0x80, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x92, 0x7C, 0x10, 0x7C, 0x92, 0x92, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x82, 0x1C, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x82, 0x8E, 0x92, 0xE2, 0x82, 0x82, 0x00, 0x00,
0x00, 0x6C, 0x10, 0x82, 0x8E, 0x92, 0xE2, 0x82, 0x00, 0x00,
0x00, 0x00, 0x82, 0x8C, 0x90, 0xF0, 0x8C, 0x82, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x62, 0x62, 0x62, 0x62, 0xE2, 0x00, 0x00,
0x00, 0x00, 0x82, 0xEE, 0x92, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x82, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7C, 0x44, 0x7C, 0x02, 0x7E, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x44, 0x00, 0x7C, 0x02, 0x7E, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x44, 0x00, 0x7C, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x8C, 0x00, 0xFC, 0x80, 0xF0, 0x80, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x62, 0x7C, 0x62, 0x62, 0xFC, 0x00, 0x00,
0x00, 0x82, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x82, 0x00, 0x7C, 0x82, 0xFE, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x7C, 0x44, 0x7C, 0x82, 0xFE, 0x82, 0x82, 0x00, 0x00,
0x00, 0x82, 0x7C, 0x82, 0x82, 0xFE, 0x82, 0x82, 0x00, 0x00,
0x00, 0x82, 0x7C, 0x82, 0x82, 0x82, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x82, 0x00, 0x82, 0x82, 0x82, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x82, 0xFE, 0x80, 0xF0, 0x80, 0x80, 0xFE, 0x00, 0x00,
0x00, 0x60, 0x10, 0x7C, 0x82, 0xFE, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x0C, 0x10, 0x7C, 0x82, 0xFE, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x10, 0x6C, 0x7C, 0x82, 0xFE, 0x80, 0x7E, 0x00, 0x00,
0x00, 0x60, 0x10, 0x7C, 0x02, 0x7E, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x10, 0x6C, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x10, 0x0C, 0x82, 0x82, 0x82, 0x82, 0x7E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0x80, 0x80, 0x7C, 0x10, 0x00, 0x00,
0x00, 0x7C, 0x82, 0x60, 0xFC, 0x60, 0x60, 0xFE, 0x00, 0x00,
0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0x82, 0xFC, 0x80, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x82, 0x82, 0xFC, 0x80, 0x80, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x82, 0x80, 0x80, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0x6C, 0x10, 0x60, 0x80, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x10, 0xFE, 0xFE, 0x10, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x82, 0x6C, 0x10, 0x6C, 0x82, 0x82, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x02, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0x82, 0xFE, 0x02, 0x1E, 0x00, 0x00,
0x00, 0x00, 0x92, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x92, 0x92, 0x92, 0x92, 0xFE, 0x02, 0x00, 0x00,
0x00, 0x00, 0xE0, 0x60, 0x7C, 0x62, 0x62, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x82, 0x82, 0xE2, 0x92, 0x92, 0xF2, 0x00, 0x00,
0x00, 0x00, 0x80, 0x80, 0xFC, 0x82, 0x82, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x82, 0x1E, 0x02, 0x82, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x8C, 0x92, 0x92, 0xF2, 0x92, 0x8C, 0x00, 0x00,
0x00, 0x00, 0x1E, 0x62, 0x62, 0x1E, 0x12, 0x62, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
StdFont fonts[] = {
{stdfont8x5, 8, 5},
{stdfont10x7, 10, 7}
};
//Returns the width of a given, 0 = invalid font
unsigned int stdfont_getFontWidth(unsigned int fontNumber)
{
if (fontNumber >= STDFONTS)
return 0;
return fonts[fontNumber].charWidth;
}
//Returns the height of a given, 0 = invalid font
unsigned int stdfont_getFontHeight(unsigned int fontNumber)
{
if (fontNumber >= STDFONTS)
return 0;
return fonts[fontNumber].charHeight;
}
//Returns a pointer to the desired font's bitmap representation
unsigned char *stdfont_getBitmap(unsigned int fontNumber)
{
if (fontNumber >= STDFONTS)
return 0;
return (unsigned char *)fonts[fontNumber].fontPtr;
}

27
kernel/video/stdfont.h Normal file
View File

@ -0,0 +1,27 @@
// stdfont.c
// Author: Josh Holtrop
// Created: 02/26/04
// Standard font server
#ifndef __HOS_STDFONT__
#define __HOS_STDFONT__ __HOS_STDFONT__
#define STDFONTS 2
typedef struct {
const unsigned char *fontPtr;
unsigned int charHeight;
unsigned int charWidth;
} StdFont;
//Returns the standard font size, 0 = invalid font
unsigned int stdfont_getFontWidth(unsigned int fontNumber);
//Returns the height of a given, 0 = invalid font
unsigned int stdfont_getFontHeight(unsigned int fontNumber);
//Returns a pointer to the desired font's bitmap representation
unsigned char *stdfont_getBitmap(unsigned int fontNumber);
#endif

265
kernel/video/video.cpp Normal file
View File

@ -0,0 +1,265 @@
// video.c
// 08/13/03 Josh Holtrop
// Modified: 03/08/04
#include "hos_defines.h"
#include "video.h"
#include "video/stdfont.h"
#include "mm/vmm.h"
ModeInfoBlock video_mode;
dword videoMode = 0; //what video mode # we are in, 0 for console mode
word *vid_ptr16 = (word *)0xF0000000;
byte *vid_ptr24 = (byte *)0xF0000000;
dword *vid_ptr32 = (dword *)0xF0000000;
void (*video_psetp)(int, dword) = video_psetpnull; //function pointer to set a pixel
//Initialized the video mode information block video_mode and allocated double-buffer memory for graphics display
void video_init()
{
videoMode = *(word *)BOOT_VIDEO_MODE;
if (!videoMode) //we are in console mode
return;
video_mode = *(ModeInfoBlock *) BOOT_VIDEO_MODE_INFO_BLOCK;
switch(video_mode.BitsPerPixel)
{
case 16:
video_psetp = &video_psetp16;
break;
case 24:
video_psetp = &video_psetp24;
break;
case 32:
video_psetp = &video_psetp32;
}
unsigned int vidPages = video_mode.XResolution * video_mode.YResolution * (video_mode.BitsPerPixel >> 3);
if (vidPages % 4096)
vidPages = (vidPages >> 12) + 1;
else
vidPages = (vidPages >> 12);
vmm_mapn(0xF0000000, video_mode.PhysBasePtr, vidPages);
}
//Renders a character using stdfont[] as a bitmask
void video_renderChar(int x, int y, int character, int font, dword color, int drawBack, dword backColor)
{
int charWidth = stdfont_getFontWidth(font);
if (!charWidth)
return;
int charHeight = stdfont_getFontHeight(font);
int charpos = (character & 0xFF) * charHeight;
byte *charBMP = (byte *)stdfont_getBitmap(font);
int row;
int col;
for (row = 0; row < charHeight; row++)
{
for (col = 0; col < charWidth; col++)
{
if ((charBMP[charpos + row] << col) & 0x80)
video_pset(x + col, y + row, color);
else if (drawBack)
video_pset(x + col, y + row, backColor);
}
}
}
//Draws a horizontal line
void video_horiz(int y, int x1, int x2, dword color)
{
if (x1 > x2)
{
int tmp = x2;
x2 = x1;
x1 = tmp; //x2 >= x1 now
}
if (x2 < 0)
return;
if (x1 >= video_mode.XResolution)
return;
if (x1 < 0)
x1 = 0;
if (x2 >= video_mode.XResolution)
x2 = video_mode.XResolution - 1;
int pixel = y * video_mode.XResolution + x1;
for (; x1 <= x2; x1++)
{
video_psetp(pixel++, color);
}
}
//Draws a single pixel
void video_pset(int x, int y, dword color)
{
if ((x < 0) || (x >= video_mode.XResolution) || (y < 0) || (y >= video_mode.YResolution))
return;
video_psetp(y * video_mode.XResolution + x, color);
}
//Draws a pixel at the specified pixel position
//This function is needed because external modules do not have access to the function pointer video_psetp
void video_pseti(int pixel, dword color)
{
video_psetp(pixel, color);
}
//Draws a vertical line
void video_vert(int x, int y1, int y2, dword color)
{
if (y1 > y2)
{
int tmp = y2;
y2 = y1;
y1 = tmp; //y2 >= y1 now
}
if (y2 < 0)
return;
if (y1 >= video_mode.YResolution)
return;
if (y1 < 0)
y1 = 0;
if (y2 >= video_mode.YResolution)
y2 = video_mode.YResolution - 1;
int pixel = y1 * video_mode.XResolution + x;
for (; y1 <= y2; y1++)
{
video_psetp(pixel, color);
pixel += video_mode.XResolution;
}
}
//Draws a rectangle
void video_rect(int x1, int y1, int x2, int y2, dword color)
{
video_horiz(y1, x1, x2, color);
video_horiz(y2, x1, x2, color);
video_vert(x1, y1, y2, color);
video_vert(x2, y1, y2, color);
}
//Draws a filled rectangle
void video_rectf(int x1, int y1, int x2, int y2, dword color)
{
if (y2 < y1)
{
int tmp = y2;
y2 = y1;
y1 = tmp;
}
for (; y1 <= y2; y1++)
video_horiz(y1, x1, x2, color);
}
//Draws a pixel at the specified pixel position
void video_psetp16(int pixel, dword color)
{
vid_ptr16[pixel] = ((color&0xFF)>>3) | ((((color>>8)&0xFF)>>2)<<5) | ((((color>>16)&0xFF)>>3)<<11);
}
//Draws a pixel at the specified pixel position
void video_psetp24(int pixel, dword color)
{
vid_ptr24[pixel*3] = color & 0xFF;
vid_ptr24[pixel*3+1] = (color>>8) & 0xFF;
vid_ptr24[pixel*3+2] = (color>>16) & 0xFF;
}
//Draws a pixel at the specified pixel position
void video_psetp32(int pixel, dword color)
{
vid_ptr32[pixel] = color;
}
//Dummy function to not draw anything if there is no graphical mode enabled
void video_psetpnull(int pixel, dword color) {}
int video_getWidth()
{
return video_mode.XResolution;
}
int video_getHeight()
{
return video_mode.YResolution;
}
byte video_getBitsPerPixel()
{
return video_mode.BitsPerPixel;
}
dword video_getPhysBasePtr()
{
return video_mode.PhysBasePtr;
}
dword video_Mode()
{
return videoMode;
}
void video_line(int x0, int y0, int x1, int y1, dword color)
{
int dy = y1 - y0;
int dx = x1 - x0;
int stepx, stepy;
if (dy < 0)
{
dy = -dy;
stepy = -1;
}
else
{
stepy = 1;
}
if (dx < 0)
{
dx = -dx;
stepx = -1;
}
else
{
stepx = 1;
}
dy <<= 1; // dy is now 2*dy
dx <<= 1; // dx is now 2*dx
video_pset(x0, y0, color);
if (dx > dy)
{
int fraction = dy - (dx >> 1); // same as 2*dy - dx
while (x0 != x1)
{
if (fraction >= 0)
{
y0 += stepy;
fraction -= dx; // same as fraction -= 2*dx
}
x0 += stepx;
fraction += dy; // same as fraction -= 2*dy
video_pset(x0, y0, color);
}
}
else
{
int fraction = dx - (dy >> 1);
while (y0 != y1)
{
if (fraction >= 0)
{
x0 += stepx;
fraction -= dy;
}
y0 += stepy;
fraction += dx;
video_pset(x0, y0, color);
}
}
}

72
kernel/video/video.h Normal file
View File

@ -0,0 +1,72 @@
// video.h
// 08/18/03 Josh Holtrop
// Modified: 03/08/04
#ifndef __HOS_VIDEO__
#define __HOS_VIDEO__ __HOS_VIDEO__
#include "hos_defines.h"
void video_init();
void video_horiz(int y, int x1, int x2, dword color);
void video_vert(int x, int y1, int y2, dword color);
void video_rect(int x1, int y1, int x2, int y2, dword color);
void video_rectf(int x1, int y1, int x2, int y2, dword color);
void video_pset(int x, int y, dword color);
void video_pseti(int pixel, dword color);
void video_psetp16(int pixel, dword color);
void video_psetp24(int pixel, dword color);
void video_psetp32(int pixel, dword color);
void video_psetpnull(int pixel, dword color);
void video_renderChar(int x, int y, int character, int font, dword color, int drawBack, dword backColor);
int video_getWidth();
int video_getHeight();
byte video_getBitsPerPixel();
dword video_getPhysBasePtr();
dword video_Mode();
void video_line(int x0, int y0, int x1, int y1, dword color);
typedef struct{
word ModeAttributes;
byte WinAAttributes;
byte WinBAttributes;
word WinGranularity;
word WinSize;
word WinASegment;
word WinBSegment;
dword WinFuncPtr;
word BytesPerScanLine;
word XResolution;
word YResolution;
byte XCharSize;
byte YCharSize;
byte NumberOfPlanes;
byte BitsPerPixel;
byte NumberOfBanks;
byte MemoryModel;
byte BankSize;
byte NumberOfImagePages;
byte Reserved1;
byte RedMaskSize;
byte RedFieldPosition;
byte GreenMaskSize;
byte GreenFieldPosition;
byte BlueMaskSize;
byte BlueFieldPosition;
byte RsvdMaskSize;
byte RsvdFieldPosition;
byte DirectColorModeInfo;
dword PhysBasePtr;
dword OffScreenMemOffset;
word OffScreenMemSize;
byte Reserved[206];
} ModeInfoBlock;
#endif

View File

@ -1,89 +1,74 @@
HOS - Holtrop's Operating System
--------------------------------
HOS is (in the process of becoming) a 32-bit, protected mode, graphical, multitasking operating system.
It was written by me, Josh Holtrop, with help from a few others along the way.
Goals: (A = accomplished, P = in progress, T = todo)
----------------------------------------------------
(A) Custom bootloader to load kernel from FAT-formatted boot media, options for video mode/ram disk
(A) Multiboot compliance - kernel can be loaded by GRUB
(A) 32-bit protected mode environment
(A) VESA Support for graphics modes
(A) PS/2 keyboard & mouse drivers
(A) Utilize x86's paging architecture for virtual memory management
(P) Console Manager
(P) VFS abstraction layer for a single file system
(P) ram disk driver
(P) devfs file system driver
(P) ext2 file system support
(T) vfat file system support
(T) Multitasking support
(T) HASH command shell
(T) Window Manager
(T) Various other utilities/applications
(T) Hard Drive (ATA) driver
(T) cdrom (ATAPI) driver
Change Log
----------
0.16
12/16/04 - initrd going to be loaded as a gzipped ext2 image (kernel module) - faster loading!
0.15
07/10/04 - Multiboot support added, loadable by GRUB
0.14
05/21/04 - C++ support in kernel, can use classes & templates
04/04/04 - video_line function for diagonal lines
03/16/04 - new VFS design with support for a loop device
03/01/04 - Thanks to Ben Meyer for helping me get a Makefile working and building on linux to work!
0.13
01/26/04 - functions added to read/write CMOS clock date and time
01/19/04 - fixed bug GDTR/IDTR pointing to physical rather than linear table base address
01/07/04 - fixed bug not reading sectors correctly from floppy
12/28/03 - fixed bug not storing eax on interrupt
12/25/03 - fixed bug in mm_palloc()
12/25/03 - incorporated output functions as regular functions rather than as part of a linked library
12/23/03 - re-written physical memory manager using bitmap instead of stack
12/22/03 - kernel relocated to 3gb linear / 1mb+24kb physical to allow for app. address space
0.12
12/21/03 - sample bmp loader tested, works (tests loading a kernel of size ~ 932kb)
12/20/03 - GDT/IDT now located at 1mb physical, before kernel
10/30/03 - turns floppy motor off
10/30/03 - keyboard LEDs working
10/29/03 - paging functions working
10/15/03 - physical memory management page allocators working
0.11
10/09/03 - PS/2 mouse driver
0.10
09/11/03 - Rewritten C and assembly kernel with VESA GUI mode support, keyboard driver
0.05
05/14/03 - HGUI24/HGUI32 commands finished for testing GUI on both 24bpp and 32bpp graphics cards
05/14/03 - first web release!
0.04
03/09/03 - added VM shortcut command
03/09/03 - press up to fill retrieve last inputted command for Nate Scholten
03/08/03 - press clear to clear console input
03/07/03 - added "shortcut" commands PC, IC, ? for Nate Scholten
03/06/03 - added PROMPTC, INPUTC commands
0.03
12/30/02 - Command Line Interface working, accepting basic commands
0.02
12/11/02 - Assembly bootsector can load stage2 ("console")
0.01
12/01/02 - Real mode assembly bootsector boots from floppy disk successfully
HOS - Holtrop's Operating System
--------------------------------
HOS is a 32-bit, protected mode, graphical, multitasking operating system.
It was written by me, Josh Holtrop, with help from a few others along the way.
Goals: (A = accomplished, P = in progress, T = todo)
----------------------------------------------------
(A) Custom bootloader to load kernel from FAT-formatted boot media, options for video mode/ram disk
(A) 32-bit protected mode environment
(A) VESA Support for graphics modes
(A) PS/2 keyboard & mouse drivers
(A) Utilize x86's paging architecture for virtual memory management
(P) VFS abstraction layer for a single file system
(P) ram disk driver
(P) devfs file system driver
(T) ext2 file system support
(T) vfat file system support
(T) Multitasking support
(T) Console Manager
(T) HASH command shell
(T) Window Manager
(T) Various other utilities/applications
(T) Hard Drive (ATA) driver
(T) cdrom (ATAPI) driver
Change Log
----------
0.14
05/21/04 - C++ support in kernel, can use classes & templates
04/04/04 - video_line function for diagonal lines
03/16/04 - new VFS design with support for a loop device
03/01/04 - Thanks to Ben Meyer for helping me get a Makefile working and building on linux to work!
0.13
01/26/04 - functions added to read/write CMOS clock date and time
01/19/04 - fixed bug GDTR/IDTR pointing to physical rather than linear table base address
01/07/04 - fixed bug not reading sectors correctly from floppy
12/28/03 - fixed bug not storing eax on interrupt
12/25/03 - fixed bug in mm_palloc()
12/25/03 - incorporated output functions as regular functions rather than as part of a linked library
12/23/03 - re-written physical memory manager using bitmap instead of stack
12/22/03 - kernel relocated to 3gb linear / 1mb+24kb physical to allow for app. address space
0.12
12/21/03 - sample bmp loader tested, works (tests loading a kernel of size ~ 932kb
12/20/03 - GDT/IDT now located at 1mb physical, before kernel
10/30/03 - turns floppy motor off
10/30/03 - keyboard LEDs working
10/29/03 - paging functions working
10/15/03 - physical memory management page allocators working
0.11
10/09/03 - PS/2 mouse driver
0.10
09/11/03 - Rewritten C and assembly kernel with VESA GUI mode support, keyboard driver
0.05
05/14/03 - HGUI24/HGUI32 commands finished for testing GUI on both 24bpp and 32bpp graphics cards
05/14/03 - first web release!
0.04
03/09/03 - added VM shortcut command
03/09/03 - press up to fill retrieve last inputted command for Nate Scholten
03/08/03 - press clear to clear console input
03/07/03 - added "shortcut" commands PC, IC, ? for Nate Scholten
03/06/03 - added PROMPTC, INPUTC commands
0.03
12/30/02 - Command Line Interface working, accepting basic commands

46
rscons

File diff suppressed because one or more lines are too long

View File

@ -1,18 +0,0 @@
.global hos_start
.type hos_start, @function
hos_start:
/* Set stack pointer. */
mov $_stack_end, %esp
/* Jump to C. */
push $0
push $0
push $0
push %ebx
call hos_main
cli
1: hlt
jmp 1b
.size hos_start, . - hos_start

116
src/fb.c
View File

@ -1,116 +0,0 @@
#include "fb.h"
#include <stddef.h>
#include "mem.h"
static struct {
uint32_t * addr;
uint32_t width;
uint32_t height;
uint32_t pitch;
} fb;
static inline uint32_t build_pixel(uint8_t r, uint8_t g, uint8_t b)
{
return (r << 16u) | (g << 8u) | b;
}
static inline void fb_set_pixel(int x, int y, uint8_t r, uint8_t g, uint8_t b)
{
fb.addr[fb.pitch * y + x] = build_pixel(r, g, b);
}
void fb_clear(void)
{
memset32(fb.addr, 0u, fb.pitch * fb.height);
}
void fb_init(uint32_t * addr, uint32_t width, uint32_t height, uint32_t pitch)
{
fb.addr = addr;
fb.width = width;
fb.height = height;
fb.pitch = pitch / 4u;
fb_clear();
}
uint32_t * fb_addr(void)
{
return fb.addr;
}
bool fb_ready(void)
{
return fb.addr != NULL;
}
uint32_t fb_width(void)
{
return fb.width;
}
uint32_t fb_height(void)
{
return fb.height;
}
void fb_blend_alpha8(const uint8_t * bitmap, int width, int height, int pitch, int x, int y, uint8_t r, uint8_t g, uint8_t b)
{
if (((x + width) <= 0) || (x >= (int)fb.width) || ((y + height) <= 0) || (y >= (int)fb.height))
{
return;
}
if (x < 0)
{
width += x;
bitmap += (-x);
x = 0;
}
if (y < 0)
{
height += y;
bitmap += ((-y) * pitch);
y = 0;
}
if ((x + width) > (int)fb.width)
{
width = (int)fb.width - x;
}
if ((y + height) > (int)fb.height)
{
height = (int)fb.height - y;
}
uint32_t * target = &fb.addr[fb.pitch * y + x];
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
uint32_t alpha = bitmap[col];
uint32_t current_pixel = target[col];
uint8_t cr = (current_pixel >> 16u) & 0xFFu;
uint8_t cg = (current_pixel >> 8u) & 0xFFu;
uint8_t cb = current_pixel & 0xFFu;
uint8_t pr = alpha * r / 255u;
uint8_t pg = alpha * g / 255u;
uint8_t pb = alpha * b / 255u;
uint32_t current_alpha = 255u - alpha;
uint32_t pixel = build_pixel(
pr + current_alpha * cr / 255u,
pg + current_alpha * cg / 255u,
pb + current_alpha * cb / 255u);
target[col] = pixel;
}
bitmap += pitch;
target += fb.pitch;
}
}
void fb_fill(int x, int y, int width, int height, uint8_t r, uint8_t g, uint8_t b)
{
uint32_t * target = &fb.addr[fb.pitch * y + x];
uint32_t pixel = build_pixel(r, g, b);
for (int row = 0; row < height; row++)
{
memset32(target, pixel, width);
target += fb.pitch;
}
}

View File

@ -1,16 +0,0 @@
#ifndef FB_H
#define FB_H
#include <stdint.h>
#include <stdbool.h>
void fb_init(uint32_t * addr, uint32_t width, uint32_t height, uint32_t pitch);
bool fb_ready(void);
uint32_t * fb_addr(void);
uint32_t fb_width(void);
uint32_t fb_height(void);
void fb_blend_alpha8(const uint8_t * bitmap, int width, int height, int pitch, int x, int y, uint8_t r, uint8_t g, uint8_t b);
void fb_fill(int x, int y, int width, int height, uint8_t r, uint8_t g, uint8_t b);
void fb_clear(void);
#endif

View File

@ -1,11 +0,0 @@
#include "fb_text.h"
#include "kfont.h"
#include "fb.h"
void fb_text_render_char(int c, int x, int y, uint8_t r, uint8_t g, uint8_t b)
{
const fontgen_char_info_t * char_info = kfont.char_infos[c];
y += kfont.line_height - kfont.baseline_offset - char_info->top;
x += char_info->left;
fb_blend_alpha8(char_info->bitmap, char_info->width, char_info->height, char_info->width, x, y, r, g, b);
}

View File

@ -1,8 +0,0 @@
#ifndef FB_TEXT_H
#define FB_TEXT_H
#include <stdint.h>
void fb_text_render_char(int c, int x, int y, uint8_t r, uint8_t g, uint8_t b);
#endif

View File

@ -1,16 +0,0 @@
.global gdt_set
.extern gdtr
.type gdt_set, @function
gdt_set:
lgdt gdtr
jmp $0x8, $gdt_set_reload
gdt_set_reload:
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
ret
.size gdt_set, . - gdt_set

View File

@ -1,20 +0,0 @@
#include "gdt.h"
static const gdt_entry_t gdt_entries[] = {
/* Null descriptor */
0u,
/* Code segment for kernel */
gdt_build_entry(0u, 0xFFFFFu, 1u, 0u, 1u, 1u, 0u, 1u, 0u, 1u, 1u, 0u),
/* Data segment for kernel */
gdt_build_entry(0u, 0xFFFFFu, 1u, 0u, 1u, 0u, 0u, 1u, 0u, 1u, 1u, 0u),
};
gdtr_t gdtr;
void gdt_init(void)
{
gdtr.size = sizeof(gdt_entries);
gdtr.offset_lower = (uintptr_t)gdt_entries & 0xFFFFu;
gdtr.offset_upper = (uintptr_t)gdt_entries >> 16u;
gdt_set();
}

View File

@ -1,34 +0,0 @@
#ifndef GDT_H
#define GDT_H
#include <stdint.h>
typedef struct {
uint16_t size;
uint16_t offset_lower;
uint16_t offset_upper;
uint16_t _reserved;
} gdtr_t;
typedef uint64_t gdt_entry_t;
#define gdt_build_entry(base, limit, pr, privl, s, ex, dc, rw, ac, gr, sz, l) \
(gdt_entry_t)( \
(((gdt_entry_t)base << 32) & 0xFF00000000000000ull) | /* Base 0:15 */ \
(((gdt_entry_t)gr & 0x1u) << 55) | /* Granularity (0 = bytes, 1 = blocks) */ \
(((gdt_entry_t)sz & 0x1u) << 54) | /* Size (0 = 16-bit, 1 = 32-bit) */ \
(((gdt_entry_t)l & 0x1u) << 53) | /* L flag (x86_64 code) */ \
(((gdt_entry_t)limit << 32) & 0x000F000000000000ull) | /* Limit 16:19 */ \
(((gdt_entry_t)pr & 0x1u) << 47) | /* Present flag */ \
(((gdt_entry_t)privl & 0x3u) << 45) | /* Privilege (ring level) */ \
(((gdt_entry_t)s & 0x1u) << 44) | /* Type (0 = system, 1 = code/data) */ \
(((gdt_entry_t)ex & 0x1u) << 43) | /* Executable flag */ \
(((gdt_entry_t)dc & 0x1u) << 42) | /* Direction/Conforming */ \
(((gdt_entry_t)rw & 0x1u) << 41) | /* Readable/Writable */ \
(((gdt_entry_t)ac & 0x1u) << 40) | /* Accessed flag */ \
(((gdt_entry_t)base << 16) & 0x000000FFFFFF0000ull) | /* Base 0:23 */ \
((gdt_entry_t)limit & 0x000000000000FFFFull)) /* Limit 0:15 */
void gdt_init(void);
void gdt_set(void);
#endif

View File

@ -1,25 +0,0 @@
#include <stdint.h>
#include "fb.h"
#include "mbinfo.h"
#include "klog.h"
#include "gdt.h"
#include "mm.h"
void hos_main(uint32_t mbinfo_addr)
{
gdt_init();
if (!mbinfo_init(mbinfo_addr))
{
return;
}
if (!fb_ready())
{
return;
}
klog_init();
klog_printf("Welcome to HOS!\n");
mm_init();
mbinfo_load();
klog_printf("Found %dKB of usable RAM\n", mm_get_total_ram() / 1024u);
klog_printf("Kernel is %dKB at 0x%x\n", mm_get_kernel_size() / 1024u, mm_get_kernel_address());
}

View File

@ -1,281 +0,0 @@
#include "hos_printf.h"
#include <stdint.h>
#include <stdbool.h>
#include "string.h"
static size_t format_dec(char * buffer, int32_t v)
{
size_t sz = 0u;
bool printing = false;
if (v < 0)
{
buffer[sz++] = '-';
v = -v;
}
for (int32_t div = 1000000000; div >= 1; div /= 10)
{
int32_t digit = v / div;
v %= div;
if ((digit != 0) || (div == 1))
{
printing = true;
}
if (printing)
{
buffer[sz++] = digit + '0';
}
}
return sz;
}
static size_t format_dec64(char * buffer, int64_t v)
{
size_t sz = 0u;
bool printing = false;
if (v < 0)
{
buffer[sz++] = '-';
v = -v;
}
for (int64_t div = 1000000000000000000; div >= 1; div /= 10)
{
int64_t digit = v / div;
v %= div;
if ((digit != 0) || (div == 1))
{
printing = true;
}
if (printing)
{
buffer[sz++] = digit + '0';
}
}
return sz;
}
static size_t format_udec(char * buffer, int32_t v)
{
size_t sz = 0u;
for (int32_t div = 1000000000u; div >= 1u; div /= 10u)
{
int32_t digit = v / div;
v %= div;
if ((digit != 0) || (sz > 0u) || (div == 1))
{
buffer[sz++] = digit + '0';
}
}
return sz;
}
static size_t format_udec64(char * buffer, uint64_t v)
{
size_t sz = 0u;
for (uint64_t div = 10000000000000000000u; div >= 1u; div /= 10u)
{
uint64_t digit = v / div;
v %= div;
if ((digit != 0) || (sz > 0u) || (div == 1))
{
buffer[sz++] = digit + '0';
}
}
return sz;
}
static size_t format_hex(char * buffer, uint32_t v, bool upper)
{
const char upper_hex[] = "0123456789ABCDEF";
const char lower_hex[] = "0123456789abcdef";
size_t sz = 0u;
for (int i = 28; i >= 0; i -= 4)
{
uint8_t n = (v >> i) & 0xFu;
if ((sz > 0u) || (n != 0u) || (i == 0))
{
buffer[sz] = upper ? upper_hex[n] : lower_hex[n];
sz++;
}
}
return sz;
}
static size_t format_hex64(char * buffer, uint64_t v, bool upper)
{
const char upper_hex[] = "0123456789ABCDEF";
const char lower_hex[] = "0123456789abcdef";
size_t sz = 0u;
for (int i = 60; i >= 0; i -= 4)
{
uint8_t n = (v >> i) & 0xFu;
if ((sz > 0u) || (n != 0u) || (i == 0))
{
buffer[sz] = upper ? upper_hex[n] : lower_hex[n];
sz++;
}
}
return sz;
}
static void pad_write(const stream_t * stream, const char * data, size_t length, bool leading_zero, bool left_just, size_t width)
{
if (left_just)
{
stream->write(data, length);
while (length < width)
{
stream->write1(' ');
length++;
}
}
else
{
char fill = leading_zero ? '0' : ' ';
size_t l = length;
while (l < width)
{
stream->write1(fill);
l++;
}
stream->write(data, length);
}
}
void hos_vprintf(const stream_t * stream, const char * fmt, va_list va)
{
bool in_conv = false;
char c;
char buffer[22];
size_t width;
bool leading_zero;
bool left_just;
bool long_flag;
size_t length;
while ((c = *fmt))
{
if (in_conv)
{
switch (c)
{
case '%':
stream->write1('%');
break;
case 'X':
{
if (long_flag)
{
uint64_t v = va_arg(va, uint64_t);
length = format_hex(buffer, v, true);
}
else
{
uint32_t v = va_arg(va, uint32_t);
length = format_hex(buffer, v, true);
}
pad_write(stream, buffer, length, leading_zero, left_just, width);
}
break;
case 'c':
{
char ch = va_arg(va, int);
pad_write(stream, &ch, 1u, leading_zero, left_just, width);
}
break;
case 'd':
{
if (long_flag)
{
int64_t v = va_arg(va, int64_t);
length = format_dec64(buffer, v);
}
else
{
int32_t v = va_arg(va, int32_t);
length = format_dec(buffer, v);
}
pad_write(stream, buffer, length, leading_zero, left_just, width);
}
break;
case 's':
{
const char * s = va_arg(va, const char *);
pad_write(stream, s, strlen(s), leading_zero, left_just, width);
}
break;
case 'u':
{
if (long_flag)
{
uint64_t v = va_arg(va, uint64_t);
length = format_udec64(buffer, v);
}
else
{
uint32_t v = va_arg(va, uint32_t);
length = format_udec(buffer, v);
}
pad_write(stream, buffer, length, leading_zero, left_just, width);
}
break;
case 'x':
{
if (long_flag)
{
uint64_t v = va_arg(va, uint64_t);
length = format_hex64(buffer, v, false);
}
else
{
uint32_t v = va_arg(va, uint32_t);
length = format_hex(buffer, v, false);
}
pad_write(stream, buffer, length, leading_zero, left_just, width);
}
break;
}
in_conv = false;
}
else if (c == '%')
{
in_conv = true;
width = 0u;
leading_zero = false;
left_just = false;
long_flag = false;
if (fmt[1] == '-')
{
left_just = true;
fmt++;
}
if (fmt[1] == '0')
{
leading_zero = true;
fmt++;
}
while (('0' <= fmt[1]) && (fmt[1] <= '9'))
{
width *= 10u;
width += (fmt[1] - '0');
fmt++;
}
if (fmt[1] == 'l')
{
long_flag = true;
fmt++;
}
}
else
{
stream->write1(c);
}
fmt++;
}
}
void hos_printf(const stream_t * stream, const char * fmt, ...)
{
va_list va;
va_start(va, fmt);
hos_vprintf(stream, fmt, va);
va_end(va);
}

View File

@ -1,10 +0,0 @@
#ifndef HOS_PRINTF_H
#define HOS_PRINTF_H
#include "stream.h"
#include <stdarg.h>
void hos_vprintf(const stream_t * stream, const char * fmt, va_list va);
void hos_printf(const stream_t * stream, const char * fmt, ...);
#endif

View File

@ -1,103 +0,0 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdarg.h>
#include "klog.h"
#include "kfont.h"
#include "fb.h"
#include "fb_text.h"
#include "stream.h"
#include "hos_printf.h"
#include "mem.h"
static struct {
size_t console_width;
size_t console_height;
size_t x;
size_t y;
bool need_shift;
} klog;
static void shift_line(void)
{
uint32_t * fb = fb_addr();
uint32_t w = fb_width();
size_t console_fb_line_words = w * kfont.line_height;
for (size_t row = 0u; row < klog.console_height; row++)
{
memcpy32(fb, fb + console_fb_line_words, console_fb_line_words);
fb += console_fb_line_words;
}
fb_fill(0, kfont.line_height * (klog.console_height - 1u), w, kfont.line_height, 0u, 0x2Cu, 0x55u);
}
static void klog_fb_write1(char c)
{
if (klog.need_shift)
{
shift_line();
klog.need_shift = false;
}
if (c == '\n')
{
if (klog.y == (klog.console_height - 1u))
{
klog.need_shift = true;
}
else
{
klog.y++;
}
klog.x = 0u;
}
else
{
int px = klog.x * kfont.advance;
int py = klog.y * kfont.line_height;
fb_text_render_char(c, px, py, 0xFFu, 0x80u, 0u);
klog.x++;
if (klog.x == klog.console_width)
{
if (klog.y == (klog.console_height - 1u))
{
klog.need_shift = true;
}
else
{
klog.y++;
}
klog.x = 0u;
}
}
}
static void klog_fb_write(const char * src, size_t length)
{
for (size_t i = 0u; i < length; i++)
{
klog_fb_write1(src[i]);
}
}
static const stream_t klog_fb_stream = {
klog_fb_write,
klog_fb_write1,
};
void klog_init(void)
{
klog.console_width = fb_width() / kfont.advance;
klog.console_height = fb_height() / kfont.line_height;
klog.x = 0u;
klog.y = 0u;
klog.need_shift = false;
fb_fill(0, 0, fb_width(), fb_height(), 0u, 0x2Cu, 0x55u);
}
void klog_printf(const char * fmt, ...)
{
va_list va;
va_start(va, fmt);
hos_vprintf(&klog_fb_stream, fmt, va);
va_end(va);
}

View File

@ -1,7 +0,0 @@
#ifndef KLOG_H
#define KLOG_H
void klog_init(void);
void klog_printf(const char * fmt, ...);
#endif

View File

@ -1,41 +0,0 @@
ENTRY(hos_start)
SECTIONS
{
. = 1M;
_hos_mem_start = .;
.text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
_stack_size = 16K;
.stack (NOLOAD) : ALIGN(4K)
{
_stack_start = .;
. = . + _stack_size;
_stack_end = .;
}
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
. = ALIGN(4K);
_hos_mem_end = .;
}

View File

@ -1,100 +0,0 @@
#include "multiboot2.h"
#include "fb.h"
#include "mem.h"
#include <stdint.h>
#include "klog.h"
#include "mm.h"
static uint32_t mbinfo[2048];
static void mbinfo_process_tag(const multiboot2_info_tag_t * tag)
{
switch (tag->type)
{
case MULTIBOOT2_INFO_BOOT_COMMAND_LINE:
{
multiboot2_info_boot_command_line_t * cl =
(multiboot2_info_boot_command_line_t *)tag;
klog_printf("Kernel boot command line: '%s'\n", cl->string);
}
break;
case MULTIBOOT2_INFO_BOOT_LOADER_NAME:
{
multiboot2_info_boot_loader_name_t * bln =
(multiboot2_info_boot_loader_name_t *)tag;
klog_printf("Boot loader: '%s'\n", bln->string);
}
break;
case MULTIBOOT2_INFO_MEMORY_MAP:
{
multiboot2_info_memory_map_t * mmap_info =
(multiboot2_info_memory_map_t *)tag;
size_t sz = sizeof(mmap_info->header) +
sizeof(mmap_info->entry_size) +
sizeof(mmap_info->entry_version);
multiboot2_info_memory_map_entry_t * entry = &mmap_info->entries[0];
for (;;)
{
sz += mmap_info->entry_size;
if (sz > mmap_info->header.size)
{
break;
}
if (entry->type == MULTIBOOT2_MEMORY_MAP_TYPE_RAM)
{
klog_printf("Memory region %16lx : %16lx\n",
entry->base_addr,
entry->length);
mm_register_ram_region(entry->base_addr, entry->length);
}
entry = (multiboot2_info_memory_map_entry_t *)((uintptr_t)entry + mmap_info->entry_size);
}
}
break;
case MULTIBOOT2_INFO_FRAMEBUFFER_INFO:
{
multiboot2_info_framebuffer_info_t * fbinfo =
(multiboot2_info_framebuffer_info_t *)tag;
fb_init((uint32_t *)(uintptr_t)fbinfo->framebuffer_addr,
fbinfo->framebuffer_width,
fbinfo->framebuffer_height,
fbinfo->framebuffer_pitch);
}
break;
}
}
static void process_tags(const multiboot2_info_tag_t * tag, bool init)
{
while (tag->type != 0u)
{
if ((init && (tag->type == MULTIBOOT2_INFO_FRAMEBUFFER_INFO)) ||
(!init && (tag->type != MULTIBOOT2_INFO_FRAMEBUFFER_INFO)))
{
mbinfo_process_tag(tag);
}
tag = multiboot2_info_next_tag(tag);
}
}
bool mbinfo_init(uint32_t mbinfo_addr)
{
multiboot2_info_header_t * mbinfo_header = (multiboot2_info_header_t *)mbinfo_addr;
if (mbinfo_header->total_size <= sizeof(mbinfo))
{
memcpy32(mbinfo, mbinfo_header, mbinfo_header->total_size / 4u);
multiboot2_info_tag_t * tag = (multiboot2_info_tag_t *)(mbinfo + sizeof(multiboot2_info_header_t) / 4u);
process_tags(tag, true);
return true;
}
return false;
}
void mbinfo_load(void)
{
multiboot2_info_tag_t * tag = (multiboot2_info_tag_t *)(mbinfo + sizeof(multiboot2_info_header_t) / 4u);
process_tags(tag, false);
}

View File

@ -1,10 +0,0 @@
#ifndef MBINFO_H
#define MBINFO_H
#include <stdint.h>
#include <stdbool.h>
bool mbinfo_init(uint32_t mbinfo_addr);
void mbinfo_load(void);
#endif

View File

@ -1,49 +0,0 @@
#ifndef MEM_H
#define MEM_H
#include <stddef.h>
static inline void memcpy(void * dest, const void * src, size_t n)
{
uint32_t r0, r1, r2;
__asm__ __volatile__ (
"cld\n\t"
"rep movsb"
: "=&c" (r0), "=&S" (r1), "=&D" (r2)
: "2" (dest), "1" (src), "0" (n)
: "memory");
}
static inline void memcpy32(void * dest, const void * src, size_t count)
{
uint32_t r0, r1, r2;
__asm__ __volatile__ (
"cld\n\t"
"rep movsd"
: "=&c" (r0), "=&S" (r1), "=&D" (r2)
: "2" (dest), "1" (src), "0" (count)
: "memory");
}
static inline void * memmove(void * dest, const void * src, size_t count)
{
return __builtin_memmove(dest, src, count);
}
static inline void * memset(void * dest, int val, size_t count)
{
return __builtin_memset(dest, val, count);
}
static inline void memset32(void * dest, uint32_t val, size_t count)
{
uint32_t r0, r1;
__asm__ __volatile__ (
"cld\n\t"
"rep stosl"
: "=&c" (r0), "=&D" (r1)
: "a" (val), "1" (dest), "0" (count)
: "memory");
}
#endif

View File

@ -1,91 +0,0 @@
#include "mm.h"
typedef struct mm_page_entry_s {
size_t count;
struct mm_page_entry_s * next;
} mm_region_entry_t;
static mm_region_entry_t * mm_next_free_region;
static size_t mm_free_pages;
static size_t mm_total_ram;
static size_t kernel_start_address;
static size_t kernel_size;
extern uint8_t _hos_mem_start;
extern uint8_t _hos_mem_end;
static void mm_add_ram_region(size_t base, size_t size)
{
mm_region_entry_t * region = (mm_region_entry_t *)base;
size_t pages = size / PAGE_SIZE;
region->count = pages;
region->next = mm_next_free_region;
mm_next_free_region = region;
mm_total_ram += size;
mm_free_pages = pages;
}
void mm_register_ram_region(uint64_t base, size_t size)
{
/* Ignore any RAM region above 4GB. */
if (base >= 0x100000000ull)
{
return;
}
if ((base + size) > 0x100000000ull)
{
size = (size_t)(0x100000000ull - base);
}
size_t end_address = mm_page_floor((size_t)base + size);
size_t start_address = mm_page_ceil(base);
size = end_address - start_address;
if (size < PAGE_SIZE)
{
return;
}
size_t kernel_end_address = kernel_start_address + kernel_size;
/* Add regions before and after kernel RAM. */
if (start_address < kernel_start_address)
{
/* RAM region begins before kernel RAM. */
size_t this_sz = size;
if ((start_address + this_sz) > kernel_start_address)
{
this_sz = kernel_start_address - start_address;
}
mm_add_ram_region(start_address, this_sz);
}
if ((start_address + size) > kernel_end_address)
{
/* RAM region ends after kernel RAM. */
size_t this_sz = size;
if (start_address < kernel_end_address)
{
this_sz = (start_address + size) - kernel_end_address;
start_address = kernel_end_address;
}
mm_add_ram_region(start_address, this_sz);
}
}
void mm_init(void)
{
kernel_start_address = mm_page_floor((size_t)&_hos_mem_start);
kernel_size = mm_page_ceil((size_t)&_hos_mem_end - kernel_start_address);
mm_total_ram = kernel_size;
}
size_t mm_get_total_ram(void)
{
return mm_total_ram;
}
size_t mm_get_kernel_address(void)
{
return kernel_start_address;
}
size_t mm_get_kernel_size(void)
{
return kernel_size;
}

View File

@ -1,25 +0,0 @@
#ifndef MM_H
#define MM_H
#include <stdint.h>
#include <stddef.h>
#define PAGE_SIZE 4096u
static inline size_t mm_page_floor(size_t bytes)
{
return bytes & ~(PAGE_SIZE - 1u);
}
static inline size_t mm_page_ceil(size_t bytes)
{
return (bytes + PAGE_SIZE - 1u) & ~(PAGE_SIZE - 1u);
}
void mm_init(void);
void mm_register_ram_region(uint64_t base, size_t size);
size_t mm_get_total_ram(void);
size_t mm_get_kernel_address(void);
size_t mm_get_kernel_size(void);
#endif

View File

@ -1,127 +0,0 @@
#ifndef MULTIBOOT2_H
#define MULTIBOOT2_H
#include <stdint.h>
#define MULTIBOOT2_MAGIC 0xE85250D6u
#define MULTIBOOT2_ARCHITECTURE_I386 0u
typedef struct {
uint32_t magic;
uint32_t architecture;
uint32_t header_length;
uint32_t checksum;
} multiboot2_header_t;
#define multiboot2_header(magic, architecture, header_length) \
{(magic), (architecture), (header_length), (uint32_t)(0x100000000u - (magic) - (architecture) - (header_length))}
#define multiboot2_header_default() \
multiboot2_header(MULTIBOOT2_MAGIC, MULTIBOOT2_ARCHITECTURE_I386, sizeof(multiboot2_header_t))
typedef struct {
uint16_t type;
uint16_t flags;
uint32_t size;
} multiboot2_tag_t;
#define multiboot2_end_tag() {0u, 0u, 8u}
typedef struct {
multiboot2_tag_t header;
uint32_t width;
uint32_t height;
uint32_t depth;
uint32_t _padding;
} multiboot2_framebuffer_tag_t;
#define multiboot2_framebuffer_tag(width, height, depth) \
{{5u, 0u, 20u}, width, height, depth}
#define MULTIBOOT2_INFO_TAG_ALIGNMENT 8u
#define MULTIBOOT2_INFO_BOOT_COMMAND_LINE 1u
#define MULTIBOOT2_INFO_BOOT_LOADER_NAME 2u
#define MULTIBOOT2_INFO_MODULES 3u
#define MULTIBOOT2_INFO_BASIC_MEMORY_INFO 4u
#define MULTIBOOT2_INFO_BIOS_BOOT_DEVICE 5u
#define MULTIBOOT2_INFO_MEMORY_MAP 6u
#define MULTIBOOT2_INFO_VBE_INFO 7u
#define MULTIBOOT2_INFO_FRAMEBUFFER_INFO 8u
#define MULTIBOOT2_INFO_ELF_SYMBOLS 9u
#define MULTIBOOT2_INFO_APM_TABLE 10u
#define MULTIBOOT2_INFO_EFI_32BIT_SYSTEM_TABLE_POINTER 11u
#define MULTIBOOT2_INFO_EFI_64BIT_SYSTEM_TABLE_POINTER 12u
#define MULTIBOOT2_INFO_SMBIOS_TABLES 13u
#define MULTIBOOT2_INFO_ACPI_OLD_RSDP 14u
#define MULTIBOOT2_INFO_NETWORKING_INFO 16u
#define MULTIBOOT2_INFO_EFI_MEMORY_MAP 17u
#define MULTIBOOT2_INFO_EFI_BOOT_SERVICES_NOT_TERMINATED 18u
#define MULTIBOOT2_INFO_EFI_32BIT_IMAGE_HANDLE_POINTER 19u
#define MULTIBOOT2_INFO_EFI_64BIT_IMAGE_HANDLE_POINTER 20u
#define MULTIBOOT2_INFO_IMAGE_LOAD_BASE_PHYSICAL_ADDRESS 21u
typedef struct {
uint32_t total_size;
uint32_t _reserved;
} multiboot2_info_header_t;
typedef struct {
uint32_t type;
uint32_t size;
} multiboot2_info_tag_t;
#define multiboot2_info_next_tag(current_tag) \
(multiboot2_info_tag_t *)(((uintptr_t)current_tag + current_tag->size + MULTIBOOT2_INFO_TAG_ALIGNMENT - 1u) & ~(MULTIBOOT2_INFO_TAG_ALIGNMENT - 1u))
typedef struct {
multiboot2_info_tag_t header;
char string[];
} multiboot2_info_boot_command_line_t;
typedef struct {
multiboot2_info_tag_t header;
char string[];
} multiboot2_info_boot_loader_name_t;
typedef struct {
multiboot2_info_tag_t header;
uint32_t mem_lower;
uint32_t mem_upper;
} multiboot2_info_basic_memory_info_t;
#define MULTIBOOT2_MEMORY_MAP_TYPE_RAM 1u
#define MULTIBOOT2_MEMORY_MAP_TYPE_ACPI 3u
#define MULTIBOOT2_MEMORY_MAP_TYPE_PRESERVE 4u
#define MULTIBOOT2_MEMORY_MAP_TYPE_DEFECTIVE 5u
typedef struct {
uint64_t base_addr;
uint64_t length;
uint32_t type;
uint32_t _reserved;
} multiboot2_info_memory_map_entry_t;
typedef struct {
multiboot2_info_tag_t header;
uint32_t entry_size;
uint32_t entry_version;
multiboot2_info_memory_map_entry_t entries[];
} multiboot2_info_memory_map_t;
typedef struct {
multiboot2_info_tag_t header;
uint16_t vbe_mode;
uint16_t vbe_interface_set;
uint16_t vbe_interface_off;
uint16_t vbe_interface_len;
uint8_t vbe_control_info[512];
uint8_t vbe_mode_info[256];
} multiboot2_info_vbe_info_t;
typedef struct {
multiboot2_info_tag_t header;
uint64_t framebuffer_addr;
uint32_t framebuffer_pitch;
uint32_t framebuffer_width;
uint32_t framebuffer_height;
uint8_t framebuffer_bpp;
uint8_t framebuffer_type;
uint8_t _reserved;
} multiboot2_info_framebuffer_info_t;
#endif

View File

@ -1,12 +0,0 @@
#include "multiboot2.h"
/* Multiboot2 Header. */
struct {
multiboot2_header_t header;
multiboot2_framebuffer_tag_t framebuffer_tag;
multiboot2_tag_t end_tag;
} multiboot_header __attribute__((section(".multiboot"))) = {
multiboot2_header_default(),
multiboot2_framebuffer_tag(1600u, 900u, 32u),
multiboot2_end_tag(),
};

View File

@ -1,12 +0,0 @@
#ifndef STREAM_H
#define STREAM_H
#include <stddef.h>
#include <stdint.h>
typedef struct {
void (*write)(const char * src, size_t length);
void (*write1)(char c);
} stream_t;
#endif

View File

@ -1,26 +0,0 @@
#ifndef STRING_H
#define STRING_H
#include <stddef.h>
static inline size_t strlen(const char * s)
{
size_t r = 0u;
while (*s++ != (char)0)
{
r++;
}
return r;
}
static inline char * strcpy(char * dest, const char * src)
{
return __builtin_strcpy(dest, src);
}
static inline char * strncpy(char * dest, const char * src, size_t n)
{
return __builtin_strncpy(dest, src, n);
}
#endif