misaka: initial merge

This commit is contained in:
K. Lange 2021-05-31 10:47:02 +09:00
parent 229c4f9631
commit b35f7ac8c9
317 changed files with 12311 additions and 24364 deletions

View File

@ -8,37 +8,19 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: true - name: Clone Kuroko
uses: actions/checkout@v2
with:
repository: kuroko-lang/kuroko
path: kuroko
- name: Pull Builder Image - name: Pull Builder Image
run: docker pull toaruos/build-tools:1.8.x run: docker pull toaruos/build-tools:1.99.x
- name: Run Builder - name: Run Builder
run: docker run -v ${GITHUB_WORKSPACE}:/root/toaruos -w /root/toaruos -e LANG=C.UTF-8 -t toaruos/build-tools:1.8.x util/build-in-docker.sh run: docker run -v ${GITHUB_WORKSPACE}:/root/misaka -w /root/misaka -e LANG=C.UTF-8 -t toaruos/build-tools:1.99.x util/build-in-docker.sh
- name: Upload Branch Image - name: Upload Branch Image
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: image name: build
path: ./image.iso path: |
- name: Draft Release notes ramdisk.tar
if: startsWith(github.ref, 'refs/tags/v') misaka-kernel
run: bash util/generate-release-notes.sh > notes.md
- name: Create Release
if: startsWith(github.ref, 'refs/tags/v')
uses: actions/create-release@v1
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ToaruOS ${{ github.ref }}
body_path: ./notes.md
draft: true
- name: Upload Release Image
if: startsWith(github.ref, 'refs/tags/v')
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./image.iso
asset_name: image.iso
asset_content_type: application/x-iso9660-image

96
.gitignore vendored
View File

@ -1,80 +1,28 @@
*.so *.aux
*.a *.idx
*.ilg
*.ind
*.log
*.o *.o
*.iso *.a
*.efi *.out
*.pdf
*.so
*.swp
*.swn
*.toc
*.ko
*.pcap
.gdb_history .gdb_history
/tags /ramdisk.tar
/ramdisk.igz
/.make/* /misaka-kernel.64
/base/bin/* /misaka-kernel
/base/lib/kuroko /kernel/symbols.S
/base/src
/_base
/cdrom/extra
/cdrom/kernel
/cdrom/netinit
/cdrom/mod/*
/cdrom/ramdisk.img
/cdrom/ramdisk.igz
/cdrom/boot.sys
/cdrom/fat.img
/fatbase/extra
/fatbase/kernel
/fatbase/netinit
/fatbase/mod/*
/fatbase/ramdisk.img
/fatbase/ramdisk.igz
/fatbase/efi/boot/bootia32.efi
/util/tarballs
/util/build /util/build
/util/local /util/local
/util/devtable /util/cross
/util/tmp-gcc /base/bin/*
/util/kuroko
/kernel/symbols.S
/base/usr/python
/base/usr/bin/* /base/usr/bin/*
/base/usr/lib/* /base/usr/lib/*
/base/usr/share/python-demos /.make/
# Generic
/base/usr/share/aclocal
/base/usr/share/gtk-doc
/base/usr/share/man
/base/usr/share/info/
/base/usr/share/doc/
/base/usr/local
# GMP
/base/usr/include/gmp.h
# MPFR
/base/usr/include/mpf2mpfr.h
/base/usr/include/mpfr.h
# MPC
/base/usr/include/mpc.h
# zlib
/base/usr/include/zconf.h
/base/usr/include/zlib.h
/util/ungz
# binutils
/base/usr/i686-pc-toaru
# Freetype
/base/usr/include/freetype2
/base/usr/include/ft2build.h
/base/usr/share/fonts
# Cairo + Pixman
/base/usr/include/cairo
/base/usr/include/pixman-1
# SDL
/base/usr/include/SDL
# Kuroko build files
/base/usr/share/kuroko

8
.gitmodules vendored
View File

@ -1,3 +1,9 @@
[submodule "util/binutils-gdb"]
path = util/binutils-gdb
url = ../../toaruos/binutils-gdb.git
[submodule "util/gcc"]
path = util/gcc
url = ../../toaruos/gcc
[submodule "kuroko"] [submodule "kuroko"]
path = kuroko path = kuroko
url = git@github.com:kuroko-lang/kuroko url = ../../kuroko-lang/kuroko

550
Makefile
View File

@ -1,170 +1,190 @@
ifeq ($(TOOLCHAIN),) TOOLCHAIN=util
ifeq ($(shell util/check.sh),y) BASE=base
export PATH := $(shell util/activate.sh) export PATH := $(shell $(TOOLCHAIN)/activate.sh)
else
FOO := $(shell util/prompt.sh)
ifeq ($(shell util/check.sh),y)
export PATH := $(shell util/activate.sh)
else
$(error "No toolchain, and you did not ask to build it.")
endif
endif
endif
# Prevents Make from removing intermediary files on failure include build/x86_64.mk
.SECONDARY:
# Disable built-in rules CC = ${TARGET}-gcc
.SUFFIXES: NM = ${TARGET}-nm
CXX= ${TARGET}-g++
AR = ${TARGET}-ar
AS = ${TARGET}-as
OC = ${TARGET}-objcopy
all: image.iso KERNEL_CFLAGS = -ffreestanding -O2 -std=gnu11 -g -static
KERNEL_CFLAGS += -Wall -Wextra -Wno-unused-function -Wno-unused-parameter
KERNEL_CFLAGS += -pedantic -Wwrite-strings ${ARCH_KERNEL_CFLAGS}
TARGET_TRIPLET=i686-pc-toaru # Defined constants for the kernel
KERNEL_CFLAGS += -D_KERNEL_ -DKERNEL_ARCH=${ARCH}
KERNEL_CFLAGS += -DKERNEL_GIT_TAG=`util/make-version`
# Userspace flags KERNEL_OBJS = $(patsubst %.c,%.o,$(wildcard kernel/*.c))
KERNEL_OBJS += $(patsubst %.c,%.o,$(wildcard kernel/*/*.c))
KERNEL_OBJS += $(patsubst %.c,%.o,$(wildcard kernel/arch/${ARCH}/*.c))
CC=$(TARGET_TRIPLET)-gcc KERNEL_ASMOBJS = $(filter-out kernel/symbols.o,$(patsubst %.S,%.o,$(wildcard kernel/arch/${ARCH}/*.S)))
AR=$(TARGET_TRIPLET)-ar
AS=$(TARGET_TRIPLET)-as
CFLAGS= -O2 -s -std=gnu99 -I. -Iapps -pipe -mmmx -msse -msse2 -fplan9-extensions -Wall -Wextra -Wno-unused-parameter
## KERNEL_SOURCES = $(wildcard kernel/*.c) $(wildcard kernel/*/*.c) $(wildcard kernel/${ARCH}/*/*.c)
# C library objects from libc/ C sources (and setjmp, which is assembly) KERNEL_SOURCES += $(wildcard kernel/arch/${ARCH}/*.S)
LIBC_OBJS = $(patsubst %.c,%.o,$(wildcard libc/*.c))
LIBC_OBJS += $(patsubst %.c,%.o,$(wildcard libc/*/*.c))
LIBC_OBJS += libc/setjmp.o
LC=base/lib/libc.so
## MODULES = $(patsubst %.c,%.ko,$(wildcard modules/*.c))
# APPS = C sources from apps/
# APPS_X = binaries # Configs you can override.
# APPS_Y = generated makefiles for binaries SMP ?= 1
# APPS_SH = shell scripts to copy to base/bin/ and mark executable RAM ?= 3G
# APPS_SH_X = destinations for shell scripts EXTRA_ARGS ?=
APPS=$(patsubst apps/%.c,%,$(wildcard apps/*.c))
APPS_X=$(foreach app,$(APPS),base/bin/$(app)) EMU = qemu-system-x86_64
EMU_ARGS = -kernel misaka-kernel
EMU_ARGS += -M q35
EMU_ARGS += -m $(RAM)
EMU_ARGS += -smp $(SMP)
EMU_ARGS += -no-reboot
#EMU_ARGS += -display none
EMU_ARGS += -serial mon:stdio
EMU_ARGS += -rtc base=localtime
EMU_ARGS += -soundhw pcspk,ac97
EMU_ARGS += -netdev user,id=u1,hostfwd=tcp::5555-:23 -device e1000e,netdev=u1 -object filter-dump,id=f1,netdev=u1,file=qemu-e1000e.pcap
EMU_ARGS += -netdev user,id=u2,hostfwd=tcp::5580-:80 -device e1000,netdev=u2 -object filter-dump,id=f2,netdev=u2,file=qemu.pcap
#EMU_ARGS += -hda toaruos-disk.img
EMU_KVM ?= -enable-kvm
APPS=$(patsubst apps/%.c,%,$(wildcard apps/*.c)) $(patsubst apps/%.c++,%,$(wildcard apps/*.c++))
APPS_X=$(foreach app,$(APPS),$(BASE)/bin/$(app))
APPS_Y=$(foreach app,$(APPS),.make/$(app).mak) APPS_Y=$(foreach app,$(APPS),.make/$(app).mak)
APPS_SH=$(patsubst apps/%.sh,%.sh,$(wildcard apps/*.sh)) APPS_SH=$(patsubst apps/%.sh,%.sh,$(wildcard apps/*.sh))
APPS_SH_X=$(foreach app,$(APPS_SH),base/bin/$(app)) APPS_SH_X=$(foreach app,$(APPS_SH),$(BASE)/bin/$(app))
APPS_KRK=$(patsubst apps/%.krk,%.krk,$(wildcard apps/*.krk)) APPS_KRK=$(patsubst apps/%.krk,%.krk,$(wildcard apps/*.krk))
APPS_KRK_X=$(foreach app,$(APPS_KRK),base/bin/$(app)) APPS_KRK_X=$(foreach app,$(APPS_KRK),$(BASE)/bin/$(app))
##
# LIBS = C sources from lib/
# LIBS_X = Shared libraries (.so)
# LIBS_Y = Generated makefiles for libraries
LIBS=$(patsubst lib/%.c,%,$(wildcard lib/*.c)) LIBS=$(patsubst lib/%.c,%,$(wildcard lib/*.c))
LIBS_X=$(foreach lib,$(LIBS),base/lib/libtoaru_$(lib).so) LIBS_X=$(foreach lib,$(LIBS),$(BASE)/lib/libtoaru_$(lib).so)
LIBS_Y=$(foreach lib,$(LIBS),.make/$(lib).lmak) LIBS_Y=$(foreach lib,$(LIBS),.make/$(lib).lmak)
SOURCE_FILES = $(wildcard kernel/*.c kernel/*/*.c kernel/*/*/*.c modules/*.c) KRK_MODS = $(patsubst kuroko/src/modules/module_%.c,$(BASE)/lib/kuroko/%.so,$(wildcard kuroko/src/modules/module_*.c))
SOURCE_FILES += $(wildcard apps/*.c linker/*.c libc/*.c libc/*/*.c lib/*.c) KRK_MODS_X = $(patsubst lib/kuroko/%.c,$(BASE)/lib/kuroko/%.so,$(wildcard lib/kuroko/*.c))
KRK_MODS_Y = $(patsubst lib/kuroko/%.c,.make/%.kmak,$(wildcard lib/kuroko/*.c))
tags: $(SOURCE_FILES) $(wildcard kuroko/src/*.c kuroko/src/*.h) CFLAGS= -O2 -std=gnu11 -I. -Iapps -fplan9-extensions -Wall -Wextra -Wno-unused-parameter
ctags -f tags $(SOURCE_FILES) $(wildcard kuroko/src/*.c kuroko/src/*.h)
## LIBC_OBJS = $(patsubst %.c,%.o,$(wildcard libc/*.c))
# Files that must be present in the ramdisk (apps, libraries) LIBC_OBJS += $(patsubst %.c,%.o,$(wildcard libc/*/*.c))
RAMDISK_FILES= ${APPS_X} ${APPS_SH_X} ${APPS_KRK_X} ${LIBS_X} base/lib/ld.so base/lib/libm.so ${KUROKO_FILES} LIBC_OBJS += $(patsubst %.c,%.o,$(wildcard libc/arch/${ARCH}/*.c))
# Kernel / module flags GCC_SHARED = $(BASE)/usr/lib/libgcc_s.so.1 $(BASE)/usr/lib/libgcc_s.so
LIBSTDCXX = $(BASE)/usr/lib/libstdc++.so.6.0.28 $(BASE)/usr/lib/libstdc++.so.6 $(BASE)/usr/lib/libstdc++.so
ifeq (,${USE_CLANG}) CRTS = $(BASE)/lib/crt0.o $(BASE)/lib/crti.o $(BASE)/lib/crtn.o
KCC = $(TARGET_TRIPLET)-gcc
LGCC = -lgcc
EXTRALIB =
else
KCC = clang --target=i686-elf -static -Ibase/usr/include -nostdinc -mno-sse
LGCC = util/compiler-rt.o
EXTRALIB = util/compiler-rt.o
util/compiler-rt.o: util/compiler-rt.S
${KAS} ${ASFLAGS} $< -o $@
endif
KAS = $(TARGET_TRIPLET)-as
KLD = $(TARGET_TRIPLET)-ld
KNM = $(TARGET_TRIPLET)-nm
KCFLAGS = -O2 -std=c99 LC = $(BASE)/lib/libc.so $(GCC_SHARED) $(LIBSTDCXX)
KCFLAGS += -finline-functions -ffreestanding
KCFLAGS += -Wall -Wextra -Wno-unused-function -Wno-unused-parameter -Wno-format
KCFLAGS += -pedantic -fno-omit-frame-pointer
KCFLAGS += -D_KERNEL_
KCFLAGS += -DKERNEL_GIT_TAG=$(shell util/make-version)
KASFLAGS = --32
## .PHONY: all system clean run shell
# Kernel objects from kernel/ C sources
KERNEL_OBJS = $(patsubst %.c,%.o,$(wildcard kernel/*.c))
KERNEL_OBJS += $(patsubst %.c,%.o,$(wildcard kernel/*/*.c))
KERNEL_OBJS += $(patsubst %.c,%.o,$(wildcard kernel/*/*/*.c))
## all: system
# Kernel objects from kernel/ assembly sources system: misaka-kernel $(MODULES) ramdisk.igz
KERNEL_ASMOBJS = $(filter-out kernel/symbols.o,$(patsubst %.S,%.o,$(wildcard kernel/*.S)))
HEADERS = $(wildcard base/usr/include/kernel/*.h base/usr/include/kernel/*/*.h)
# Kernel %.ko: %.c
${CC} -c ${KERNEL_CFLAGS} -o $@ $<
fatbase/kernel: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o ${EXTRALIB} ramdisk.igz: $(wildcard $(BASE)/* $(BASE)/*/* $(BASE)/*/*/*) $(APPS_X) $(LIBS_X) $(KRK_MODS_X) $(BASE)/bin/kuroko $(BASE)/lib/ld.so $(APPS_KRK_X) $(KRK_MODS)
${KCC} -T kernel/link.ld ${KCFLAGS} -nostdlib -o $@ ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o ${LGCC} python3 util/createramdisk.py
## KRK_SRC = $(sort $(wildcard kuroko/src/*.c))
# Symbol table for the kernel. Instead of relying on getting $(BASE)/bin/kuroko: $(KRK_SRC) $(CRTS) | $(LC)
# the symbol table from our bootloader (eg. through ELF $(CC) -O2 -g -o $@ -Wl,--export-dynamic -Ikuroko/src $(KRK_SRC) kuroko/src/vendor/rline.c
# headers provided via multiboot structure), we have a dedicated
# object that build with all the symbols. This allows us to $(BASE)/lib/kuroko/%.so: kuroko/src/modules/module_%.c| dirs $(LC)
# build the kernel as a flat binary or load it with less-capable $(CC) -O2 -shared -fPIC -Ikuroko/src -o $@ $<
# multiboot loaders and still get symbols, which we need to
# load kernel modules and link them properly. $(BASE)/lib/libkuroko.so: $(KRK_SRC) | $(LC)
kernel/symbols.o: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} util/generate_symbols.krk ${EXTRALIB} | util/kuroko $(CC) -O2 -shared -fPIC -Ikuroko/src -o $@ $(filter-out kuroko/src/kuroko.c,$(KRK_SRC))
$(BASE)/lib/ld.so: linker/linker.c $(BASE)/lib/libc.a | dirs $(LC)
$(CC) -g -static -Wl,-static $(CFLAGS) -o $@ -Os -T linker/link.ld $<
run: system
${EMU} ${EMU_ARGS} ${EMU_KVM} -append "root=/dev/ram0 start=live-session migrate $(EXTRA_ARGS)" -initrd ramdisk.igz
shell: system
${EMU} -m $(RAM) ${EMU_KVM} -kernel misaka-kernel -append "root=/dev/ram0 start=--headless migrate" -initrd ramdisk.igz \
-nographic -no-reboot -audiodev none,id=id -serial null -serial mon:stdio \
-fw_cfg name=opt/org.toaruos.gettyargs,string="-a local /dev/ttyS1" \
-fw_cfg name=opt/org.toaruos.term,string=${TERM}
misaka-kernel: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o
${CC} -g -T kernel/arch/${ARCH}/link.ld ${KERNEL_CFLAGS} -o $@.64 ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o -lgcc
${OC} -I elf64-x86-64 -O elf32-i386 $@.64 $@
kernel/sys/version.o: ${KERNEL_SOURCES}
kernel/symbols.o: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} util/gensym.krk
-rm -f kernel/symbols.o -rm -f kernel/symbols.o
${KCC} -T kernel/link.ld ${KCFLAGS} -nostdlib -o .toaruos-kernel ${KERNEL_ASMOBJS} ${KERNEL_OBJS} ${LGCC} ${CC} -T kernel/arch/${ARCH}/link.ld ${KERNEL_CFLAGS} -o misaka-kernel.64 ${KERNEL_ASMOBJS} ${KERNEL_OBJS} -lgcc
${KNM} .toaruos-kernel -g | util/kuroko util/generate_symbols.krk > kernel/symbols.S ${NM} misaka-kernel.64 -g | kuroko util/gensym.krk > kernel/symbols.S
${KAS} ${KASFLAGS} kernel/symbols.S -o $@ ${CC} -c kernel/symbols.S -o $@
-rm -f .toaruos-kernel
##
# version.o should be rebuilt whenever the kernel changes
# in order to get fresh git commit hash information.
kernel/sys/version.o: kernel/*/*.c kernel/*.c
kernel/%.o: kernel/%.S kernel/%.o: kernel/%.S
${KAS} ${ASFLAGS} $< -o $@ echo ${PATH}
${CC} -c $< -o $@
HEADERS = $(wildcard base/usr/include/kernel/*.h)
kernel/%.o: kernel/%.c ${HEADERS} kernel/%.o: kernel/%.c ${HEADERS}
${KCC} ${KCFLAGS} -nostdlib -g -c -o $@ $< ${CC} ${KERNEL_CFLAGS} -nostdlib -g -Iinclude -c -o $@ $<
# Modules clean:
-rm -f ${KERNEL_ASMOBJS}
-rm -f ${KERNEL_OBJS}
-rm -f kernel/symbols.o misaka-kernel misaka-kernel.64
-rm -f ramdisk.tar ramdisk.igz
-rm -f $(APPS_Y) $(LIBS_Y) $(KRK_MODS_Y) $(KRK_MODS)
-rm -f $(APPS_X) $(LIBS_X) $(KRK_MODS_X) $(APPS_KRK_X) $(APPS_SH_X)
-rm -f $(BASE)/lib/crt0.o $(BASE)/lib/crti.o $(BASE)/lib/crtn.o
-rm -f $(BASE)/lib/libc.so $(BASE)/lib/libc.a
-rm -f $(LIBC_OBJS) $(BASE)/lib/ld.so $(BASE)/lib/libkuroko.so $(BASE)/lib/libm.so
-rm -f $(BASE)/bin/kuroko
-rm -f $(GCC_SHARED) $(LIBSTDCXX)
fatbase/mod: libc/%.o: libc/%.c base/usr/include/syscall.h
@mkdir -p $@ $(CC) -O2 -std=gnu11 -Wall -Wextra -Wno-unused-parameter -fPIC -c -o $@ $<
## .PHONY: libc
# Modules need to be installed on the boot image libc: $(BASE)/lib/libc.a $(BASE)/lib/libc.so
MODULES = $(patsubst modules/%.c,fatbase/mod/%.ko,$(wildcard modules/*.c))
fatbase/mod/%.ko: modules/%.c ${HEADERS} | fatbase/mod $(BASE)/lib/libc.a: ${LIBC_OBJS} $(CRTS)
${KCC} -nostdlib ${KCFLAGS} -c -o $@ $< $(AR) cr $@ $(LIBC_OBJS)
modules: ${MODULES} $(BASE)/lib/libc.so: ${LIBC_OBJS} | $(CRTS)
${CC} -nodefaultlibs -shared -fPIC -o $@ $^
# Root Filesystem $(BASE)/lib/crt%.o: libc/arch/${ARCH}/crt%.S
${AS} -o $@ $<
base/dev: $(BASE)/usr/lib/%: util/local/${TARGET}/lib/% | dirs
cp -a $< $@
-strip $@
$(BASE)/lib/libm.so: util/libm.c
$(CC) -shared -nostdlib -fPIC -o $@ $<
$(BASE)/dev:
mkdir -p $@ mkdir -p $@
base/tmp: $(BASE)/tmp:
mkdir -p $@ mkdir -p $@
base/proc: $(BASE)/proc:
mkdir -p $@ mkdir -p $@
base/bin: $(BASE)/bin:
mkdir -p $@ mkdir -p $@
base/lib: $(BASE)/lib:
mkdir -p $@ mkdir -p $@
base/cdrom: $(BASE)/cdrom:
mkdir -p $@ mkdir -p $@
base/var: $(BASE)/var:
mkdir -p $@ mkdir -p $@
base/lib/kuroko: $(BASE)/lib/kuroko:
mkdir -p $@
$(BASE)/usr/lib:
mkdir -p $@ mkdir -p $@
fatbase/efi/boot: fatbase/efi/boot:
mkdir -p $@ mkdir -p $@
@ -172,271 +192,49 @@ cdrom:
mkdir -p $@ mkdir -p $@
.make: .make:
mkdir -p .make mkdir -p .make
dirs: base/dev base/tmp base/proc base/bin base/lib base/cdrom base/lib/kuroko cdrom base/var fatbase/efi/boot .make dirs: $(BASE)/dev $(BASE)/tmp $(BASE)/proc $(BASE)/bin $(BASE)/lib $(BASE)/cdrom $(BASE)/usr/lib $(BASE)/lib/kuroko cdrom $(BASE)/var fatbase/efi/boot .make
# C Library
crts: base/lib/crt0.o base/lib/crti.o base/lib/crtn.o | dirs
base/lib/crt%.o: libc/crt%.S
$(AS) -o $@ $<
libc/setjmp.o: libc/setjmp.S
$(AS) -o $@ $<
libc/%.o: libc/%.c
$(CC) $(CFLAGS) -fPIC -c -o $@ $<
base/lib/libc.a: ${LIBC_OBJS} | dirs crts
$(AR) cr $@ $^
base/lib/libc.so: ${LIBC_OBJS} | dirs crts
$(CC) -nodefaultlibs -o $@ $(CFLAGS) -shared -fPIC $^ -lgcc
base/lib/libm.so: util/lm.c | dirs crts
$(CC) -nodefaultlibs -o $@ $(CFLAGS) -shared -fPIC $^ -lgcc
KUROKO_OBJS=$(patsubst %.c, %.o, $(filter-out kuroko/src/kuroko.c,$(sort $(wildcard kuroko/src/*.c))))
kuroko/%.o: kuroko/%.c
$(CC) $(CFLAGS) -fPIC -c -o $@ $^
KUROKO_CMODS=$(patsubst kuroko/src/modules/module_%.c,%,$(wildcard kuroko/src/modules/module_*.c)) $(patsubst lib/kuroko/%.c,%,$(wildcard lib/kuroko/*.c))
KUROKO_CMODS_X=$(foreach lib,$(KUROKO_CMODS),base/lib/kuroko/$(lib).so)
KUROKO_CMODS_Y=$(foreach lib,$(KUROKO_CMODS),.make/$(lib).kmak)
KUROKO_KRK_MODS=$(patsubst kuroko/modules/%.krk,base/lib/kuroko/%.krk,$(wildcard kuroko/modules/*.krk kuroko/modules/*/*.krk))
KUROKO_FILES=$(KUROKO_CMODS_X) $(KUROKO_KRK_MODS) base/lib/libkuroko.so
base/lib/kuroko/%.krk: kuroko/modules/%.krk
@mkdir -p `dirname $@`
cp $< $@
MINIMAL_KUROKO = $(filter-out kuroko/src/modules/module_%,$(sort $(wildcard kuroko/src/*.c)))
util/kuroko: $(MINIMAL_KUROKO)
gcc -Ikuroko/src -DNO_RLINE -DSTATIC_ONLY -DKRK_DISABLE_THREADS -o $@ $^
.make/%.kmak: kuroko/src/modules/module_%.c util/auto-dep.krk | dirs util/kuroko
util/kuroko util/auto-dep.krk --makekurokomod $< > $@
.make/%.kmak: lib/kuroko/%.c util/auto-dep.krk | dirs util/kuroko
util/kuroko util/auto-dep.krk --makekurokomod $< > $@
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include ${KUROKO_CMODS_Y}
endif
base/lib/libkuroko.so: $(KUROKO_OBJS) | dirs crts ${LC}
$(CC) $(CFLAGS) -shared -fPIC -o $@ $^ -lgcc
# Userspace Linker/Loader
base/lib/ld.so: linker/linker.c base/lib/libc.a | dirs
$(CC) -static -Wl,-static $(CFLAGS) -o $@ -Os -T linker/link.ld $<
# Shared Libraries
.make/%.lmak: lib/%.c util/auto-dep.krk | dirs crts util/kuroko
util/kuroko util/auto-dep.krk --makelib $< > $@
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include ${LIBS_Y}
endif
# netinit needs to go in the CD/FAT root, so it gets built specially
fatbase/netinit: util/netinit.c base/lib/libc.a | dirs
$(CC) $(CFLAGS) -o $@ $<
# Userspace applications
.make/%.mak: apps/%.c util/auto-dep.krk | dirs crts util/kuroko
util/kuroko util/auto-dep.krk --make $< > $@
ifeq (,$(findstring clean,$(MAKECMDGOALS))) ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include ${APPS_Y} -include ${APPS_Y}
-include ${LIBS_Y}
-include ${KRK_MODS_Y}
endif endif
base/bin/%.sh: apps/%.sh .make/%.lmak: lib/%.c util/auto-dep.krk | dirs $(CRTS)
kuroko util/auto-dep.krk --makelib $< > $@
.make/%.mak: apps/%.c util/auto-dep.krk | dirs $(CRTS)
kuroko util/auto-dep.krk --make $< > $@
.make/%.mak: apps/%.c++ util/auto-dep.krk | dirs $(CRTS)
kuroko util/auto-dep.krk --make $< > $@
.make/%.kmak: lib/kuroko/%.c util/auto-dep.krk | dirs
kuroko util/auto-dep.krk --makekurokomod $< > $@
$(BASE)/bin/%.sh: apps/%.sh
cp $< $@ cp $< $@
chmod +x $@ chmod +x $@
base/bin/%.krk: apps/%.krk $(BASE)/bin/%.krk: apps/%.krk
cp $< $@ cp $< $@
chmod +x $@ chmod +x $@
# Ramdisk .PHONY: libs
fatbase/ramdisk.igz: ${RAMDISK_FILES} $(shell find base) Makefile util/createramdisk.py | dirs libs: $(LIBS_X)
python3 util/createramdisk.py
gzip -c fatbase/ramdisk.img > fatbase/ramdisk.igz
rm fatbase/ramdisk.img
# CD image .PHONY: apps
apps: $(APPS_X)
ifeq (,$(wildcard /usr/lib32/crt0-efi-ia32.o)) .PHONY: libstdcxx
$(error Missing GNU-EFI.) libstdcxx: $(LIBSTDCXX)
endif
EFI_XORRISO=-eltorito-alt-boot -e fat.img -no-emul-boot -isohybrid-gpt-basdat util/local/${TARGET}/lib/libstdc++.so.6.0.28: | $(BASE)/lib/libm.so
EFI_BOOT=cdrom/fat.img cd util/build/gcc && make all-target-libstdc++-v3 && make install-target-libstdc++-v3
EFI_UPDATE=util/update-extents.py
image.iso: ${EFI_BOOT} cdrom/boot.sys fatbase/netinit ${MODULES} util/update-extents.py SOURCE_FILES = $(wildcard kernel/*.c kernel/*/*.c kernel/*/*/*.c kernel/*/*/*/*.c)
xorriso -as mkisofs -R -J -c bootcat \ SOURCE_FILES += $(wildcard apps/*.c linker/*.c libc/*.c libc/*/*.c lib/*.c lib/kuroko/*.c)
-b boot.sys -no-emul-boot -boot-load-size full \ SOURCE_FILES += $(wildcard kuroko/src/*.c kuroko/src/*.h kuroko/src/*/*.c kuroko/src/*/*.h)
${EFI_XORRISO} \ SOURCE_FILES += $(wildcard $(BASE)/usr/include/*.h $(BASE)/usr/include/*/*.h $(BASE)/usr/include/*/*/*.h)
-o image.iso cdrom tags: $(SOURCE_FILES)
${EFI_UPDATE} ctags -f tags $(SOURCE_FILES)
# Boot loader
##
# FAT EFI payload
# This is the filesystem the EFI loaders see, so it must contain
# the kernel, modules, and ramdisk, plus anything else we want
# available to the bootloader (eg., netinit).
cdrom/fat.img: fatbase/ramdisk.igz ${MODULES} fatbase/kernel fatbase/netinit fatbase/efi/boot/bootia32.efi fatbase/efi/boot/bootx64.efi util/mkdisk.sh | dirs
util/mkdisk.sh $@ fatbase
##
# For EFI, we build two laoders: ia32 and x64
# We build them as ELF shared objects and the use objcopy to convert
# them to PE executables / DLLs (as expected by EFI).
EFI_CFLAGS=-fno-stack-protector -fpic -DEFI_PLATFORM -ffreestanding -fshort-wchar -I /usr/include/efi -mno-red-zone
EFI_SECTIONS=-j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .reloc
# ia32
boot/efi.so: boot/cstuff.c boot/*.h
$(CC) ${EFI_CFLAGS} -I /usr/include/efi/ia32 -c -o boot/efi.o $<
$(LD) boot/efi.o /usr/lib32/crt0-efi-ia32.o -nostdlib -znocombreloc -T /usr/lib32/elf_ia32_efi.lds -shared -Bsymbolic -L /usr/lib32 -lefi -lgnuefi -o boot/efi.so
fatbase/efi/boot/bootia32.efi: boot/efi.so
objcopy ${EFI_SECTIONS} --target=efi-app-ia32 $< $@
# x64
boot/efi64.so: boot/cstuff.c boot/*.h
gcc ${EFI_CFLAGS} -I /usr/include/efi/x86_64 -DEFI_FUNCTION_WRAPPER -c -o boot/efi64.o $<
$(LD) boot/efi64.o /usr/lib/crt0-efi-x86_64.o -nostdlib -znocombreloc -T /usr/lib/elf_x86_64_efi.lds -shared -Bsymbolic -L /usr/lib -lefi -lgnuefi -o boot/efi64.so
fatbase/efi/boot/bootx64.efi: boot/efi64.so
objcopy ${EFI_SECTIONS} --target=efi-app-x86_64 $< $@
# BIOS loader
cdrom/boot.sys: boot/boot.o boot/cstuff.o boot/link.ld | dirs
${KLD} -T boot/link.ld -o $@ boot/boot.o boot/cstuff.o
boot/cstuff.o: boot/cstuff.c boot/*.h
${CC} -c -Os -fno-strict-aliasing -finline-functions -ffreestanding -o $@ $<
boot/boot.o: boot/boot.S
${AS} -o $@ $<
.PHONY: clean
clean:
rm -f base/lib/*.so
rm -f base/lib/libc.a
rm -f ${APPS_X} ${APPS_SH_X}
rm -f libc/*.o libc/*/*.o
rm -f image.iso
rm -f fatbase/ramdisk.img fatbase/ramdisk.igz
rm -f cdrom/boot.sys
rm -f boot/*.o
rm -f boot/*.efi
rm -f boot/*.so
rm -f cdrom/fat.img cdrom/kernel cdrom/mod/* cdrom/ramdisk.img
rm -f fatbase/kernel fatbase/efi/boot/bootia32.efi fatbase/efi/boot/bootx64.efi
rm -f cdrom/netinit fatbase/netinit
rm -f ${KERNEL_OBJS} ${KERNEL_ASMOBJS} kernel/symbols.o kernel/symbols.S
rm -f base/lib/crt*.o
rm -f ${MODULES}
rm -f ${APPS_Y} ${LIBS_Y} ${EXT_LIBS_Y}
rm -f ${KUROKO_FILES} ${KUROKO_CMODS_Y} ${KUROKO_CMODS_X}
rm -f kuroko/src/*.o
rm -f util/kuroko
ifneq (,$(findstring Microsoft,$(shell uname -r)))
QEMU_ARGS=-serial mon:stdio -m 1G -rtc base=localtime -vnc :0
else
ifeq (,${NO_KVM})
KVM=-enable-kvm
else
KVM=
endif
QEMU_ARGS=-serial mon:stdio -m 1G -soundhw ac97,pcspk ${KVM} -rtc base=localtime ${QEMU_EXTRA}
endif
.PHONY: run
run: image.iso
qemu-system-i386 -cdrom $< ${QEMU_ARGS}
.PHONY: fast
fast: image.iso
qemu-system-i386 -cdrom $< ${QEMU_ARGS} \
-fw_cfg name=opt/org.toaruos.bootmode,string=normal
.PHONY: headless
headless: image.iso
@qemu-system-i386 -cdrom $< -m 1G ${KVM} -rtc base=localtime ${QEMU_EXTRA} \
-serial null -serial mon:stdio \
-nographic -no-reboot -audiodev none,id=id \
-fw_cfg name=opt/org.toaruos.bootmode,string=headless \
-fw_cfg name=opt/org.toaruos.gettyargs,string="-a local /dev/ttyS1"
.PHONY: shell
shell: image.iso
@qemu-system-i386 -cdrom $< ${QEMU_ARGS} \
-nographic -no-reboot \
-fw_cfg name=opt/org.toaruos.bootmode,string=headless \
-fw_cfg name=opt/org.toaruos.forceuser,string=local \
-fw_cfg name=opt/org.toaruos.term,string=${TERM} </dev/null >/dev/null & \
stty raw -echo && nc -l 127.0.0.1 8090 && stty sane && wait
.PHONY: efi64
efi64: image.iso
qemu-system-x86_64 -cdrom $< ${QEMU_ARGS} \
-bios /usr/share/qemu/OVMF.fd
VMNAME=ToaruOS CD
define virtualbox-runner =
.PHONY: $1
$1: image.iso
-VBoxManage unregistervm "$(VMNAME)" --delete
VBoxManage createvm --name "$(VMNAME)" --ostype $2 --register
VBoxManage modifyvm "$(VMNAME)" --memory 1024 --vram 32 --audio pulse --audiocontroller ac97 --bioslogodisplaytime 1 --bioslogofadeout off --bioslogofadein off --biosbootmenu disabled $3
VBoxManage storagectl "$(VMNAME)" --add ide --name "IDE"
VBoxManage storageattach "$(VMNAME)" --storagectl "IDE" --port 0 --device 0 --medium $$(shell pwd)/image.iso --type dvddrive
VBoxManage setextradata "$(VMNAME)" GUI/DefaultCloseAction PowerOff
VBoxManage startvm "$(VMNAME)" --type separate
endef
$(eval $(call virtualbox-runner,virtualbox,"Other",))
$(eval $(call virtualbox-runner,virtualbox-efi,"Other",--firmware efi))
$(eval $(call virtualbox-runner,virtualbox-efi64,"Other_64",--firmware efi))
##
# Optional Extensions
#
# These optional extension libraries require third-party components to build,
# but allow the native applications to make use of functionality such as
# TrueType fonts or PNG images. You must have the necessary elements to build
# these already installed into your sysroot for this to work.
EXT_LIBS=$(patsubst ext/%.c,%,$(wildcard ext/*.c))
EXT_LIBS_X=$(foreach lib,$(EXT_LIBS),base/lib/libtoaru_$(lib).so)
EXT_LIBS_Y=$(foreach lib,$(EXT_LIBS),.make/$(lib).elmak)
.make/%.elmak: ext/%.c util/auto-dep.krk | dirs util/kuroko
util/kuroko util/auto-dep.krk --makelib $< > $@
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include ${EXT_LIBS_Y}
endif
# Freetype: Terminal text rendering backend
ext-freetype: base/lib/libtoaru_ext_freetype_fonts.so
# Cairo: Compositor rendering backend
ext-cairo: base/lib/libtoaru_ext_cairo_renderer.so
# Other extra stuff
util/ungz: util/ungz.c
$(CC) -o $@ $< -lz

View File

@ -171,7 +171,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win) { if (win) {
win->focused = wf->focused; win->focused = wf->focused;
redraw(); redraw();

View File

@ -46,7 +46,7 @@
#include <toaru/list.h> #include <toaru/list.h>
#include <toaru/spinlock.h> #include <toaru/spinlock.h>
//#define _DEBUG_YUTANI #define _DEBUG_YUTANI
#ifdef _DEBUG_YUTANI #ifdef _DEBUG_YUTANI
#include <toaru/trace.h> #include <toaru/trace.h>
#define TRACE_APP_NAME "yutani" #define TRACE_APP_NAME "yutani"
@ -175,7 +175,7 @@ static int next_wid(void) {
return _next++; return _next++;
} }
uint32_t yutani_current_time(yutani_globals_t * yg) { uint64_t yutani_current_time(yutani_globals_t * yg) {
struct timeval t; struct timeval t;
gettimeofday(&t, NULL); gettimeofday(&t, NULL);
@ -187,13 +187,13 @@ uint32_t yutani_current_time(yutani_globals_t * yg) {
usec_diff = (1000000 + t.tv_usec) - yg->start_subtime; usec_diff = (1000000 + t.tv_usec) - yg->start_subtime;
} }
return (uint32_t)(sec_diff * 1000 + usec_diff / 1000); return (uint64_t)(sec_diff * 1000 + usec_diff / 1000);
} }
uint32_t yutani_time_since(yutani_globals_t * yg, uint32_t start_time) { uint64_t yutani_time_since(yutani_globals_t * yg, uint64_t start_time) {
uint32_t now = yutani_current_time(yg); uint64_t now = yutani_current_time(yg);
uint32_t diff = now - start_time; /* Milliseconds */ uint64_t diff = now - start_time; /* Milliseconds */
return diff; return diff;
} }
@ -390,13 +390,13 @@ static int yutani_pick_animation(uint32_t flags, int direction) {
* *
* Initializes a window of the particular size for a given client. * Initializes a window of the particular size for a given client.
*/ */
static yutani_server_window_t * server_window_create(yutani_globals_t * yg, int width, int height, uint32_t owner, uint32_t flags) { static yutani_server_window_t * server_window_create(yutani_globals_t * yg, int width, int height, uintptr_t owner, uint32_t flags) {
yutani_server_window_t * win = malloc(sizeof(yutani_server_window_t)); yutani_server_window_t * win = malloc(sizeof(yutani_server_window_t));
win->wid = next_wid(); win->wid = next_wid();
win->owner = owner; win->owner = owner;
list_insert(yg->windows, win); list_insert(yg->windows, win);
hashmap_set(yg->wids_to_windows, (void*)win->wid, win); hashmap_set(yg->wids_to_windows, (void*)(uintptr_t)win->wid, win);
list_t * client_list = hashmap_get(yg->clients_to_windows, (void *)owner); list_t * client_list = hashmap_get(yg->clients_to_windows, (void *)owner);
list_insert(client_list, win); list_insert(client_list, win);
@ -733,7 +733,7 @@ static int yutani_blit_window(yutani_globals_t * yg, yutani_server_window_t * wi
case YUTANI_EFFECT_FADE_OUT: case YUTANI_EFFECT_FADE_OUT:
{ {
frame = yutani_animation_lengths[window->anim_mode] - frame; frame = yutani_animation_lengths[window->anim_mode] - frame;
} } /* fallthrough */
case YUTANI_EFFECT_SQUEEZE_IN: case YUTANI_EFFECT_SQUEEZE_IN:
case YUTANI_EFFECT_FADE_IN: case YUTANI_EFFECT_FADE_IN:
{ {
@ -1018,7 +1018,7 @@ static void redraw_windows(yutani_globals_t * yg) {
if ((!yg->bottom_z || yg->bottom_z->anim_mode) && renderer_blit_screen) { if ((!yg->bottom_z || yg->bottom_z->anim_mode) && renderer_blit_screen) {
/* TODO: Need to clear with Cairo backend */ /* TODO: Need to clear with Cairo backend */
draw_fill(yg->backend_ctx, rgb(110,110,110)); draw_fill(yg->backend_ctx, rgb(5,5,5));
} }
if (renderer_set_clip) renderer_set_clip(yg); if (renderer_set_clip) renderer_set_clip(yg);
@ -1252,7 +1252,7 @@ static void window_mark_for_close(yutani_globals_t * yg, yutani_server_window_t
* Remove a window from its owner's child set. * Remove a window from its owner's child set.
*/ */
static void window_remove_from_client(yutani_globals_t * yg, yutani_server_window_t * w) { static void window_remove_from_client(yutani_globals_t * yg, yutani_server_window_t * w) {
list_t * client_list = hashmap_get(yg->clients_to_windows, (void *)w->owner); list_t * client_list = hashmap_get(yg->clients_to_windows, (void *)(uintptr_t)w->owner);
if (client_list) { if (client_list) {
node_t * n = list_find(client_list, w); node_t * n = list_find(client_list, w);
if (n) { if (n) {
@ -1267,7 +1267,7 @@ static void window_remove_from_client(yutani_globals_t * yg, yutani_server_windo
*/ */
static void window_actually_close(yutani_globals_t * yg, yutani_server_window_t * w) { static void window_actually_close(yutani_globals_t * yg, yutani_server_window_t * w) {
/* Remove from the wid -> window mapping */ /* Remove from the wid -> window mapping */
hashmap_remove(yg->wids_to_windows, (void *)w->wid); hashmap_remove(yg->wids_to_windows, (void *)(uintptr_t)w->wid);
/* Remove from the general list of windows. */ /* Remove from the general list of windows. */
list_remove(yg->windows, list_index_of(yg->windows, w)); list_remove(yg->windows, list_index_of(yg->windows, w));
@ -1319,7 +1319,7 @@ static uint32_t ad_flags(yutani_globals_t * yg, yutani_server_window_t * win) {
/** /**
* Send a result for a window query. * Send a result for a window query.
*/ */
static void yutani_query_result(yutani_globals_t * yg, uint32_t dest, yutani_server_window_t * win) { static void yutani_query_result(yutani_globals_t * yg, uintptr_t dest, yutani_server_window_t * win) {
if (win && win->client_length) { if (win && win->client_length) {
yutani_msg_buildx_window_advertise_alloc(response, win->client_length); yutani_msg_buildx_window_advertise_alloc(response, win->client_length);
yutani_msg_buildx_window_advertise(response, win->wid, ad_flags(yg, win), win->client_offsets, win->client_length, win->client_strings); yutani_msg_buildx_window_advertise(response, win->wid, ad_flags(yg, win), win->client_offsets, win->client_length, win->client_strings);
@ -1335,7 +1335,7 @@ static void notify_subscribers(yutani_globals_t * yg) {
yutani_msg_buildx_notify(response); yutani_msg_buildx_notify(response);
list_t * remove = NULL; list_t * remove = NULL;
foreach(node, yg->window_subscribers) { foreach(node, yg->window_subscribers) {
uint32_t subscriber = (uint32_t)node->value; uintptr_t subscriber = (uintptr_t)node->value;
if (!hashmap_has(yg->clients_to_windows, (void *)subscriber)) { if (!hashmap_has(yg->clients_to_windows, (void *)subscriber)) {
if (!remove) { if (!remove) {
remove = list_create(); remove = list_create();
@ -1601,8 +1601,8 @@ static void handle_key_event(yutani_globals_t * yg, struct yutani_msg_key_event
* External bindings registered by clients. * External bindings registered by clients.
*/ */
uint32_t key_code = ((ke->event.modifiers << 24) | (ke->event.keycode)); uint32_t key_code = ((ke->event.modifiers << 24) | (ke->event.keycode));
if (hashmap_has(yg->key_binds, (void*)key_code)) { if (hashmap_has(yg->key_binds, (void*)(uintptr_t)key_code)) {
struct key_bind * bind = hashmap_get(yg->key_binds, (void*)key_code); struct key_bind * bind = hashmap_get(yg->key_binds, (void*)(uintptr_t)key_code);
yutani_msg_buildx_key_event_alloc(response); yutani_msg_buildx_key_event_alloc(response);
yutani_msg_buildx_key_event(response,focused ? focused->wid : UINT32_MAX, &ke->event, &ke->state); yutani_msg_buildx_key_event(response,focused ? focused->wid : UINT32_MAX, &ke->event, &ke->state);
@ -1630,9 +1630,9 @@ static void handle_key_event(yutani_globals_t * yg, struct yutani_msg_key_event
* req - bind message * req - bind message
* owner - client to assign the binding to * owner - client to assign the binding to
*/ */
static void add_key_bind(yutani_globals_t * yg, struct yutani_msg_key_bind * req, unsigned int owner) { static void add_key_bind(yutani_globals_t * yg, struct yutani_msg_key_bind * req, uintptr_t owner) {
uint32_t key_code = (((uint8_t)req->modifiers << 24) | ((uint32_t)req->key & 0xFFFFFF)); uint32_t key_code = (((uint8_t)req->modifiers << 24) | ((uint32_t)req->key & 0xFFFFFF));
struct key_bind * bind = hashmap_get(yg->key_binds, (void*)key_code); struct key_bind * bind = hashmap_get(yg->key_binds, (void*)(uintptr_t)key_code);
if (!bind) { if (!bind) {
bind = malloc(sizeof(struct key_bind)); bind = malloc(sizeof(struct key_bind));
@ -1640,7 +1640,7 @@ static void add_key_bind(yutani_globals_t * yg, struct yutani_msg_key_bind * req
bind->owner = owner; bind->owner = owner;
bind->response = req->response; bind->response = req->response;
hashmap_set(yg->key_binds, (void*)key_code, bind); hashmap_set(yg->key_binds, (void*)(uintptr_t)key_code, bind);
} else { } else {
bind->owner = owner; bind->owner = owner;
bind->response = req->response; bind->response = req->response;
@ -2103,7 +2103,7 @@ int main(int argc, char * argv[]) {
yg->width = yg->backend_ctx->width; yg->width = yg->backend_ctx->width;
yg->height = yg->backend_ctx->height; yg->height = yg->backend_ctx->height;
draw_fill(yg->backend_ctx, rgb(110,110,110)); draw_fill(yg->backend_ctx, rgb(5,5,5));
flip(yg->backend_ctx); flip(yg->backend_ctx);
yg->backend_framebuffer = yg->backend_ctx->backbuffer; yg->backend_framebuffer = yg->backend_ctx->backbuffer;
@ -2388,10 +2388,10 @@ int main(int argc, char * argv[]) {
switch(m->type) { switch(m->type) {
case YUTANI_MSG_HELLO: case YUTANI_MSG_HELLO:
{ {
TRACE("And hello to you, %08x!", p->source); TRACE("And hello to you, %p!", p->source);
list_t * client_list = hashmap_get(yg->clients_to_windows, (void *)p->source); list_t * client_list = hashmap_get(yg->clients_to_windows, (void *)p->source);
if (!client_list) { if (!client_list) {
TRACE("Client is new: %x", p->source); TRACE("Client is new: %p", p->source);
client_list = list_create(); client_list = list_create();
hashmap_set(yg->clients_to_windows, (void *)p->source, client_list); hashmap_set(yg->clients_to_windows, (void *)p->source, client_list);
} }
@ -2404,7 +2404,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_NEW_FLAGS: case YUTANI_MSG_WINDOW_NEW_FLAGS:
{ {
struct yutani_msg_window_new_flags * wn = (void *)m->data; struct yutani_msg_window_new_flags * wn = (void *)m->data;
TRACE("Client %08x requested a new window (%dx%d).", p->source, wn->width, wn->height); TRACE("Client %p requested a new window (%dx%d).", p->source, wn->width, wn->height);
yutani_server_window_t * w = server_window_create(yg, wn->width, wn->height, p->source, m->type != YUTANI_MSG_WINDOW_NEW ? wn->flags : 0); yutani_server_window_t * w = server_window_create(yg, wn->width, wn->height, p->source, m->type != YUTANI_MSG_WINDOW_NEW ? wn->flags : 0);
yutani_msg_buildx_window_init_alloc(response); yutani_msg_buildx_window_init_alloc(response);
yutani_msg_buildx_window_init(response,w->wid, w->width, w->height, w->bufid); yutani_msg_buildx_window_init(response,w->wid, w->width, w->height, w->bufid);
@ -2420,7 +2420,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_FLIP: case YUTANI_MSG_FLIP:
{ {
struct yutani_msg_flip * wf = (void *)m->data; struct yutani_msg_flip * wf = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wf->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wf->wid);
if (w) { if (w) {
mark_window(yg, w); mark_window(yg, w);
} }
@ -2429,7 +2429,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_FLIP_REGION: case YUTANI_MSG_FLIP_REGION:
{ {
struct yutani_msg_flip_region * wf = (void *)m->data; struct yutani_msg_flip_region * wf = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wf->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wf->wid);
if (w) { if (w) {
mark_window_relative(yg, w, wf->x, wf->y, wf->width, wf->height); mark_window_relative(yg, w, wf->x, wf->y, wf->width, wf->height);
} }
@ -2457,7 +2457,7 @@ int main(int argc, char * argv[]) {
TRACE("Refusing to move window to these coordinates."); TRACE("Refusing to move window to these coordinates.");
break; break;
} }
yutani_server_window_t * win = hashmap_get(yg->wids_to_windows, (void*)wm->wid); yutani_server_window_t * win = hashmap_get(yg->wids_to_windows, (void*)(uintptr_t)wm->wid);
if (win) { if (win) {
window_move(yg, win, wm->x, wm->y); window_move(yg, win, wm->x, wm->y);
} else { } else {
@ -2468,7 +2468,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_CLOSE: case YUTANI_MSG_WINDOW_CLOSE:
{ {
struct yutani_msg_window_close * wc = (void *)m->data; struct yutani_msg_window_close * wc = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wc->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wc->wid);
if (w) { if (w) {
window_mark_for_close(yg, w); window_mark_for_close(yg, w);
window_remove_from_client(yg, w); window_remove_from_client(yg, w);
@ -2478,7 +2478,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_STACK: case YUTANI_MSG_WINDOW_STACK:
{ {
struct yutani_msg_window_stack * ws = (void *)m->data; struct yutani_msg_window_stack * ws = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)ws->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)ws->wid);
if (w) { if (w) {
reorder_window(yg, w, ws->z); reorder_window(yg, w, ws->z);
} }
@ -2487,7 +2487,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_RESIZE_REQUEST: case YUTANI_MSG_RESIZE_REQUEST:
{ {
struct yutani_msg_window_resize * wr = (void *)m->data; struct yutani_msg_window_resize * wr = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wr->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wr->wid);
if (w) { if (w) {
yutani_msg_buildx_window_resize_alloc(response); yutani_msg_buildx_window_resize_alloc(response);
yutani_msg_buildx_window_resize(response,YUTANI_MSG_RESIZE_OFFER, w->wid, wr->width, wr->height, 0, w->tiled); yutani_msg_buildx_window_resize(response,YUTANI_MSG_RESIZE_OFFER, w->wid, wr->width, wr->height, 0, w->tiled);
@ -2498,7 +2498,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_RESIZE_OFFER: case YUTANI_MSG_RESIZE_OFFER:
{ {
struct yutani_msg_window_resize * wr = (void *)m->data; struct yutani_msg_window_resize * wr = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wr->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wr->wid);
if (w) { if (w) {
yutani_msg_buildx_window_resize_alloc(response); yutani_msg_buildx_window_resize_alloc(response);
yutani_msg_buildx_window_resize(response,YUTANI_MSG_RESIZE_OFFER, w->wid, wr->width, wr->height, 0, w->tiled); yutani_msg_buildx_window_resize(response,YUTANI_MSG_RESIZE_OFFER, w->wid, wr->width, wr->height, 0, w->tiled);
@ -2509,7 +2509,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_RESIZE_ACCEPT: case YUTANI_MSG_RESIZE_ACCEPT:
{ {
struct yutani_msg_window_resize * wr = (void *)m->data; struct yutani_msg_window_resize * wr = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wr->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wr->wid);
if (w) { if (w) {
uint32_t newbufid = server_window_resize(yg, w, wr->width, wr->height); uint32_t newbufid = server_window_resize(yg, w, wr->width, wr->height);
yutani_msg_buildx_window_resize_alloc(response); yutani_msg_buildx_window_resize_alloc(response);
@ -2521,7 +2521,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_RESIZE_DONE: case YUTANI_MSG_RESIZE_DONE:
{ {
struct yutani_msg_window_resize * wr = (void *)m->data; struct yutani_msg_window_resize * wr = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wr->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wr->wid);
if (w) { if (w) {
server_window_resize_finish(yg, w, wr->width, wr->height); server_window_resize_finish(yg, w, wr->width, wr->height);
} }
@ -2542,7 +2542,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_SUBSCRIBE: case YUTANI_MSG_SUBSCRIBE:
{ {
foreach(node, yg->window_subscribers) { foreach(node, yg->window_subscribers) {
if ((uint32_t)node->value == p->source) { if ((uintptr_t)node->value == p->source) {
break; break;
} }
} }
@ -2560,7 +2560,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_ADVERTISE: case YUTANI_MSG_WINDOW_ADVERTISE:
{ {
struct yutani_msg_window_advertise * wa = (void *)m->data; struct yutani_msg_window_advertise * wa = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wa->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wa->wid);
if (w) { if (w) {
if (w->client_strings) free(w->client_strings); if (w->client_strings) free(w->client_strings);
@ -2587,7 +2587,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS: case YUTANI_MSG_WINDOW_FOCUS:
{ {
struct yutani_msg_window_focus * wa = (void *)m->data; struct yutani_msg_window_focus * wa = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wa->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wa->wid);
if (w) { if (w) {
set_focused_window(yg, w); set_focused_window(yg, w);
} }
@ -2602,7 +2602,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_DRAG_START: case YUTANI_MSG_WINDOW_DRAG_START:
{ {
struct yutani_msg_window_drag_start * wa = (void *)m->data; struct yutani_msg_window_drag_start * wa = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wa->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wa->wid);
if (w) { if (w) {
/* Start dragging */ /* Start dragging */
mouse_start_drag(yg, w); mouse_start_drag(yg, w);
@ -2612,7 +2612,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_UPDATE_SHAPE: case YUTANI_MSG_WINDOW_UPDATE_SHAPE:
{ {
struct yutani_msg_window_update_shape * wa = (void *)m->data; struct yutani_msg_window_update_shape * wa = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wa->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wa->wid);
if (w) { if (w) {
/* Set shape parameter */ /* Set shape parameter */
server_window_update_shape(yg, w, wa->set_shape); server_window_update_shape(yg, w, wa->set_shape);
@ -2622,7 +2622,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_WARP_MOUSE: case YUTANI_MSG_WINDOW_WARP_MOUSE:
{ {
struct yutani_msg_window_warp_mouse * wa = (void *)m->data; struct yutani_msg_window_warp_mouse * wa = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wa->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wa->wid);
if (w) { if (w) {
if (yg->focused_window == w) { if (yg->focused_window == w) {
int32_t x, y; int32_t x, y;
@ -2643,7 +2643,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_SHOW_MOUSE: case YUTANI_MSG_WINDOW_SHOW_MOUSE:
{ {
struct yutani_msg_window_show_mouse * wa = (void *)m->data; struct yutani_msg_window_show_mouse * wa = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wa->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wa->wid);
if (w) { if (w) {
if (wa->show_mouse == -1) { if (wa->show_mouse == -1) {
w->show_mouse = w->default_mouse; w->show_mouse = w->default_mouse;
@ -2662,7 +2662,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_RESIZE_START: case YUTANI_MSG_WINDOW_RESIZE_START:
{ {
struct yutani_msg_window_resize_start * wa = (void *)m->data; struct yutani_msg_window_resize_start * wa = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wa->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)wa->wid);
if (w) { if (w) {
if (yg->focused_window == w && !yg->resizing_window) { if (yg->focused_window == w && !yg->resizing_window) {
yg->resizing_window = w; yg->resizing_window = w;
@ -2675,7 +2675,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_SPECIAL_REQUEST: case YUTANI_MSG_SPECIAL_REQUEST:
{ {
struct yutani_msg_special_request * sr = (void *)m->data; struct yutani_msg_special_request * sr = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)sr->wid); yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)(uintptr_t)sr->wid);
switch (sr->request) { switch (sr->request) {
case YUTANI_SPECIAL_REQUEST_MAXIMIZE: case YUTANI_SPECIAL_REQUEST_MAXIMIZE:
if (w) { if (w) {

6
apps/demo.c Normal file
View File

@ -0,0 +1,6 @@
#include <stdio.h>
int main(int argc, char * argv[]) {
printf("Hello, world! I am %s! I was called with '%s'\n", argv[0], argv[1]);
return 0;
}

4
apps/demo.krk Normal file
View File

@ -0,0 +1,4 @@
import os, kuroko
print('Kuroko',kuroko.version, kuroko.buildenv, kuroko.builddate)
print('Running on:',os.uname())

374
apps/dhcp_bitbanger.c Normal file
View File

@ -0,0 +1,374 @@
#include <stdint.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
struct ethernet_packet {
uint8_t destination[6];
uint8_t source[6];
uint16_t type;
uint8_t payload[];
} __attribute__((packed)) __attribute__((aligned(2)));
struct ipv4_packet {
uint8_t version_ihl;
uint8_t dscp_ecn;
uint16_t length;
uint16_t ident;
uint16_t flags_fragment;
uint8_t ttl;
uint8_t protocol;
uint16_t checksum;
uint32_t source;
uint32_t destination;
uint8_t payload[];
} __attribute__ ((packed)) __attribute__((aligned(2)));
struct udp_packet {
uint16_t source_port;
uint16_t destination_port;
uint16_t length;
uint16_t checksum;
uint8_t payload[];
} __attribute__ ((packed)) __attribute__((aligned(2)));
struct dhcp_packet {
uint8_t op;
uint8_t htype;
uint8_t hlen;
uint8_t hops;
uint32_t xid;
uint16_t secs;
uint16_t flags;
uint32_t ciaddr;
uint32_t yiaddr;
uint32_t siaddr;
uint32_t giaddr;
uint8_t chaddr[16];
uint8_t sname[64];
uint8_t file[128];
uint32_t magic;
uint8_t options[];
} __attribute__ ((packed)) __attribute__((aligned(2)));
struct dns_packet {
uint16_t qid;
uint16_t flags;
uint16_t questions;
uint16_t answers;
uint16_t authorities;
uint16_t additional;
uint8_t data[];
} __attribute__ ((packed)) __attribute__((aligned(2)));
struct tcp_header {
uint16_t source_port;
uint16_t destination_port;
uint32_t seq_number;
uint32_t ack_number;
uint16_t flags;
uint16_t window_size;
uint16_t checksum;
uint16_t urgent;
uint8_t payload[];
} __attribute__((packed)) __attribute__((aligned(2)));
struct tcp_check_header {
uint32_t source;
uint32_t destination;
uint8_t zeros;
uint8_t protocol;
uint16_t tcp_len;
uint8_t tcp_header[];
};
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
// Note: Data offset is in upper 4 bits of flags field. Shift and subtract 5 since that is the min TCP size.
// If the value is more than 5, multiply by 4 because this field is specified in number of words
#define TCP_OPTIONS_LENGTH(tcp) (((((tcp)->flags) >> 12) - 5) * 4)
#define TCP_HEADER_LENGTH(tcp) ((((tcp)->flags) >> 12) * 4)
#define TCP_HEADER_LENGTH_FLIPPED(tcp) (((htons((tcp)->flags)) >> 12) * 4)
#define htonl(l) ( (((l) & 0xFF) << 24) | (((l) & 0xFF00) << 8) | (((l) & 0xFF0000) >> 8) | (((l) & 0xFF000000) >> 24))
#define htons(s) ( (((s) & 0xFF) << 8) | (((s) & 0xFF00) >> 8) )
#define ntohl(l) htonl((l))
#define ntohs(s) htons((s))
#define BROADCAST_MAC {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
#define IPV4_PROT_UDP 17
#define IPV4_PROT_TCP 6
#define DHCP_MAGIC 0x63825363
#define TCP_FLAGS_FIN (1 << 0)
#define TCP_FLAGS_SYN (1 << 1)
#define TCP_FLAGS_RES (1 << 2)
#define TCP_FLAGS_PSH (1 << 3)
#define TCP_FLAGS_ACK (1 << 4)
#define TCP_FLAGS_URG (1 << 5)
#define TCP_FLAGS_ECE (1 << 6)
#define TCP_FLAGS_CWR (1 << 7)
#define TCP_FLAGS_NS (1 << 8)
#define DATA_OFFSET_5 (0x5 << 12)
#define ETHERNET_TYPE_IPV4 0x0800
#define ETHERNET_TYPE_ARP 0x0806
struct payload {
struct ethernet_packet eth_header;
struct ipv4_packet ip_header;
struct udp_packet udp_header;
struct dhcp_packet dhcp_header;
uint8_t payload[32];
};
static void eth_ntoa(const uint8_t addr[6], char * out) {
/* XX:XX:XX:XX:XX:XX */
snprintf(out, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
addr[0], addr[1], addr[2],
addr[3], addr[4], addr[5]);
}
static void ip_ntoa(const uint32_t src_addr, char * out) {
snprintf(out, 16, "%d.%d.%d.%d",
(src_addr & 0xFF000000) >> 24,
(src_addr & 0xFF0000) >> 16,
(src_addr & 0xFF00) >> 8,
(src_addr & 0xFF));
}
static const char * eth_type_str(uint16_t type) {
switch(type) {
case ETHERNET_TYPE_IPV4: return "IPv4";
case ETHERNET_TYPE_ARP: return "ARP";
default: return "unknown";
}
}
static void print_ipv4_header(struct ipv4_packet * packet) {
/* get addresses, type... */
char dest_addr[16];
char src_addr[16];
ip_ntoa(ntohl(packet->destination), dest_addr);
ip_ntoa(ntohl(packet->source), src_addr);
fprintf(stderr, "%s -> %s %d (%s) ",
src_addr, dest_addr, packet->protocol,
packet->protocol == IPV4_PROT_UDP ? "udp" :
packet->protocol == IPV4_PROT_TCP ? "tcp" : "?");
}
void print_header(const struct payload * header) {
/* Assume it's at least an Ethernet frame */
char dest_addr[18];
char src_addr[18];
eth_ntoa(header->eth_header.destination, dest_addr);
eth_ntoa(header->eth_header.source, src_addr);
fprintf(stderr, "%s -> %s %d (%s) ",
src_addr, dest_addr, ntohs(header->eth_header.type), eth_type_str(ntohs(header->eth_header.type)));
switch (ntohs(header->eth_header.type)) {
case ETHERNET_TYPE_IPV4:
print_ipv4_header((void*)&header->eth_header.payload);
break;
case ETHERNET_TYPE_ARP:
//print_arp_header(&header->eth_header.payload);
break;
}
fprintf(stderr, "\n");
}
uint16_t calculate_ipv4_checksum(struct ipv4_packet * p) {
uint32_t sum = 0;
uint16_t * s = (uint16_t *)p;
/* TODO: Checksums for options? */
for (int i = 0; i < 10; ++i) {
sum += ntohs(s[i]);
}
if (sum > 0xFFFF) {
sum = (sum >> 16) + (sum & 0xFFFF);
}
return ~(sum & 0xFFFF) & 0xFFFF;
}
uint8_t mac_addr[6];
void fill(struct payload *it, size_t payload_size) {
it->eth_header.source[0] = mac_addr[0];
it->eth_header.source[1] = mac_addr[1];
it->eth_header.source[2] = mac_addr[2];
it->eth_header.source[3] = mac_addr[3];
it->eth_header.source[4] = mac_addr[4];
it->eth_header.source[5] = mac_addr[5];
it->eth_header.destination[0] = 0xFF;
it->eth_header.destination[1] = 0xFF;
it->eth_header.destination[2] = 0xFF;
it->eth_header.destination[3] = 0xFF;
it->eth_header.destination[4] = 0xFF;
it->eth_header.destination[5] = 0xFF;
it->eth_header.type = htons(0x0800);
it->ip_header.version_ihl = ((0x4 << 4) | (0x5 << 0));
it->ip_header.dscp_ecn = 0;
it->ip_header.length = htons(sizeof(struct ipv4_packet) + sizeof(struct udp_packet) + sizeof(struct dhcp_packet) + payload_size);
it->ip_header.ident = htons(1);
it->ip_header.flags_fragment = 0;
it->ip_header.ttl = 0x40;
it->ip_header.protocol = IPV4_PROT_UDP;
it->ip_header.checksum = 0;
it->ip_header.source = htonl(0);
it->ip_header.destination = htonl(0xFFFFFFFF);
it->ip_header.checksum = htons(calculate_ipv4_checksum(&it->ip_header));
it->udp_header.source_port = htons(68);
it->udp_header.destination_port = htons(67);
it->udp_header.length = htons(sizeof(struct udp_packet) + sizeof(struct dhcp_packet) + payload_size);
it->udp_header.checksum = 0; /* uh */
it->dhcp_header.op = 1;
it->dhcp_header.htype = 1;
it->dhcp_header.hlen = 6;
it->dhcp_header.hops = 0;
it->dhcp_header.xid = htons(0x1337); /* transaction id... */
it->dhcp_header.secs = 0;
it->dhcp_header.flags = 0;
it->dhcp_header.ciaddr = 0;
it->dhcp_header.yiaddr = 0;
it->dhcp_header.siaddr = 0;
it->dhcp_header.giaddr = 0;
it->dhcp_header.chaddr[0] = mac_addr[0];
it->dhcp_header.chaddr[1] = mac_addr[1];
it->dhcp_header.chaddr[2] = mac_addr[2];
it->dhcp_header.chaddr[3] = mac_addr[3];
it->dhcp_header.chaddr[4] = mac_addr[4];
it->dhcp_header.chaddr[5] = mac_addr[5];
it->dhcp_header.magic = htonl(DHCP_MAGIC);
}
int main(int argc, char * argv[]) {
#if 0
/* Let's make a socket. */
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) { perror("socket"); return 1; }
/* Bind the socket to the requested device. */
//if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
#endif
char * if_name = "enp0s4";
char if_path[100];
if (argc > 1) {
if_name = argv[1];
}
snprintf(if_path, 100, "/dev/net/%s", if_name);
int netdev = open(if_path, O_RDWR);
fprintf(stderr, "Configuring %s\n", if_name);
if (ioctl(netdev, 0x12340001, &mac_addr)) {
fprintf(stderr, "could not get mac address\n");
return 1;
}
fprintf(stderr, "mac address: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5]);
/* Try to frob the whatsit */
{
struct payload thething = {
.payload = {53,1,1,55,2,3,6,255,0}
};
fill(&thething, 8);
write(netdev, &thething, sizeof(struct payload));
}
uint32_t yiaddr;
int stage = 1;
do {
char buf[8092] = {0};
struct pollfd fds[1];
fds[0].fd = netdev;
fds[0].events = POLLIN;
int ret = poll(fds,1,2000);
if (ret <= 0) {
printf("...\n");
continue;
}
ssize_t rsize = read(netdev, &buf, 8092);
if (rsize <= 0) {
printf("bad size? %zd\n", rsize);
continue;
}
struct payload * response = (void*)buf;
print_header(response);
if (ntohs(response->udp_header.destination_port) != 68) {
continue;
}
if (stage == 1) {
yiaddr = response->dhcp_header.yiaddr;
char yiaddr_ip[16];
ip_ntoa(ntohl(yiaddr), yiaddr_ip);
printf("Response from DHCP Discover: %s\n", yiaddr_ip);
struct payload thething = {
.payload = {53,1,3,50,4,
(yiaddr) & 0xFF,
(yiaddr >> 8) & 0xFF,
(yiaddr >> 16) & 0xFF,
(yiaddr >> 24) & 0xFF,
55,2,3,6,255,0}
};
fill(&thething, 14);
write(netdev, &thething, sizeof(struct payload));
stage = 2;
} else if (stage == 2) {
yiaddr = response->dhcp_header.yiaddr;
char yiaddr_ip[16];
ip_ntoa(ntohl(yiaddr), yiaddr_ip);
printf("ACK returns: %s\n", yiaddr_ip);
printf("Address is configured, continuing trace mode.\n");
stage = 3;
}
} while (1);
return 0;
}

View File

@ -38,7 +38,7 @@ static int print_human_readable_size(char * _out, size_t s) {
} }
static void print_size(uint64_t size, char * name) { static void print_size(uint64_t size, char * name) {
char sizes[8]; char sizes[30];
if (!human) { if (!human) {
sprintf(sizes, "%-7llu", size/1024LLU); sprintf(sizes, "%-7llu", size/1024LLU);
} else { } else {

View File

@ -289,7 +289,7 @@ int main(int argc, char * argv[]) {
struct http_req my_req; struct http_req my_req;
parse_url(argv[optind], &my_req); parse_url(argv[optind], &my_req);
char file[100]; char file[600];
sprintf(file, "/dev/net/%s", my_req.domain); sprintf(file, "/dev/net/%s", my_req.domain);
if (fetch_options.calculate_output) { if (fetch_options.calculate_output) {

View File

@ -85,7 +85,7 @@ static int nav_bar_cursor_x = 0;
static int nav_bar_focused = 0; static int nav_bar_focused = 0;
/* Status bar displayed at the bottom of the window */ /* Status bar displayed at the bottom of the window */
static char window_status[512] = {0}; static char window_status[1024] = {0};
/* Button row visibility statuses */ /* Button row visibility statuses */
static int _button_hilights[4] = {3,3,3,3}; static int _button_hilights[4] = {3,3,3,3};
@ -435,7 +435,7 @@ static void update_status(void) {
char tmp_size[50]; char tmp_size[50];
if (selected_count == 0) { if (selected_count == 0) {
print_human_readable_size(tmp_size, total_size); print_human_readable_size(tmp_size, total_size);
sprintf(window_status, "%d item%s (%s)", file_pointers_len, file_pointers_len == 1 ? "" : "s", tmp_size); sprintf(window_status, "%zd item%s (%s)", file_pointers_len, file_pointers_len == 1 ? "" : "s", tmp_size);
} else if (selected_count == 1) { } else if (selected_count == 1) {
print_human_readable_size(tmp_size, selected->size); print_human_readable_size(tmp_size, selected->size);
sprintf(window_status, "\"%s\" (%s) %s", selected->name, tmp_size, selected->filetype); sprintf(window_status, "\"%s\" (%s) %s", selected->name, tmp_size, selected->filetype);
@ -1955,7 +1955,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win == main_window) { if (win == main_window) {
win->focused = wf->focused; win->focused = wf->focused;
redraw_files(); redraw_files();
@ -1994,7 +1994,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_MOUSE_EVENT: case YUTANI_MSG_WINDOW_MOUSE_EVENT:
{ {
struct yutani_msg_window_mouse_event * me = (void*)m->data; struct yutani_msg_window_mouse_event * me = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)me->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)me->wid);
struct decor_bounds bounds; struct decor_bounds bounds;
_decor_get_bounds(win, &bounds); _decor_get_bounds(win, &bounds);

View File

@ -1,16 +0,0 @@
#!/bin/sh
# Start font server if freetype is available
if stat -Lq /usr/lib/libfreetype.so then font-server
if empty? "$1" then export WIDTH=1024 else export WIDTH="$1"
if empty? "$2" then export HEIGHT=768 else export HEIGHT="$2"
# Switch to graphics mode
if not set-resolution --initialize auto $WIDTH $HEIGHT then exec sh -c "echo 'Failed to set video mode, bailing.'; exit 1"
# Tell the terminal to pause input
killall -s USR2 terminal-vga
# Start the compositor
compositor

View File

@ -118,13 +118,13 @@ static void write_buffer(void) {
static int parser_open(struct markup_state * self, void * user, struct markup_tag * tag) { static int parser_open(struct markup_state * self, void * user, struct markup_tag * tag) {
if (!strcmp(tag->name, "b")) { if (!strcmp(tag->name, "b")) {
list_insert(state, (void*)current_state); list_insert(state, (void*)(uintptr_t)current_state);
current_state |= (1 << 0); current_state |= (1 << 0);
} else if (!strcmp(tag->name, "i")) { } else if (!strcmp(tag->name, "i")) {
list_insert(state, (void*)current_state); list_insert(state, (void*)(uintptr_t)current_state);
current_state |= (1 << 1); current_state |= (1 << 1);
} else if (!strcmp(tag->name, "h1")) { } else if (!strcmp(tag->name, "h1")) {
list_insert(state, (void*)current_state); list_insert(state, (void*)(uintptr_t)current_state);
current_state |= (1 << 2); current_state |= (1 << 2);
} else if (!strcmp(tag->name, "br")) { } else if (!strcmp(tag->name, "br")) {
write_buffer(); write_buffer();
@ -138,18 +138,18 @@ static int parser_open(struct markup_state * self, void * user, struct markup_ta
static int parser_close(struct markup_state * self, void * user, char * tag_name) { static int parser_close(struct markup_state * self, void * user, char * tag_name) {
if (!strcmp(tag_name, "b")) { if (!strcmp(tag_name, "b")) {
node_t * nstate = list_pop(state); node_t * nstate = list_pop(state);
current_state = (int)nstate->value; current_state = (int)(uintptr_t)nstate->value;
free(nstate); free(nstate);
} else if (!strcmp(tag_name, "i")) { } else if (!strcmp(tag_name, "i")) {
node_t * nstate = list_pop(state); node_t * nstate = list_pop(state);
current_state = (int)nstate->value; current_state = (int)(uintptr_t)nstate->value;
free(nstate); free(nstate);
} else if (!strcmp(tag_name, "h1")) { } else if (!strcmp(tag_name, "h1")) {
write_buffer(); write_buffer();
cursor_x = BASE_X; cursor_x = BASE_X;
cursor_y += current_line_height(); cursor_y += current_line_height();
node_t * nstate = list_pop(state); node_t * nstate = list_pop(state);
current_state = (int)nstate->value; current_state = (int)(uintptr_t)nstate->value;
free(nstate); free(nstate);
} }
return 0; return 0;
@ -413,7 +413,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win == main_window) { if (win == main_window) {
win->focused = wf->focused; win->focused = wf->focused;
redraw_window(); redraw_window();
@ -431,7 +431,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_MOUSE_EVENT: case YUTANI_MSG_WINDOW_MOUSE_EVENT:
{ {
struct yutani_msg_window_mouse_event * me = (void*)m->data; struct yutani_msg_window_mouse_event * me = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)me->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)me->wid);
if (win == main_window) { if (win == main_window) {
int result = decor_handle_event(yctx, m); int result = decor_handle_event(yctx, m);

11
apps/ifconfig.c Normal file
View File

@ -0,0 +1,11 @@
/**
* @file apps/ifconfig.c
* @brief Network interface configuration tool.
*
* Manipulates and enumerates network interfaces.
*/
#include <stdio.h>
int main(int argc, char * argv[]) {
/* I have no idea how this works on Linux or BSD, but based on some manpages... */
}

View File

@ -190,7 +190,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win && win == window) { if (win && win == window) {
win->focused = wf->focused; win->focused = wf->focused;
decors(); decors();

View File

@ -24,19 +24,19 @@ int main(int argc, char * argv[]) {
{ {
Value * result = json_parse("-123"); Value * result = json_parse("-123");
assert(result && result->type == JSON_TYPE_NUMBER); assert(result && result->type == JSON_TYPE_NUMBER);
assert(fabs(result->number - (-123.0) < 0.0001)); assert(fabs(result->number - (-123.0)) < 0.0001);
} }
{ {
Value * result = json_parse("2e3"); Value * result = json_parse("2e3");
assert(result && result->type == JSON_TYPE_NUMBER); assert(result && result->type == JSON_TYPE_NUMBER);
assert(fabs(result->number - (2000.0) < 0.0001)); assert(fabs(result->number - (2000.0)) < 0.0001);
} }
{ {
Value * result = json_parse("0.124"); Value * result = json_parse("0.124");
assert(result && result->type == JSON_TYPE_NUMBER); assert(result && result->type == JSON_TYPE_NUMBER);
assert(fabs(result->number - (0.124) < 0.0001)); assert(fabs(result->number - (0.124)) < 0.0001);
} }
{ {

View File

@ -299,7 +299,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win && win == window) { if (win && win == window) {
win->focused = wf->focused; win->focused = wf->focused;
decors(); decors();

View File

@ -31,7 +31,7 @@ typedef struct process {
#define LINE_LEN 4096 #define LINE_LEN 4096
p_t * build_entry(struct dirent * dent) { p_t * build_entry(struct dirent * dent) {
char tmp[256]; char tmp[300];
FILE * f; FILE * f;
char line[LINE_LEN]; char line[LINE_LEN];

File diff suppressed because it is too large Load Diff

View File

@ -63,10 +63,16 @@ struct {
{0x15ad, 0x0405, "SVGA II Adapter"}, {0x15ad, 0x0405, "SVGA II Adapter"},
{0x15ad, 0x0790, "PCI bridge"}, {0x15ad, 0x0790, "PCI bridge"},
{0x15ad, 0x07a0, "PCI Express Root Port"}, {0x15ad, 0x07a0, "PCI Express Root Port"},
{0x8086, 0x100e, "Gigabit Ethernet Controller (e1000)"}, {0x8086, 0x1004, "82543GC Gigabit Ethernet Controller (e1000)"},
{0x8086, 0x100f, "Gigabit Ethernet Controller (e1000)"}, {0x8086, 0x100e, "82540EM Gigabit Ethernet Controller (e1000)"},
{0x8086, 0x100f, "82545EM Gigabit Ethernet Controller (e1000)"},
{0x8086, 0x10ea, "82577LM Gigabit Ethernet Controller (e1000)"},
{0x8086, 0x1237, "PCI & Memory"}, {0x8086, 0x1237, "PCI & Memory"},
{0x8086, 0x2415, "AC'97 Audio Chipset"}, {0x8086, 0x2415, "82801AA AC'97 Audio Controller"},
{0x8086, 0x29c0, "DRAM Controller"},
{0x8086, 0x2918, "ICH9 LPC Interface Controller"},
{0x8086, 0x2922, "ICH9 6-port SATA Controller"},
{0x8086, 0x2930, "ICH9 SMBus Controller"},
{0x8086, 0x7000, "PCI-to-ISA Bridge"}, {0x8086, 0x7000, "PCI-to-ISA Bridge"},
{0x8086, 0x7010, "IDE Interface"}, {0x8086, 0x7010, "IDE Interface"},
{0x8086, 0x7110, "PIIX4 ISA"}, {0x8086, 0x7110, "PIIX4 ISA"},

View File

@ -217,7 +217,7 @@ int main(int argc, char * argv[]) {
} }
char * root_type = hashmap_get(cmdline,"root_type"); char * root_type = hashmap_get(cmdline,"root_type");
if (!root_type) { if (!root_type) {
root_type = "ext2"; root_type = "tar";
} }
char tmp[1024]; char tmp[1024];

66
apps/misaka-test.c Normal file
View File

@ -0,0 +1,66 @@
/**
* @file misaka-test.c
* @brief Test app for Misaka with a bunch of random stuff.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <toaru/graphics.h>
#include <kuroko/kuroko.h>
#include <kuroko/vm.h>
static void demo_runKurokoSnippet(void) {
krk_initVM(0);
krk_startModule("__main__");
krk_interpret("import kuroko\nprint('Kuroko',kuroko.version)\n", "<stdin>");
krk_freeVM();
}
static void demo_drawWallpaper(void) {
/* Set up a wrapper context for the framebuffer */
gfx_context_t * ctx = init_graphics_fullscreen();
/* Load the wallpaper. */
sprite_t wallpaper = { 0 };
load_sprite(&wallpaper, "/usr/share/wallpaper.jpg");
wallpaper.alpha = ALPHA_EMBEDDED;
printf("wallpaper sprite info: %d x %d\n", wallpaper.width, wallpaper.height);
draw_sprite_scaled(ctx, &wallpaper, 0, 0, 1440, 900);
flip(ctx);
//blur_context_box(&ctx, 10);
}
int main(int argc, char * argv[]) {
demo_drawWallpaper();
demo_runKurokoSnippet();
//execve("/bin/kuroko",(char*[]){"kuroko",NULL},(char*[]){NULL});
char * args[] = {
"/bin/sh",
"-c",
"sleep 2; echo hi; echo glorp",
NULL,
};
pid_t pid = fork();
if (!pid) {
printf("returned from fork in child\n");
execvp(args[0], args);
exit(1);
} else {
printf("returned from fork with pid = %d\n", pid);
int status;
waitpid(pid, &status, 0);
printf("done with waitpid, looping\n");
while (1) {
sched_yield();
}
return WEXITSTATUS(status);
}
return 0;
}

View File

@ -423,8 +423,8 @@ static int install_packages(int argc, char * argv[]) {
} }
fprintf(stderr, "\nContinue? [Y/n] "); fprintf(stderr, "\nContinue? [Y/n] ");
fflush(stderr); fflush(stderr);
char resp[4]; char resp[5];
fgets(resp, 4, stdin); fgets(resp, 5, stdin);
if (!(!strcmp(resp,"\n") || !strcmp(resp,"y\n") || !strcmp(resp,"Y\n") || !strcmp(resp,"yes\n"))) { if (!(!strcmp(resp,"\n") || !strcmp(resp,"y\n") || !strcmp(resp,"Y\n") || !strcmp(resp,"yes\n"))) {
fprintf(stderr, "Aborting.\n"); fprintf(stderr, "Aborting.\n");
return 1; return 1;

View File

@ -552,7 +552,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win == main_window) { if (win == main_window) {
win->focused = wf->focused; win->focused = wf->focused;
redraw_packages(); redraw_packages();
@ -571,7 +571,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_MOUSE_EVENT: case YUTANI_MSG_WINDOW_MOUSE_EVENT:
{ {
struct yutani_msg_window_mouse_event * me = (void*)m->data; struct yutani_msg_window_mouse_event * me = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)me->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)me->wid);
if (win == main_window) { if (win == main_window) {
int result = decor_handle_event(yctx, m); int result = decor_handle_event(yctx, m);

View File

@ -26,7 +26,7 @@ typedef struct process {
#define LINE_LEN 4096 #define LINE_LEN 4096
p_t * build_entry(struct dirent * dent) { p_t * build_entry(struct dirent * dent) {
char tmp[256]; char tmp[300];
FILE * f; FILE * f;
char line[LINE_LEN]; char line[LINE_LEN];

View File

@ -163,7 +163,7 @@ int main (int argc, char ** argv) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win && win == wina) { if (win && win == wina) {
win->focused = wf->focused; win->focused = wf->focused;
} }

View File

@ -177,7 +177,7 @@ void update_stuff(void) {
if (colliding(&ball, &left)) { if (colliding(&ball, &left)) {
ball.x = left.x + left.width + 2; ball.x = left.x + left.width + 2;
ball.vel_x = (abs(ball.vel_x) < 8.0) ? -ball.vel_x * 1.05 : -ball.vel_x; ball.vel_x = (fabs(ball.vel_x) < 8.0) ? -ball.vel_x * 1.05 : -ball.vel_x;
double intersect = ((ball.y + ball.height/2) - (left.y)) / ((double)left.height) - 0.5; double intersect = ((ball.y + ball.height/2) - (left.y)) / ((double)left.height) - 0.5;
ball.vel_y = intersect * 8.0; ball.vel_y = intersect * 8.0;
@ -186,7 +186,7 @@ void update_stuff(void) {
if (colliding(&ball, &right)) { if (colliding(&ball, &right)) {
ball.x = right.x - ball.width - 2; ball.x = right.x - ball.width - 2;
ball.vel_x = (abs(ball.vel_x) < 8.0) ? -ball.vel_x * 1.05 : -ball.vel_x; ball.vel_x = (fabs(ball.vel_x) < 8.0) ? -ball.vel_x * 1.05 : -ball.vel_x;
double intersect = ((ball.y + ball.height/2) - (right.y)) / ((double)right.height/2.0); double intersect = ((ball.y + ball.height/2) - (right.y)) / ((double)right.height/2.0);
ball.vel_y = intersect * 3.0; ball.vel_y = intersect * 3.0;

View File

@ -55,7 +55,7 @@ void print_username(int uid) {
} }
struct process * process_entry(struct dirent *dent) { struct process * process_entry(struct dirent *dent) {
char tmp[256]; char tmp[300];
FILE * f; FILE * f;
char line[LINE_LEN]; char line[LINE_LEN];

View File

@ -29,7 +29,7 @@ typedef struct process {
#define LINE_LEN 4096 #define LINE_LEN 4096
p_t * build_entry(struct dirent * dent) { p_t * build_entry(struct dirent * dent) {
char tmp[256]; char tmp[300];
FILE * f; FILE * f;
char line[LINE_LEN]; char line[LINE_LEN];
@ -87,7 +87,7 @@ p_t * build_entry(struct dirent * dent) {
uint8_t find_pid(void * proc_v, void * pid_v) { uint8_t find_pid(void * proc_v, void * pid_v) {
p_t * p = proc_v; p_t * p = proc_v;
pid_t i = (pid_t)pid_v; pid_t i = (pid_t)(uintptr_t)pid_v;
return (uint8_t)(p->pid == i); return (uint8_t)(p->pid == i);
} }
@ -161,7 +161,7 @@ int main (int argc, char * argv[]) {
if (proc->ppid == 0 && proc->pid == 1) { if (proc->ppid == 0 && proc->pid == 1) {
tree_set_root(procs, proc); tree_set_root(procs, proc);
} else { } else {
tree_node_t * parent = tree_find(procs,(void *)proc->ppid,find_pid); tree_node_t * parent = tree_find(procs,(void *)(uintptr_t)proc->ppid,find_pid);
if (parent) { if (parent) {
tree_node_insert_child(procs, parent, proc); tree_node_insert_child(procs, parent, proc);
} }

View File

@ -1,256 +1,688 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab /**
* This file is part of ToaruOS and is released under the terms * @file readelf.c
* of the NCSA / University of Illinois License - see LICENSE.md * @brief Display information about a 64-bit Elf binary or object.
* Copyright (C) 2013-2018 K Lange
* *
* readelf - Show information about ELF objects * Implementation of a `readelf` utility.
*
* This is a very custom implementation and nothing remotely
* like the version that comes with binutils. Making it more
* like that version might be worthwhile.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <kernel/elf.h> #include <kernel/elf.h>
/**
* Show usage for the readelf application. static const char * elf_classToStr(unsigned char ei_class) {
* @param argc Argument count (unused) static char buf[64];
* @param argv Arguments to binary switch (ei_class) {
*/ case ELFCLASS32: return "ELF32";
void usage(int argc, char ** argv) { case ELFCLASS64: return "ELF64";
/* Show usage */ default:
printf("%s [filename]\n", argv[0]); sprintf(buf, "unknown (%d)", ei_class);
printf("\tDisplays information on ELF binaries such as section names,\n"); return buf;
printf("\tlocations, sizes, and loading positions in memory.\n"); }
exit(1);
} }
/** static const char * elf_dataToStr(unsigned char ei_data) {
* Application entry point. static char buf[64];
* @returns 0 on sucess, 1 on failure switch (ei_data) {
*/ case ELFDATA2LSB: return "2's complement, little endian";
int main(int argc, char ** argv) { case ELFDATA2MSB: return "2's complement, big endian";
/* Process arguments */ default:
if (argc < 2) usage(argc,argv); sprintf(buf, "unknown (%d)", ei_data);
return buf;
}
}
FILE * binary; /**< File pointer for requested executable */ static char * elf_versionToStr(unsigned char ei_version) {
size_t binary_size; /**< Size of the file */ static char buf[64];
char * binary_buf; /**< Buffer to store the binary in memory */ switch (ei_version) {
Elf32_Header * header; /**< ELF header */ case 1: return "1 (current)";
char * string_table = NULL; /**< The section header string table */ default:
char * sym_string_table = NULL; /**< The symbol string table */ sprintf(buf, "unknown (%d)", ei_version);
return buf;
}
}
/* Open the requested binary */ static char * elf_osabiToStr(unsigned char ei_osabi) {
binary = fopen(argv[1], "r"); static char buf[64];
switch (ei_osabi) {
case 0: return "UNIX - System V";
case 1: return "HP-UX";
case 255: return "Standalone";
default:
sprintf(buf, "unknown (%d)", ei_osabi);
return buf;
}
}
if (!binary) { static char * elf_typeToStr(Elf64_Half type) {
static char buf[64];
switch (type) {
case ET_NONE: return "NONE (No file type)";
case ET_REL: return "REL (Relocatable object file)";
case ET_EXEC: return "EXEC (Executable file)";
case ET_DYN: return "DYN (Shared object file)";
case ET_CORE: return "CORE (Core file)";
default:
sprintf(buf, "unknown (%d)", type);
return buf;
}
}
static char * elf_machineToStr(Elf64_Half machine) {
static char buf[64];
switch (machine) {
case EM_X86_64: return "Advanced Micro Devices X86-64";
default:
sprintf(buf, "unknown (%d)", machine);
return buf;
}
}
static char * sectionHeaderTypeToStr(Elf64_Word type) {
static char buf[64];
switch (type) {
case SHT_NULL: return "NULL";
case SHT_PROGBITS: return "PROGBITS";
case SHT_SYMTAB: return "SYMTAB";
case SHT_STRTAB: return "STRTAB";
case SHT_RELA: return "RELA";
case SHT_HASH: return "HASH";
case SHT_DYNAMIC: return "DYNAMIC";
case SHT_NOTE: return "NOTE";
case SHT_NOBITS: return "NOBITS";
case SHT_REL: return "REL";
case SHT_SHLIB: return "SHLIB";
case SHT_DYNSYM: return "DYNSYM";
case 0xE: return "INIT_ARRAY";
case 0xF: return "FINI_ARRAY";
case 0x6ffffff6: return "GNU_HASH";
case 0x6ffffffe: return "VERNEED";
case 0x6fffffff: return "VERSYM";
default:
sprintf(buf, "(%x)", type);
return buf;
}
}
static char * programHeaderTypeToStr(Elf64_Word type) {
static char buf[64];
switch (type) {
case PT_NULL: return "NULL";
case PT_LOAD: return "LOAD";
case PT_DYNAMIC: return "DYNAMIC";
case PT_INTERP: return "INTERP";
case PT_NOTE: return "NOTE";
case PT_PHDR: return "PHDR";
case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
case 0x6474e553: return "GNU_PROPERTY";
case 0x6474e551: return "GNU_STACK";
case 0x6474e552: return "GNU_RELRO";
default:
sprintf(buf, "(%x)", type);
return buf;
}
}
static char * programHeaderFlagsToStr(Elf64_Word flags) {
static char buf[10];
snprintf(buf, 10, "%c%c%c ",
(flags & PF_R) ? 'R' : ' ',
(flags & PF_W) ? 'W' : ' ',
(flags & PF_X) ? 'E' : ' '); /* yes, E, not X... */
return buf;
}
static char * dynamicTagToStr(Elf64_Dyn * dynEntry, char * dynstr) {
static char buf[1024];
static char extra[500];
char * name = NULL;
sprintf(extra, "0x%lx", dynEntry->d_un.d_val);
switch (dynEntry->d_tag) {
case DT_NULL:
name = "(NULL)";
break;
case DT_NEEDED:
name = "(NEEDED)";
sprintf(extra, "[shared lib = %s]", dynstr + dynEntry->d_un.d_val);
break;
case DT_PLTRELSZ:
name = "(PLTRELSZ)";
break;
case DT_PLTGOT:
name = "(PLTGOT)";
break;
case DT_HASH:
name = "(HASH)";
break;
case DT_STRTAB:
name = "(STRTAB)";
break;
case DT_SYMTAB:
name = "(SYMTAB)";
break;
case DT_RELA:
name = "(RELA)";
break;
case DT_RELASZ:
name = "(RELASZ)";
break;
case DT_RELAENT:
name = "(RELAENT)";
break;
case DT_STRSZ:
name = "(STRSZ)";
sprintf(extra, "%ld (bytes)", dynEntry->d_un.d_val);
break;
case DT_SYMENT:
name = "(SYMENT)";
sprintf(extra, "%ld (bytes)", dynEntry->d_un.d_val);
break;
case DT_INIT:
name = "(INIT)";
break;
case DT_FINI:
name = "(FINI)";
break;
case DT_SONAME:
name = "(SONAME)";
break;
case DT_RPATH:
name = "(RPATH)";
break;
case DT_SYMBOLIC:
name = "(SYMBOLIC)";
break;
case DT_REL:
name = "(REL)";
break;
case DT_RELSZ:
name = "(RELSZ)";
sprintf(extra, "%ld (bytes)", dynEntry->d_un.d_val);
break;
case DT_RELENT:
name = "(RELENT)";
break;
case DT_PLTREL:
name = "(PLTREL)";
sprintf(extra, "%s",
dynEntry->d_un.d_val == DT_REL ? "REL" : "RELA");
break;
case DT_DEBUG:
name = "(DEBUG)";
break;
case DT_TEXTREL:
name = "(TEXTREL)";
break;
case DT_JMPREL:
name = "(JMPREL)";
break;
case DT_BIND_NOW:
name = "(BIND_NOW)";
break;
case DT_INIT_ARRAY:
name = "(INIT_ARRAY)";
break;
case DT_FINI_ARRAY:
name = "(FINI_ARRAY)";
break;
case DT_INIT_ARRAYSZ:
name = "(INIT_ARRAYSZ)";
sprintf(extra, "%ld (bytes)", dynEntry->d_un.d_val);
break;
case DT_FINI_ARRAYSZ:
name = "(FINI_ARRASZ)";
sprintf(extra, "%ld (bytes)", dynEntry->d_un.d_val);
break;
case 0x1E:
name = "(FLAGS)";
break;
case 0x6ffffef5:
name = "(GNU_HASH)";
break;
case 0x6ffffffb:
name = "(FLAGS_1)";
break;
case 0x6ffffffe:
name = "(VERNEED)";
break;
case 0x6fffffff:
name = "(VERNEEDNUM)";
sprintf(extra, "%ld", dynEntry->d_un.d_val);
break;
case 0x6ffffff0:
name = "(VERSYM)";
break;
case 0x6ffffff9:
name = "(RELACOUNT)";
sprintf(extra, "%ld", dynEntry->d_un.d_val);
break;
default:
name = "(unknown)";
break;
}
sprintf(buf,"%-15s %s", name, extra);
return buf;
}
static char * relocationInfoToStr(Elf64_Xword info) {
#define CASE(o) case o: return #o;
switch (info) {
CASE(R_X86_64_NONE)
CASE(R_X86_64_64)
CASE(R_X86_64_PC32)
CASE(R_X86_64_GOT32)
CASE(R_X86_64_PLT32)
CASE(R_X86_64_COPY)
CASE(R_X86_64_GLOB_DAT)
CASE(R_X86_64_JUMP_SLOT)
CASE(R_X86_64_RELATIVE)
CASE(R_X86_64_GOTPCREL)
CASE(R_X86_64_32)
CASE(R_X86_64_32S)
CASE(R_X86_64_DTPMOD64)
CASE(R_X86_64_DTPOFF64)
CASE(R_X86_64_TPOFF64)
CASE(R_X86_64_TLSGD)
CASE(R_X86_64_TLSLD)
CASE(R_X86_64_DTPOFF32)
CASE(R_X86_64_GOTTPOFF)
CASE(R_X86_64_TPOFF32)
CASE(R_X86_64_PC64)
CASE(R_X86_64_GOTOFF64)
CASE(R_X86_64_GOTPC32)
CASE(R_X86_64_GOT64)
CASE(R_X86_64_GOTPCREL64)
CASE(R_X86_64_GOTPC64)
CASE(R_X86_64_GOTPLT64)
CASE(R_X86_64_PLTOFF64)
CASE(R_X86_64_SIZE32)
CASE(R_X86_64_SIZE64)
CASE(R_X86_64_GOTPC32_TLSDESC)
CASE(R_X86_64_TLSDESC_CALL)
CASE(R_X86_64_TLSDESC)
CASE(R_X86_64_IRELATIVE)
default:
return "unknown";
}
#undef CASE
}
static int sizeOfRelocationValue(int type) {
switch (type) {
case R_X86_64_TLSDESC:
return 16;
case R_X86_64_64:
case R_X86_64_GLOB_DAT:
case R_X86_64_JUMP_SLOT:
case R_X86_64_RELATIVE:
case R_X86_64_DTPMOD64:
case R_X86_64_DTPOFF64:
case R_X86_64_TPOFF64:
case R_X86_64_PC64:
case R_X86_64_GOTOFF64:
case R_X86_64_GOT64:
case R_X86_64_GOTPCREL64:
case R_X86_64_GOTPC64:
case R_X86_64_GOTPLT64:
case R_X86_64_PLTOFF64:
case R_X86_64_SIZE64:
case R_X86_64_IRELATIVE:
return 8;
case R_X86_64_PC32:
case R_X86_64_GOT32:
case R_X86_64_PLT32:
case R_X86_64_GOTPCREL:
case R_X86_64_32:
case R_X86_64_32S:
case R_X86_64_TLSGD:
case R_X86_64_TLSLD:
case R_X86_64_DTPOFF32:
case R_X86_64_GOTTPOFF:
case R_X86_64_TPOFF32:
case R_X86_64_GOTPC32:
case R_X86_64_SIZE32:
case R_X86_64_GOTPC32_TLSDESC:
return 4;
case R_X86_64_16:
case R_X86_64_PC16:
return 2;
case R_X86_64_8:
case R_X86_64_PC8:
return 1;
case R_X86_64_NONE:
case R_X86_64_COPY:
case R_X86_64_TLSDESC_CALL:
default:
return 0;
}
}
static char * symbolTypeToStr(int type) {
static char buf[10];
switch (type) {
case STT_NOTYPE: return "NOTYPE";
case STT_OBJECT: return "OBJECT";
case STT_FUNC: return "FUNC";
case STT_SECTION: return "SECTION";
case STT_FILE: return "FILE";
default:
sprintf(buf, "%x", type);
return buf;
}
}
static char * symbolBindToStr(int bind) {
static char buf[10];
switch (bind) {
case STB_LOCAL: return "LOCAL";
case STB_GLOBAL: return "GLOBAL";
case STB_WEAK: return "WEAK";
default:
sprintf(buf, "%x", bind);
return buf;
}
}
int main(int argc, char * argv[]) {
if (argc < 2) {
fprintf(stderr, "%s: expected filename\n", argv[0]);
return 1;
}
FILE * f = fopen(argv[1],"r");
if (!f) {
fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1], strerror(errno)); fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1], strerror(errno));
return 1; return 1;
} }
/* Jump to the end so we can get the size */ /**
fseek(binary, 0, SEEK_END); * Validate header.
binary_size = ftell(binary); */
fseek(binary, 0, SEEK_SET); Elf64_Header header;
fread(&header, sizeof(Elf64_Header), 1, f);
/* Some sanity checks */ if (memcmp("\x7F" "ELF",&header,4)) {
if (binary_size < 4 || binary_size > 0xFFFFFFF) { fprintf(stderr, "%s: %s: not an elf\n", argv[0], argv[1]);
printf("Oh no! I don't quite like the size of this binary.\n");
return 1;
}
printf("Binary is %u bytes.\n", (unsigned int)binary_size);
/* Read the binary into a buffer */
binary_buf = malloc(binary_size);
fread((void *)binary_buf, binary_size, 1, binary);
/* Let's start considering this guy an elf, 'eh? */
header = (Elf32_Header *)binary_buf;
/* Verify the magic */
if ( header->e_ident[0] != ELFMAG0 ||
header->e_ident[1] != ELFMAG1 ||
header->e_ident[2] != ELFMAG2 ||
header->e_ident[3] != ELFMAG3) {
printf("Header magic is wrong!\n");
printf("Are you sure this is a 32-bit ELF binary or object file?\n");
return 1; return 1;
} }
/* Let's print out some of the header information, shall we? */ printf("ELF Header:\n");
printf("\033[1mELF Header\033[0m\n"); printf(" Magic: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
header.e_ident[0], header.e_ident[1], header.e_ident[2], header.e_ident[3],
header.e_ident[4], header.e_ident[5], header.e_ident[6], header.e_ident[7],
header.e_ident[8], header.e_ident[9], header.e_ident[10], header.e_ident[11],
header.e_ident[12], header.e_ident[13], header.e_ident[14], header.e_ident[15]);
printf(" Class: %s\n", elf_classToStr(header.e_ident[EI_CLASS]));
printf(" Data: %s\n", elf_dataToStr(header.e_ident[EI_DATA]));
printf(" Version: %s\n", elf_versionToStr(header.e_ident[EI_VERSION]));
printf(" OS/ABI: %s\n", elf_osabiToStr(header.e_ident[EI_OSABI]));
printf(" ABI Version: %u\n", header.e_ident[EI_ABIVERSION]);
/* File type */ if (header.e_ident[EI_CLASS] != ELFCLASS64) {
printf("[Type %d] ", header->e_type); return 0;
switch (header->e_type) {
case ET_NONE:
printf("No file type.\n");
break;
case ET_REL:
printf("Relocatable file.\n");
break;
case ET_EXEC:
printf("Executable file.\n");
break;
case ET_DYN:
printf("Shared object file.\n");
break;
case ET_CORE:
printf("Core file.\n");
break;
default:
printf("(Unknown file type)\n");
break;
} }
/* Machine Type */ /* Byte-order dependent from here on out... */
switch (header->e_machine) { printf(" Type: %s\n", elf_typeToStr(header.e_type));
case EM_386: printf(" Machine: %s\n", elf_machineToStr(header.e_machine));
printf("Intel x86\n"); printf(" Version: 0x%x\n", header.e_version);
break; printf(" Entry point address: 0x%lx\n", header.e_entry);
default: printf(" Start of program headers: %lu (bytes into file)\n", header.e_phoff);
printf("Unknown machine: %d\n", header->e_machine); printf(" Start of section headers: %lu (bytes into file)\n", header.e_shoff);
break; printf(" Flags: 0x%x\n", header.e_flags);
printf(" Size of this header: %u (bytes)\n", header.e_ehsize);
printf(" Size of program headers: %u (bytes)\n", header.e_phentsize);
printf(" Number of program headers: %u\n", header.e_phnum);
printf(" Size of section headers: %u (bytes)\n", header.e_shentsize);
printf(" Number of section headers: %u\n", header.e_shnum);
printf(" Section header string table index: %u\n", header.e_shstrndx);
/* Get the section header string table */
Elf64_Shdr shstr_hdr;
fseek(f, header.e_shoff + header.e_shentsize * header.e_shstrndx, SEEK_SET);
fread(&shstr_hdr, sizeof(Elf64_Shdr), 1, f);
char * stringTable = malloc(shstr_hdr.sh_size);
fseek(f, shstr_hdr.sh_offset, SEEK_SET);
fread(stringTable, shstr_hdr.sh_size, 1, f);
/**
* Section Headers
*/
printf("\nSection Headers:\n");
printf(" [Nr] Name Type Address Offset\n");
printf(" Size EntSize Flags Link Info Align\n");
for (unsigned int i = 0; i < header.e_shnum; ++i) {
fseek(f, header.e_shoff + header.e_shentsize * i, SEEK_SET);
Elf64_Shdr sectionHeader;
fread(&sectionHeader, sizeof(Elf64_Shdr), 1, f);
printf(" [%2d] %-17.17s %-16.16s %016lx %08lx\n",
i, stringTable + sectionHeader.sh_name, sectionHeaderTypeToStr(sectionHeader.sh_type),
sectionHeader.sh_addr, sectionHeader.sh_offset);
printf(" %016lx %016lx %4ld %6d %5d %5ld\n",
sectionHeader.sh_size, sectionHeader.sh_entsize, sectionHeader.sh_flags,
sectionHeader.sh_link, sectionHeader.sh_info, sectionHeader.sh_addralign);
} }
/* Version == EV_CURRENT? */ /**
if (header->e_version == EV_CURRENT) { * Program Headers
printf("ELF version is 1, as it should be.\n"); */
} if (header.e_phoff && header.e_phnum) {
printf("\nProgram Headers:\n");
printf(" Type Offset VirtAddr PhysAddr\n");
printf(" FileSiz MemSiz Flags Align\n");
for (unsigned int i = 0; i < header.e_phnum; ++i) {
fseek(f, header.e_phoff + header.e_phentsize * i, SEEK_SET);
Elf64_Phdr programHeader;
fread(&programHeader, sizeof(Elf64_Phdr), 1, f);
/* Entry point in memory */ printf(" %-14.14s 0x%016lx 0x%016lx 0x%016lx\n",
printf("Binary entry point in virtual memory is at 0x%x\n", (unsigned int)header->e_entry); programHeaderTypeToStr(programHeader.p_type),
programHeader.p_offset, programHeader.p_vaddr, programHeader.p_paddr);
printf(" 0x%016lx 0x%016lx %s 0x%lx\n",
programHeader.p_filesz, programHeader.p_memsz,
programHeaderFlagsToStr(programHeader.p_flags), programHeader.p_align);
/* Program header table offset */ if (programHeader.p_type == PT_INTERP) {
printf("Program header table is at +0x%x and one entry is 0x%x bytes.\n" /* Read interpreter string */
"There are %d total program headers.\n", char * tmp = malloc(programHeader.p_filesz);
(unsigned int)header->e_phoff, (unsigned int)header->e_phentsize, (unsigned int)header->e_phnum); fseek(f, programHeader.p_offset, SEEK_SET);
fread(tmp, programHeader.p_filesz, 1, f);
/* Section header table offset */ printf(" [Requesting program interpreter: %.*s]\n",
printf("Section header table is at +0x%x and one entry is 0x%x bytes.\n" (int)programHeader.p_filesz, tmp);
"There are %d total section headers.\n", free(tmp);
(unsigned int)header->e_shoff, (unsigned int)header->e_shentsize, (unsigned int)header->e_shnum); }
/* Read the program headers */
printf("\033[1mProgram Headers\033[0m\n");
for (uint32_t x = 0; x < header->e_phentsize * header->e_phnum; x += header->e_phentsize) {
if (header->e_phoff + x > binary_size) {
printf("Tried to read beyond the end of the file.\n");
return 1;
} }
/* Grab the program header */ }
Elf32_Phdr * phdr = (Elf32_Phdr *)((uintptr_t)binary_buf + (header->e_phoff + x));
/* Print the header type */ /* TODO Section to segment mapping? */
switch (phdr->p_type) {
case PT_LOAD: /**
printf("[Loadable Segment]\n"); * Dump section information.
*/
for (unsigned int i = 0; i < header.e_shnum; ++i) {
fseek(f, header.e_shoff + header.e_shentsize * i, SEEK_SET);
Elf64_Shdr sectionHeader;
fread(&sectionHeader, sizeof(Elf64_Shdr), 1, f);
/* I think there should only be one of these... */
switch (sectionHeader.sh_type) {
case SHT_DYNAMIC:
{
printf("\nDynamic section at offset 0x%lx contains (up to) %ld entries:\n",
sectionHeader.sh_offset, sectionHeader.sh_size / sectionHeader.sh_entsize);
printf(" Tag Type Name/Value\n");
/* Read the linked string table */
Elf64_Shdr dynstr;
fseek(f, header.e_shoff + header.e_shentsize * sectionHeader.sh_link, SEEK_SET);
fread(&dynstr, sizeof(Elf64_Shdr), 1, f);
char * dynStr = malloc(dynstr.sh_size);
fseek(f, dynstr.sh_offset, SEEK_SET);
fread(dynStr, dynstr.sh_size, 1, f);
char * dynTable = malloc(sectionHeader.sh_size);
fseek(f, sectionHeader.sh_offset, SEEK_SET);
fread(dynTable, sectionHeader.sh_size, 1, f);
for (unsigned int i = 0; i < sectionHeader.sh_size / sectionHeader.sh_entsize; i++) {
Elf64_Dyn * dynEntry = (Elf64_Dyn *)(dynTable + sectionHeader.sh_entsize * i);
printf(" 0x%016lx %s\n",
dynEntry->d_tag,
dynamicTagToStr(dynEntry, dynStr));
if (dynEntry->d_tag == DT_NULL) break;
}
free(dynStr);
free(dynTable);
}
break; break;
case PT_DYNAMIC: case SHT_RELA:
printf("[Dynamic Loading Information]\n"); {
printf("\nRelocation section '%s' at offset 0x%lx contains %ld entries.\n",
stringTable + sectionHeader.sh_name, sectionHeader.sh_offset,
sectionHeader.sh_size / sizeof(Elf64_Rela));
printf(" Offset Info Type Sym. Value Sym. Name + Addend\n");
/* Section this relocation is in */
Elf64_Shdr shdr_this;
fseek(f, header.e_shoff + header.e_shentsize * sectionHeader.sh_info, SEEK_SET);
fread(&shdr_this, sizeof(Elf64_Shdr), 1, f);
/* Symbol table link */
Elf64_Shdr shdr_symtab;
fseek(f, header.e_shoff + header.e_shentsize * sectionHeader.sh_link, SEEK_SET);
fread(&shdr_symtab, sizeof(Elf64_Shdr), 1, f);
Elf64_Sym * symtab = malloc(shdr_symtab.sh_size);
fseek(f, shdr_symtab.sh_offset, SEEK_SET);
fread(symtab, shdr_symtab.sh_size, 1, f);
/* Symbol table's string table link */
Elf64_Shdr shdr_strtab;
fseek(f, header.e_shoff + header.e_shentsize * shdr_symtab.sh_link, SEEK_SET);
fread(&shdr_strtab, sizeof(Elf64_Shdr), 1, f);
char * strtab = malloc(shdr_strtab.sh_size);
fseek(f, shdr_strtab.sh_offset, SEEK_SET);
fread(strtab, shdr_strtab.sh_size, 1, f);
/* Load relocations from file */
Elf64_Rela * relocations = malloc(sectionHeader.sh_size);
fseek(f, sectionHeader.sh_offset, SEEK_SET);
fread((void*)relocations, sectionHeader.sh_size, 1, f);
for (unsigned int i = 0; i < sectionHeader.sh_size / sizeof(Elf64_Rela); ++i) {
Elf64_Shdr shdr;
Elf64_Sym * this = &symtab[ELF64_R_SYM(relocations[i].r_info)];
char * symName;
/* Get symbol name for this relocation */
if ((this->st_info & 0xF) == STT_SECTION) {
fseek(f, header.e_shoff + header.e_shentsize * this->st_shndx, SEEK_SET);
fread(&shdr, sizeof(Elf64_Shdr), 1, f);
symName = stringTable + shdr.sh_name;
} else {
symName = strtab + this->st_name;
}
/* Get the value currently in the section data */
Elf64_Xword value = 0;
int valueSize = sizeOfRelocationValue(ELF64_R_TYPE(relocations[i].r_info));
fseek(f, shdr_this.sh_offset + relocations[i].r_offset, SEEK_SET);
switch (valueSize) {
case 8:
{
uint64_t val;
fread(&val, valueSize, 1, f);
value = val;
break;
}
case 4:
{
uint32_t val;
fread(&val, valueSize, 1, f);
value = val;
break;
}
case 2:
{
uint16_t val;
fread(&val, valueSize, 1, f);
value = val;
break;
}
case 1:
{
uint8_t val;
fread(&val, valueSize, 1, f);
value = val;
break;
}
default:
break;
}
printf("%012lx %012lx %-15.15s %016lx %s + %lx\n",
relocations[i].r_offset, relocations[i].r_info,
relocationInfoToStr(ELF64_R_TYPE(relocations[i].r_info)),
value,
symName,
relocations[i].r_addend);
}
free(relocations);
free(strtab);
free(symtab);
}
break; break;
case PT_INTERP: case SHT_SYMTAB:
printf("[Interpreter Path]\n"); {
printf("\nSymbol table '%s' contains %ld entries.\n",
stringTable + sectionHeader.sh_name,
sectionHeader.sh_size / sizeof(Elf64_Sym));
printf(" Num: Value Size Type Bind Vis Ndx Name\n");
Elf64_Sym * symtab = malloc(sectionHeader.sh_size);
fseek(f, sectionHeader.sh_offset, SEEK_SET);
fread(symtab, sectionHeader.sh_size, 1, f);
Elf64_Shdr shdr_strtab;
fseek(f, header.e_shoff + header.e_shentsize * sectionHeader.sh_link, SEEK_SET);
fread(&shdr_strtab, sizeof(Elf64_Shdr), 1, f);
char * strtab = malloc(shdr_strtab.sh_size);
fseek(f, shdr_strtab.sh_offset, SEEK_SET);
fread(strtab, shdr_strtab.sh_size, 1, f);
for (unsigned int i = 0; i < sectionHeader.sh_size / sizeof(Elf64_Sym); ++i) {
printf("%6u: %016lx %6lu %-7.7s %-6.6s %-4d %6d %s\n",
i, symtab[i].st_value, symtab[i].st_size,
symbolTypeToStr(symtab[i].st_info & 0xF),
symbolBindToStr(symtab[i].st_info >> 4),
symtab[i].st_other,
symtab[i].st_shndx,
strtab + symtab[i].st_name);
}
free(strtab);
free(symtab);
}
break; break;
default: default:
printf("[Unused Segement]\n");
break; break;
} }
} }
uint32_t i = 0;
for (uint32_t x = 0; x < header->e_shentsize * header->e_shnum; x += header->e_shentsize) {
if (header->e_shoff + x > binary_size) {
printf("Tried to read beyond the end of the file.\n");
return 1;
}
Elf32_Shdr * shdr = (Elf32_Shdr *)((uintptr_t)binary_buf + (header->e_shoff + x));
if (shdr->sh_type == SHT_STRTAB) {
if (i == header->e_shstrndx) {
string_table = (char *)((uintptr_t)binary_buf + shdr->sh_offset);
printf("Found the section string table at 0x%x\n", (unsigned int)shdr->sh_offset);
}
}
i++;
}
if (!string_table) {
printf("No string table, skipping rest of output.\n");
return 1;
}
/* Find the (hopefully two) string tables */
printf("\033[1mString Tables\033[0m\n");
for (uint32_t x = 0; x < header->e_shentsize * header->e_shnum; x += header->e_shentsize) {
if (header->e_shoff + x > binary_size) {
printf("Tried to read beyond the end of the file.\n");
return 1;
}
Elf32_Shdr * shdr = (Elf32_Shdr *)((uintptr_t)binary_buf + (header->e_shoff + x));
if (shdr->sh_type == SHT_STRTAB) {
if (!strcmp((char *)((uintptr_t)string_table + shdr->sh_name), ".strtab")) {
sym_string_table = (char *)((uintptr_t)binary_buf + shdr->sh_offset);
printf("Found the symbol string table at 0x%x\n", (unsigned int)shdr->sh_offset);
}
printf("Displaying string table at 0x%x\n", (unsigned int)shdr->sh_offset);
char * _string_table = (char *)((uintptr_t)binary_buf + shdr->sh_offset);
unsigned int j = 1;
int k = 0;
printf("%d\n", (unsigned int)shdr->sh_size);
while (j < shdr->sh_size) {
int t = strlen((char *)((uintptr_t)_string_table + j));
if (t) {
printf("%d [%d] %s\n", k, j, (char *)((uintptr_t)_string_table + j));
k++;
j += t;
} else {
j += 1;
}
}
}
}
/* Read the section headers */
printf("\033[1mSection Headers\033[0m\n");
for (uint32_t x = 0; x < header->e_shentsize * header->e_shnum; x += header->e_shentsize) {
if (header->e_shoff + x > binary_size) {
printf("Tried to read beyond the end of the file.\n");
return 1;
}
Elf32_Shdr * shdr = (Elf32_Shdr *)((uintptr_t)binary_buf + (header->e_shoff + x));
printf("[%d] %s\n", (unsigned int)shdr->sh_type, (char *)((uintptr_t)string_table + shdr->sh_name));
printf("Section starts at 0x%x and is 0x%x bytes long.\n", (unsigned int)shdr->sh_offset, (unsigned int)shdr->sh_size);
if (shdr->sh_addr) {
printf("It should be loaded at 0x%x.\n", (unsigned int)shdr->sh_addr);
}
}
#if 1
printf("\033[1mSymbol Tables\033[0m\n");
for (uint32_t x = 0; x < header->e_shentsize * header->e_shnum; x += header->e_shentsize) {
if (header->e_shoff + x > binary_size) {
printf("Tried to read beyond the end of the file.\n");
return 1;
}
Elf32_Shdr * shdr = (Elf32_Shdr *)((uintptr_t)binary_buf + (header->e_shoff + x));
if (shdr->sh_type == SHT_SYMTAB) {
printf("Found symbol table: %s\n", (char *)((uintptr_t)string_table + shdr->sh_name));
Elf32_Sym * table = (Elf32_Sym *)((uintptr_t)binary_buf + (shdr->sh_offset));
while ((uintptr_t)table - ((uintptr_t)binary_buf + shdr->sh_offset) < shdr->sh_size) {
printf("%s: 0x%x [0x%x]\n", (char *)((uintptr_t)sym_string_table + table->st_name), (unsigned int)table->st_value, (unsigned int)table->st_size);
table++;
}
}
}
#endif
return 0; return 0;
} }

View File

@ -1,5 +0,0 @@
#!/bin/sh
export-cmd DESKTOP cat /var/run/.wallpaper.pid
if not empty? "$DESKTOP" then kill -SIGUSR2 $DESKTOP

View File

@ -121,7 +121,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win) { if (win) {
win->focused = wf->focused; win->focused = wf->focused;
decors(); decors();

View File

@ -52,7 +52,7 @@ int main(int argc, char * argv[]) {
/* Send ioctl */ /* Send ioctl */
if (init) { if (init) {
char tmp[100]; char tmp[100];
sprintf(tmp, "%s,%lu,%lu", driver, s.width, s.height); sprintf(tmp, "%s,%u,%u", driver, s.width, s.height);
if (ioctl(fd, IO_VID_REINIT, tmp) < 0) { if (ioctl(fd, IO_VID_REINIT, tmp) < 0) {
perror("ioctl"); perror("ioctl");
return 1; return 1;

View File

@ -1,12 +0,0 @@
#!/bin/sh
if empty? "$1" then exec sh -c "echo 'usage: $0 WALLPAPER'"
if not stat -Lq "$1" then exec sh -c "echo '$0: $1 does not exist'"
export-cmd DESKTOP cat /var/run/.wallpaper.pid
if empty? "$DESKTOP" then sh -c "echo '$0: No wallpaper running?'"
echo "wallpaper=$1" > $HOME/.wallpaper.conf
kill -SIGUSR1 $DESKTOP

View File

@ -1109,6 +1109,7 @@ int shell_exec(char * buffer, size_t size, FILE * file, char ** out_buffer) {
*out_buffer = ++p; *out_buffer = ++p;
goto _done; goto _done;
} }
goto _just_add;
case '#': case '#':
if (!quoted && !backtick) { if (!quoted && !backtick) {
goto _done; /* Support comments; must not be part of an existing arg */ goto _done; /* Support comments; must not be part of an existing arg */
@ -1782,7 +1783,7 @@ uint32_t shell_cmd_cd(int argc, char * argv[]) {
goto cd_error; goto cd_error;
} }
} else { } else {
char home_path[512]; char home_path[1200];
sprintf(home_path, "/home/%s", username); sprintf(home_path, "/home/%s", username);
if (chdir(home_path)) { if (chdir(home_path)) {
goto cd_error; goto cd_error;

View File

@ -208,7 +208,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win) { if (win) {
win->focused = wf->focused; win->focused = wf->focused;
redraw(); redraw();

View File

@ -25,7 +25,7 @@ int main(int argc, char ** argv) {
unsigned int seconds = (unsigned int)time; unsigned int seconds = (unsigned int)time;
unsigned int subsecs = (unsigned int)((time - (float)seconds) * 100); unsigned int subsecs = (unsigned int)((time - (float)seconds) * 100);
ret = syscall_nanosleep(seconds, subsecs); ret = syscall_sleep(seconds, subsecs);
return ret; return ret;
} }

View File

@ -18,24 +18,11 @@
#include "terminal-font.h" #include "terminal-font.h"
/**
* For legacy backwards-compatibility reasons, the VGA
* text-mode window is normalled mapped 1:1. If this
* ever changes, a few applications will need to be updated.
*/
static unsigned short * textmemptr = (unsigned short *)0xB8000;
static void placech(unsigned char c, int x, int y, int attr) {
unsigned short *where;
unsigned att = attr << 8;
where = textmemptr + (y * 80 + x);
*where = c | att;
}
/** /**
* Graphical framebuffer is a bit more straightforward. * Graphical framebuffer is a bit more straightforward.
*/ */
static int framebuffer_fd = -1; static int framebuffer_fd = -1;
static int width, height, depth; static long width, height, depth;
static char * framebuffer; static char * framebuffer;
static void set_point(int x, int y, uint32_t value) { static void set_point(int x, int y, uint32_t value) {
@ -65,62 +52,39 @@ static void write_char(int x, int y, int val, uint32_t color) {
} }
static void update_message(char * c, int line) { static void update_message(char * c, int line) {
if (framebuffer_fd != -1) { if (framebuffer_fd < 0) return;
int x = 20; int x = 20;
int y = 20 + char_height * line; int y = 20 + char_height * line;
while (*c) { while (*c) {
write_char(x, y, *c, FG_COLOR); write_char(x, y, *c, FG_COLOR);
c++; c++;
x += char_width; x += char_width;
} }
while (x < width - char_width) { while (x < width - char_width) {
write_char(x, y, ' ', FG_COLOR); write_char(x, y, ' ', FG_COLOR);
x += char_width; x += char_width;
}
} else {
int x = 2;
int y = 2 + line;
while (*c) {
placech(*c, x, y, 0x7);
c++;
x++;
}
while (x < 80) {
placech(' ', x, y, 0x7);
x++;
}
} }
} }
static void clear_screen(void) { static void clear_screen(void) {
if (framebuffer_fd != -1) { if (framebuffer_fd < 0) return;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
set_point(x,y,BG_COLOR);
}
}
} else { for (int y = 0; y < height; ++y) {
for (int y = 0; y < 24; ++y) { for (int x = 0; x < width; ++x) {
for (int x = 0; x < 80; ++x) { set_point(x,y,BG_COLOR);
placech(' ', x, y, 0); /* Clear */
}
} }
} }
} }
static void check_framebuffer(void) { static void check_framebuffer(void) {
int tmpfd = open("/proc/framebuffer", O_RDONLY); framebuffer_fd = open("/dev/fb0", O_RDONLY);
if (tmpfd > 0) { if (framebuffer_fd < 0) return;
framebuffer_fd = open("/dev/fb0", O_RDONLY);
ioctl(framebuffer_fd, IO_VID_WIDTH, &width); ioctl(framebuffer_fd, IO_VID_WIDTH, &width);
ioctl(framebuffer_fd, IO_VID_HEIGHT, &height); ioctl(framebuffer_fd, IO_VID_HEIGHT, &height);
ioctl(framebuffer_fd, IO_VID_DEPTH, &depth); ioctl(framebuffer_fd, IO_VID_DEPTH, &depth);
ioctl(framebuffer_fd, IO_VID_ADDR, &framebuffer); ioctl(framebuffer_fd, IO_VID_ADDR, &framebuffer);
ioctl(framebuffer_fd, IO_VID_SIGNAL, NULL); ioctl(framebuffer_fd, IO_VID_SIGNAL, NULL);
} else {
framebuffer_fd = -1;
}
} }
static FILE * pex_endpoint = NULL; static FILE * pex_endpoint = NULL;
@ -139,6 +103,7 @@ int main(int argc, char * argv[]) {
if (!fork()) { if (!fork()) {
check_framebuffer(); check_framebuffer();
//printf("splash daemon is running, framebuffer (%ldx%ld) is at %p\n", width, height, framebuffer);
clear_screen(); clear_screen();
update_message("ToaruOS is starting up...", 0); update_message("ToaruOS is starting up...", 0);

View File

@ -299,13 +299,13 @@ int main(int argc, char * argv[]) {
if (verbose) { if (verbose) {
fprintf(stdout, "%.155s%.100s\n", file->prefix, file->filename); fprintf(stdout, "%.155s%.100s\n", file->prefix, file->filename);
} }
char name[1024] = {0}; char name[1025] = {0};
if (last_was_long) { if (last_was_long) {
strncat(name, tmpname, 1023); strncat(name, tmpname, 1024);
last_was_long = 0; last_was_long = 0;
} else { } else {
strncat(name, file->prefix, 155); strncat(name, file->prefix, 167);
strncat(name, file->filename, 100); strncat(name, file->filename, 512);
} }
if (file->type[0] == '0' || file->type[0] == 0) { if (file->type[0] == '0' || file->type[0] == 0) {
@ -335,8 +335,8 @@ int main(int argc, char * argv[]) {
} }
} else if (file->type[0] == '1') { } else if (file->type[0] == '1') {
if (!to_stdout && (!only_matches || matches_files(argc,argv,optind,name))) { if (!to_stdout && (!only_matches || matches_files(argc,argv,optind,name))) {
char tmp[101] = {0}; char tmp[356] = {0};
strncat(tmp, file->link, 100); strncat(tmp, file->link, 355);
FILE * mf = fopen(name,"w"); FILE * mf = fopen(name,"w");
if (!mf) { if (!mf) {
fprintf(stderr, "%s: %s: %s: %s\n", argv[0], fname, name, strerror(errno)); fprintf(stderr, "%s: %s: %s: %s\n", argv[0], fname, name, strerror(errno));
@ -359,8 +359,8 @@ int main(int argc, char * argv[]) {
_seek_forward(f, interpret_size(file)); _seek_forward(f, interpret_size(file));
} else if (file->type[0] == '2') { } else if (file->type[0] == '2') {
if (!to_stdout && (!only_matches || matches_files(argc,argv,optind,name))) { if (!to_stdout && (!only_matches || matches_files(argc,argv,optind,name))) {
char tmp[101] = {0}; char tmp[356] = {0};
strncat(tmp, file->link, 100); strncat(tmp, file->link, 355);
if (symlink(tmp, name) < 0) { if (symlink(tmp, name) < 0) {
fprintf(stderr, "%s: %s: %s: %s: %s\n", argv[0], fname, name, tmp, strerror(errno)); fprintf(stderr, "%s: %s: %s: %s: %s\n", argv[0], fname, name, tmp, strerror(errno));
} }

Binary file not shown.

View File

@ -1302,7 +1302,7 @@ int main(int argc, char ** argv) {
/* Prune any keyboard input we got before the terminal started. */ /* Prune any keyboard input we got before the terminal started. */
struct stat s; struct stat s;
fstat(kfd, &s); fstat(kfd, &s);
for (int i = 0; i < s.st_size; i++) { for (unsigned int i = 0; i < s.st_size; i++) {
char tmp[1]; char tmp[1];
read(kfd, tmp, 1); read(kfd, tmp, 1);
} }

View File

@ -833,7 +833,7 @@ static void redraw_cell_image(uint16_t x, uint16_t y, term_cell_t * cell) {
if (x >= term_width || y >= term_height) return; if (x >= term_width || y >= term_height) return;
/* Draw the image data */ /* Draw the image data */
uint32_t * data = (uint32_t *)cell->fg; uint32_t * data = (uint32_t *)((uintptr_t)cell->bg << 32 | cell->fg);
for (uint32_t yy = 0; yy < char_height; ++yy) { for (uint32_t yy = 0; yy < char_height; ++yy) {
for (uint32_t xx = 0; xx < char_width; ++xx) { for (uint32_t xx = 0; xx < char_width; ++xx) {
term_set_point(x * char_width + xx, y * char_height + yy, *data); term_set_point(x * char_width + xx, y * char_height + yy, *data);
@ -1066,7 +1066,8 @@ static void flush_unused_images(void) {
for (int x = 0; x < term_width; ++x) { for (int x = 0; x < term_width; ++x) {
term_cell_t * cell = (term_cell_t *)((uintptr_t)term_buffer + (y * term_width + x) * sizeof(term_cell_t)); term_cell_t * cell = (term_cell_t *)((uintptr_t)term_buffer + (y * term_width + x) * sizeof(term_cell_t));
if (cell->flags & ANSI_EXT_IMG) { if (cell->flags & ANSI_EXT_IMG) {
list_insert(tmp, (void *)cell->fg); uint32_t * data = (uint32_t *)((uintptr_t)cell->bg << 32 | cell->fg);
list_insert(tmp, data);
} }
} }
} }
@ -1364,7 +1365,10 @@ static void term_set_cell_contents(int x, int y, char * data) {
char * cell_data = malloc(char_width * char_height * sizeof(uint32_t)); char * cell_data = malloc(char_width * char_height * sizeof(uint32_t));
memcpy(cell_data, data, char_width * char_height * sizeof(uint32_t)); memcpy(cell_data, data, char_width * char_height * sizeof(uint32_t));
list_insert(images_list, cell_data); list_insert(images_list, cell_data);
cell_set(x, y, ' ', (uint32_t)cell_data, 0, ANSI_EXT_IMG); cell_set(x, y, ' ',
(uintptr_t)(cell_data) & 0xFFFFFFFF,
(uintptr_t)(cell_data) >> 32,
ANSI_EXT_IMG);
} }
/* ANSI callback to get character cell width */ /* ANSI callback to get character cell width */
@ -1945,7 +1949,7 @@ static void * handle_incoming(void) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win == window) { if (win == window) {
win->focused = wf->focused; win->focused = wf->focused;
render_decors(); render_decors();
@ -2461,8 +2465,8 @@ int main(int argc, char ** argv) {
if (res[1]) { if (res[1]) {
/* Read from PTY */ /* Read from PTY */
int r = read(fd_master, buf, 4096); ssize_t r = read(fd_master, buf, 4096);
for (int i = 0; i < r; ++i) { for (ssize_t i = 0; i < r; ++i) {
ansi_put(ansi_state, buf[i]); ansi_put(ansi_state, buf[i]);
} }
display_flip(); display_flip();

6
apps/test-cxx.c++ Normal file
View File

@ -0,0 +1,6 @@
#include <iostream>
int main() {
std::cout << "Hello, world!";
return 0;
}

View File

@ -2,7 +2,7 @@
#include <pthread.h> #include <pthread.h>
#include <sys/sysfunc.h> #include <sys/sysfunc.h>
__thread int myvalue; __thread volatile int myvalue;
void * getaddressinthread(void * _unused) { void * getaddressinthread(void * _unused) {
fprintf(stderr, "in thread before:\n"); fprintf(stderr, "in thread before:\n");

View File

@ -1,5 +0,0 @@
#!/bin/sh
export-cmd UNAME uname
export-cmd DATE date
echo "This is a test shell script."
echo "This is $UNAME and it is $DATE"

View File

@ -325,6 +325,9 @@ int main(int argc, char * argv[]) {
decor_get_bounds(NULL, &bounds); decor_get_bounds(NULL, &bounds);
window = yutani_window_create(yctx, width + bounds.width, height + bounds.height); window = yutani_window_create(yctx, width + bounds.width, height + bounds.height);
req_center_x = yctx->display_width / 2;
req_center_y = yctx->display_height / 2;
yutani_window_move(yctx, window, req_center_x - window->width / 2, req_center_y - window->height / 2);
/* Load icons */ /* Load icons */
load_sprite(&logo, "/usr/share/logo_login.png"); load_sprite(&logo, "/usr/share/logo_login.png");
@ -335,9 +338,6 @@ int main(int argc, char * argv[]) {
load_page(0); load_page(0);
req_center_x = yctx->display_width / 2;
req_center_y = yctx->display_height / 2;
yutani_window_move(yctx, window, req_center_x - window->width / 2, req_center_y - window->height / 2);
yutani_window_advertise_icon(yctx, window, title_str, "star"); yutani_window_advertise_icon(yctx, window, title_str, "star");
ctx = init_graphics_yutani_double_buffer(window); ctx = init_graphics_yutani_double_buffer(window);
@ -371,7 +371,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (wf->wid == background->wid) { if (wf->wid == background->wid) {
yutani_focus_window(yctx, window->wid); yutani_focus_window(yctx, window->wid);
} else if (win) { } else if (win) {

View File

@ -327,7 +327,7 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_WINDOW_FOCUS_CHANGE: case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
{ {
struct yutani_msg_window_focus_change * wf = (void*)m->data; struct yutani_msg_window_focus_change * wf = (void*)m->data;
yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); yutani_window_t * win = hashmap_get(yctx->windows, (void*)(uintptr_t)wf->wid);
if (win) { if (win) {
win->focused = wf->focused; win->focused = wf->focused;
redraw(); redraw();

View File

@ -11,6 +11,7 @@
typedef struct JSON_Value Value; typedef struct JSON_Value Value;
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
return 1;
Value * config = json_parse_file("/etc/weather.json"); Value * config = json_parse_file("/etc/weather.json");
if (!config) { if (!config) {

View File

@ -2,4 +2,4 @@ remote_order=local,remote
[remotes] [remotes]
local=/cdrom/extra local=/cdrom/extra
remote=http://toaruos.org/msk/1.10.x remote=http://toaruos.org/msk/2.0.x

View File

@ -1,23 +0,0 @@
# x86 Assembly w/ libc
.global fprintf # libc export
.global stdout # libc export
.global main # our exported main function, called by C runtime
main:
push $world
push $hello
push stdout
call fprintf # fprintf(stdout, "Hello, %s!\n", "world");
pop %eax
pop %eax
pop %eax
mov $0, %eax
ret
hello:
.asciz "Hello, %s!\n"
world:
.asciz "world"

View File

@ -1,54 +0,0 @@
# configuration file generated by Bochs
plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1
config_interface: textconfig
display_library: sdl
memory: host=256, guest=256
romimage: file="/usr/local/share/bochs/BIOS-bochs-latest", address=0x00000000, options=none
vgaromimage: file="/usr/local/share/bochs/VGABIOS-lgpl-latest"
boot: cdrom
floppy_bootsig_check: disabled=0
# no floppya
# no floppyb
ata0: enabled=1, ioaddr1=0x000001f0, ioaddr2=0x000003f0, irq=14
ata0-master: type=cdrom, path="/dev/cdrom0", status=inserted, model="Generic 1234", biosdetect=auto
ata0-slave: type=none
ata1: enabled=1, ioaddr1=0x00000170, ioaddr2=0x00000370, irq=15
ata1-master: type=none
ata1-slave: type=none
ata2: enabled=0
ata3: enabled=0
optromimage1: file=none
optromimage2: file=none
optromimage3: file=none
optromimage4: file=none
optramimage1: file=none
optramimage2: file=none
optramimage3: file=none
optramimage4: file=none
pci: enabled=1, chipset=i440fx, slot1=pcivga
vga: extension=vbe, update_freq=5, realtime=1
cpu: count=1, ips=4000000, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU "
cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0
cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, smep=0, smap=0, mwait=1
print_timestamps: enabled=0
port_e9_hack: enabled=0
private_colormap: enabled=0
clock: sync=realtime, time0=local, rtc_sync=1
# no cmosimage
# no loader
log: -
logprefix: %t%e%d
debug: action=ignore
info: action=report
error: action=report
panic: action=fatal
keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none
mouse: type=ps2, enabled=0, toggle=ctrl+mbutton
speaker: enabled=1, mode=gui
parport1: enabled=1, file=none
parport2: enabled=0
com1: enabled=1, mode=null
com2: enabled=0
com3: enabled=0
com4: enabled=0

View File

@ -1,7 +0,0 @@
#!/bin/sh
export CRTBEG="/lib/crt0.o /lib/crti.o /usr/lib/crtbegin.o"
export CRTEND="/usr/lib/crtend.o /lib/crtn.o"
/usr/i686-pc-toaru/bin/as -o /tmp/asm-demo.o asm-demo.s
/usr/i686-pc-toaru/bin/ld -o /tmp/asm-demo $CRTBEG -lc /tmp/asm-demo.o $CRTEND

View File

@ -1,6 +0,0 @@
#include <stdio.h>
int main(int argc, char * argv[]) {
fprintf(stdout, "Hello, %s!\n", "world");
return 0;
}

View File

@ -32,6 +32,6 @@ extern int toupper(int c);
#define _X 0100 #define _X 0100
#define _B 0200 #define _B 0200
extern char _ctype_[256]; extern unsigned char _ctype_[256];
_End_C_Header _End_C_Header

View File

@ -135,7 +135,7 @@ _Begin_C_Header
#ifndef _KERNEL_ #ifndef _KERNEL_
extern int errno; extern int errno;
#define __sets_errno(...) int ret = __VA_ARGS__; if (ret < 0) { errno = -ret; ret = -1; } return ret #define __sets_errno(...) long ret = __VA_ARGS__; if (ret < 0) { errno = -ret; ret = -1; } return ret
#endif #endif
_End_C_Header _End_C_Header

View File

@ -5,12 +5,23 @@
#include <stddef.h> #include <stddef.h>
_Begin_C_Header _Begin_C_Header
#define PRIi8 "i" #define PRIi8 "i"
#define PRIi16 "i" #define PRIi16 "i"
#define PRIi32 "i" #define PRIi32 "i"
#define PRIi64 "lli" #define PRIi64 "li"
#define PRIx64 "llx" #define PRIx8 "x"
#define PRIu64 "llu" #define PRIx16 "x"
#define PRId64 "lld" #define PRIx32 "x"
#define PRIx64 "lx"
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIu64 "lu"
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "d"
#define PRId64 "ld"
_End_C_Header _End_C_Header

View File

@ -0,0 +1,53 @@
#pragma once
#include <kernel/types.h>
struct rsdp_descriptor {
char signature[8];
uint8_t checksum;
char oemid[6];
uint8_t revision;
uint32_t rsdt_address;
} __attribute__((packed));
struct rsdp_descriptor_20 {
struct rsdp_descriptor base;
uint32_t length;
uint64_t xsdt_address;
uint8_t ext_checksum;
uint8_t _reserved[3];
} __attribute((packed));
struct acpi_sdt_header {
char signature[4];
uint32_t length;
uint8_t revision;
uint8_t checksum;
char oemid[6];
char oem_tableid[8];
uint32_t oem_revision;
uint32_t creator_id;
uint32_t creator_revision;
} __attribute__((packed));
struct rsdt {
struct acpi_sdt_header header;
uint32_t pointers[];
};
struct madt {
struct acpi_sdt_header header;
uint32_t lapic_addr;
uint32_t flags;
uint8_t entries[];
};
static inline int acpi_checksum(struct acpi_sdt_header * header) {
uint8_t check = 0;
for (size_t i = 0; i < header->length; ++i) {
check += ((uint8_t *)header)[i];
}
return check == 0;
}

View File

@ -0,0 +1,5 @@
#pragma once
#include <kernel/types.h>
uint32_t read_cmos(void);

View File

@ -0,0 +1,87 @@
#pragma once
#include <kernel/arch/x86_64/regs.h>
extern struct regs * _isr0(struct regs*);
extern struct regs * _isr1(struct regs*);
extern struct regs * _isr2(struct regs*);
extern struct regs * _isr3(struct regs*);
extern struct regs * _isr4(struct regs*);
extern struct regs * _isr5(struct regs*);
extern struct regs * _isr6(struct regs*);
extern struct regs * _isr7(struct regs*);
extern struct regs * _isr8(struct regs*);
extern struct regs * _isr9(struct regs*);
extern struct regs * _isr10(struct regs*);
extern struct regs * _isr11(struct regs*);
extern struct regs * _isr12(struct regs*);
extern struct regs * _isr13(struct regs*);
extern struct regs * _isr14(struct regs*);
extern struct regs * _isr15(struct regs*);
extern struct regs * _isr16(struct regs*);
extern struct regs * _isr17(struct regs*);
extern struct regs * _isr18(struct regs*);
extern struct regs * _isr19(struct regs*);
extern struct regs * _isr20(struct regs*);
extern struct regs * _isr21(struct regs*);
extern struct regs * _isr22(struct regs*);
extern struct regs * _isr23(struct regs*);
extern struct regs * _isr24(struct regs*);
extern struct regs * _isr25(struct regs*);
extern struct regs * _isr26(struct regs*);
extern struct regs * _isr27(struct regs*);
extern struct regs * _isr28(struct regs*);
extern struct regs * _isr29(struct regs*);
extern struct regs * _isr30(struct regs*);
extern struct regs * _isr31(struct regs*);
extern struct regs * _irq0(struct regs*);
extern struct regs * _irq1(struct regs*);
extern struct regs * _irq2(struct regs*);
extern struct regs * _irq3(struct regs*);
extern struct regs * _irq4(struct regs*);
extern struct regs * _irq5(struct regs*);
extern struct regs * _irq6(struct regs*);
extern struct regs * _irq7(struct regs*);
extern struct regs * _irq8(struct regs*);
extern struct regs * _irq9(struct regs*);
extern struct regs * _irq10(struct regs*);
extern struct regs * _irq11(struct regs*);
extern struct regs * _irq12(struct regs*);
extern struct regs * _irq13(struct regs*);
extern struct regs * _irq14(struct regs*);
extern struct regs * _irq15(struct regs*);
extern struct regs * _isr125(struct regs*); /* Does not actually take regs */
extern struct regs * _isr126(struct regs*); /* Does not actually take regs */
extern struct regs * _isr127(struct regs*); /* Syscall entry point */
typedef struct regs * (*interrupt_handler_t)(struct regs *);
/**
* Interrupt descriptor table
*/
typedef struct {
uint16_t base_low;
uint16_t selector;
uint8_t zero;
uint8_t flags;
uint16_t base_mid;
uint32_t base_high;
uint32_t pad;
} __attribute__((packed)) idt_entry_t;
struct idt_pointer {
uint16_t limit;
uintptr_t base;
} __attribute__((packed));
extern void irq_ack(size_t irq_no);
typedef int (*irq_handler_chain_t) (struct regs *);
extern void irq_install_handler(size_t irq, irq_handler_chain_t handler, const char * desc);
extern const char * get_irq_handler(int irq, int chain);
extern void idt_load(void *);

View File

@ -0,0 +1,41 @@
#pragma once
#include <stdint.h>
#include <kernel/arch/x86_64/pml.h>
#define MMU_FLAG_KERNEL 0x01
#define MMU_FLAG_WRITABLE 0x02
#define MMU_FLAG_NOCACHE 0x04
#define MMU_FLAG_WRITETHROUGH 0x08
#define MMU_FLAG_SPEC 0x10
#define MMU_FLAG_WC (MMU_FLAG_NOCACHE | MMU_FLAG_WRITETHROUGH | MMU_FLAG_SPEC)
#define MMU_FLAG_NOEXECUTE 0x20
#define MMU_GET_MAKE 0x01
void mmu_frame_set(uintptr_t frame_addr);
void mmu_frame_clear(uintptr_t frame_addr);
int mmu_frame_test(uintptr_t frame_addr);
uintptr_t mmu_first_n_frames(int n);
uintptr_t mmu_first_frame(void);
void mmu_frame_allocate(union PML * page, unsigned int flags);
void mmu_frame_map_address(union PML * page, unsigned int flags, uintptr_t physAddr);
void mmu_frame_free(union PML * page);
uintptr_t mmu_map_to_physical(uintptr_t virtAddr);
union PML * mmu_get_page(uintptr_t virtAddr, int flags);
void mmu_set_directory(union PML * new_pml);
void mmu_free(union PML * from);
union PML * mmu_clone(union PML * from);
void mmu_init(size_t memsize, uintptr_t firstFreePage);
void mmu_invalidate(uintptr_t addr);
uintptr_t mmu_allocate_a_frame(void);
uintptr_t mmu_allocate_n_frames(int n);
union PML * mmu_get_kernel_directory(void);
void * mmu_map_from_physical(uintptr_t frameaddress);
void * mmu_map_mmio_region(uintptr_t physical_address, size_t size);
size_t mmu_count_user(union PML * from);
size_t mmu_count_shm(union PML * from);
size_t mmu_total_memory(void);
size_t mmu_used_memory(void);
void * sbrk(size_t);

View File

@ -0,0 +1,23 @@
#pragma once
#include <kernel/types.h>
union PML {
struct {
uint64_t present:1;
uint64_t writable:1;
uint64_t user:1;
uint64_t writethrough:1;
uint64_t nocache:1;
uint64_t accessed:1;
uint64_t _available1:1;
uint64_t size:1;
uint64_t global:1;
uint64_t _available2:3;
uint64_t page:28;
uint64_t reserved:12;
uint64_t _available3:11;
uint64_t nx:1;
} bits;
uint64_t raw;
};

View File

@ -0,0 +1,12 @@
#pragma once
#include <kernel/types.h>
extern unsigned short inports(unsigned short _port);
extern void outports(unsigned short _port, unsigned short _data);
extern unsigned int inportl(unsigned short _port);
extern void outportl(unsigned short _port, unsigned int _data);
extern unsigned char inportb(unsigned short _port);
extern void outportb(unsigned short _port, unsigned char _data);
extern void outportsm(unsigned short port, unsigned char * data, unsigned long size);
extern void inportsm(unsigned short port, unsigned char * data, unsigned long size);

View File

@ -0,0 +1,18 @@
#pragma once
#include <kernel/types.h>
/**
* Register layout for interrupt context.
*/
struct regs {
/* Pushed by common stub */
uintptr_t r15, r14, r13, r12;
uintptr_t r11, r10, r9, r8;
uintptr_t rbp, rdi, rsi, rdx, rcx, rbx, rax;
/* Pushed by wrapper */
uintptr_t int_no, err_code;
/* Pushed by interrupt */
uintptr_t rip, cs, rflags, rsp, ss;
};

View File

@ -1,9 +1,6 @@
#pragma once #pragma once
int args_present(char * karg); int args_present(const char * karg);
char * args_value(char * karg); char * args_value(const char * karg);
void args_parse(char * _arg); void args_parse(const char * arg);
void early_stage_args(void);
void late_stage_args(void);

View File

@ -1,141 +0,0 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*
* Values for ATA / PATA devices
*/
#pragma once
#define ATA_SR_BSY 0x80
#define ATA_SR_DRDY 0x40
#define ATA_SR_DF 0x20
#define ATA_SR_DSC 0x10
#define ATA_SR_DRQ 0x08
#define ATA_SR_CORR 0x04
#define ATA_SR_IDX 0x02
#define ATA_SR_ERR 0x01
#define ATA_ER_BBK 0x80
#define ATA_ER_UNC 0x40
#define ATA_ER_MC 0x20
#define ATA_ER_IDNF 0x10
#define ATA_ER_MCR 0x08
#define ATA_ER_ABRT 0x04
#define ATA_ER_TK0NF 0x02
#define ATA_ER_AMNF 0x01
#define ATA_CMD_READ_PIO 0x20
#define ATA_CMD_READ_PIO_EXT 0x24
#define ATA_CMD_READ_DMA 0xC8
#define ATA_CMD_READ_DMA_EXT 0x25
#define ATA_CMD_WRITE_PIO 0x30
#define ATA_CMD_WRITE_PIO_EXT 0x34
#define ATA_CMD_WRITE_DMA 0xCA
#define ATA_CMD_WRITE_DMA_EXT 0x35
#define ATA_CMD_CACHE_FLUSH 0xE7
#define ATA_CMD_CACHE_FLUSH_EXT 0xEA
#define ATA_CMD_PACKET 0xA0
#define ATA_CMD_IDENTIFY_PACKET 0xA1
#define ATA_CMD_IDENTIFY 0xEC
#define ATAPI_CMD_READ 0xA8
#define ATAPI_CMD_EJECT 0x1B
#define ATA_IDENT_DEVICETYPE 0
#define ATA_IDENT_CYLINDERS 2
#define ATA_IDENT_HEADS 6
#define ATA_IDENT_SECTORS 12
#define ATA_IDENT_SERIAL 20
#define ATA_IDENT_MODEL 54
#define ATA_IDENT_CAPABILITIES 98
#define ATA_IDENT_FIELDVALID 106
#define ATA_IDENT_MAX_LBA 120
#define ATA_IDENT_COMMANDSETS 164
#define ATA_IDENT_MAX_LBA_EXT 200
#define IDE_ATA 0x00
#define IDE_ATAPI 0x01
#define ATA_MASTER 0x00
#define ATA_SLAVE 0x01
#define ATA_REG_DATA 0x00
#define ATA_REG_ERROR 0x01
#define ATA_REG_FEATURES 0x01
#define ATA_REG_SECCOUNT0 0x02
#define ATA_REG_LBA0 0x03
#define ATA_REG_LBA1 0x04
#define ATA_REG_LBA2 0x05
#define ATA_REG_HDDEVSEL 0x06
#define ATA_REG_COMMAND 0x07
#define ATA_REG_STATUS 0x07
#define ATA_REG_SECCOUNT1 0x08
#define ATA_REG_LBA3 0x09
#define ATA_REG_LBA4 0x0A
#define ATA_REG_LBA5 0x0B
#define ATA_REG_CONTROL 0x0C
#define ATA_REG_ALTSTATUS 0x0C
#define ATA_REG_DEVADDRESS 0x0D
// Channels:
#define ATA_PRIMARY 0x00
#define ATA_SECONDARY 0x01
// Directions:
#define ATA_READ 0x00
#define ATA_WRITE 0x01
typedef struct {
uint16_t base;
uint16_t ctrl;
uint16_t bmide;
uint16_t nien;
} ide_channel_regs_t;
typedef struct {
uint8_t reserved;
uint8_t channel;
uint8_t drive;
uint16_t type;
uint16_t signature;
uint16_t capabilities;
uint32_t command_sets;
uint32_t size;
uint8_t model[41];
} ide_device_t;
typedef struct {
uint8_t status;
uint8_t chs_first_sector[3];
uint8_t type;
uint8_t chs_last_sector[3];
uint32_t lba_first_sector;
uint32_t sector_count;
} partition_t;
typedef struct {
uint16_t flags;
uint16_t unused1[9];
char serial[20];
uint16_t unused2[3];
char firmware[8];
char model[40];
uint16_t sectors_per_int;
uint16_t unused3;
uint16_t capabilities[2];
uint16_t unused4[2];
uint16_t valid_ext_data;
uint16_t unused5[5];
uint16_t size_of_rw_mult;
uint32_t sectors_28;
uint16_t unused6[38];
uint64_t sectors_48;
uint16_t unused7[152];
} __attribute__((packed)) ata_identify_t;
typedef struct {
uint8_t boostrap[446];
partition_t partitions[4];
uint8_t signature[2];
} __attribute__((packed)) mbr_t;

View File

@ -1,19 +0,0 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#pragma once
#include <kernel/system.h>
typedef struct {
unsigned char *data;
size_t size;
} bitset_t;
void bitset_init(bitset_t *set, size_t size);
void bitset_free(bitset_t *set);
void bitset_set(bitset_t *set, size_t bit);
void bitset_clear(bitset_t *set, size_t bit);
int bitset_test(bitset_t *set, size_t bit);
/* Find first unset bit */
int bitset_ffub(bitset_t *set);

View File

@ -1,20 +0,0 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#pragma once
/*
* Boot Information Types
* Used in the kernel boot process to determine
* how we booted and where we can get BIOS
* information from that bootloader.
*
*/
#include <kernel/system.h>
/*
* Multiboot
* A format managed by GNU and used in GRUB.
* Also supported natively by QEMU and a few
* other emulators.
*/
#include <kernel/multiboot.h>

View File

@ -1,185 +1,353 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab /**
* @file elf.h
* @author K. Lange
* *
* ELF Binary Executable headers * @copyright Copyright in this work is disclaimed under the assertion
* that its contents are purely factual and no rights may be reserved
* for its use.
* *
* @brief Structures for Elf binary files.
*
* Based primarily on the Elf and SysV ABI specification documents.
*
* @see https://uclibc.org/docs/elf-64-gen.pdf
* @see https://refspecs.linuxfoundation.org/elf/x86_64-abi-0.99.pdf
*/ */
#pragma once #pragma once
#include <stdint.h>
/* /**
* Different bits of our build environment * @typedef Elf64_Addr
* require different header files for definitions * @brief Unsigned program address. (uintptr_t)
* @typedef Elf64_Off
* @brief Unsigned file offset. (size_t)
* @typedef Elf64_Half
* @brief Unsigned medium integer. (unsigned short)
* @typedef Elf64_Word
* @brief Unsigned integer. (unsigned int)
* @typedef Elf64_Sword
* @brief Signed integer. (int)
* @typedef Elf64_Xword
* @brief Unsigned long integer. (unsigned long long)
* @typedef Elf64_Sxword
* @brief Signed long integer. (long long)
*/ */
#ifdef _KERNEL_ typedef uint64_t Elf64_Addr;
# include <kernel/types.h> typedef uint64_t Elf64_Off;
#else typedef uint16_t Elf64_Half;
# include <stdint.h> typedef uint32_t Elf64_Word;
#endif typedef int32_t Elf64_Sword;
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;
/* /**
* Unless otherwise stated, the definitions herein * Values for e_ident[EI_MAGn]
* are sourced from the Portable Formats Specification,
* version 1.1 - ELF: Executable and Linkable Format
*/
/*
* ELF Magic Signature
*/ */
#define ELFMAG0 0x7f #define ELFMAG0 0x7f
#define ELFMAG1 'E' #define ELFMAG1 'E'
#define ELFMAG2 'L' #define ELFMAG2 'L'
#define ELFMAG3 'F' #define ELFMAG3 'F'
#define EI_NIDENT 16
/* /**
* ELF Datatypes * Values for e_ident[EI_CLASS]
*/ */
typedef uint32_t Elf32_Word; #define ELFCLASS32 1
typedef uint32_t Elf32_Addr; #define ELFCLASS64 2
typedef uint32_t Elf32_Off;
typedef uint32_t Elf32_Sword;
typedef uint16_t Elf32_Half;
/* /**
* ELF Header * Values for e_ident[EI_DATA]
*/ */
typedef struct { #define ELFDATA2LSB 1
unsigned char e_ident[EI_NIDENT]; #define ELFDATA2MSB 2
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Header;
/* /**
* e_type * Values for e_type
*/ */
#define ET_NONE 0
#define ET_REL 1
#define ET_EXEC 2
#define ET_DYN 3
#define ET_CORE 4
#define ET_NONE 0 /* No file type */ /**
#define ET_REL 1 /* Relocatable file */ * e_ident fields
#define ET_EXEC 2 /* Executable file */
#define ET_DYN 3 /* Shared object file */
#define ET_CORE 4 /* Core file */
#define ET_LOPROC 0xff0 /* [Processor Specific] */
#define ET_HIPROC 0xfff /* [Processor Specific] */
/*
* Machine types
*/ */
#define EM_NONE 0 #define EI_MAG0 0
#define EM_386 3 #define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
#define EI_OSABI 7
#define EI_ABIVERSION 8
#define EI_PAD 9
#define EI_NIDENT 16
#define EV_NONE 0 #define EM_X86_64 62
#define EV_CURRENT 1
/** Program Header */ /**
typedef struct { * @brief Elf object file header.
Elf32_Word p_type; */
Elf32_Off p_offset; typedef struct Elf64_Header {
Elf32_Addr p_vaddr; uint8_t e_ident[EI_NIDENT]; /**< @brief Identifies the layout of the rest of the file. */
Elf32_Addr p_paddr; Elf64_Half e_type; /**< @brief What kind of file this is, eg. object or executable... */
Elf32_Word p_filesz; Elf64_Half e_machine; /**< @brief The architecture this file is for. */
Elf32_Word p_memsz; Elf64_Word e_version; /**< @brief The version of the standard this file confirms to. */
Elf32_Word p_flags; Elf64_Addr e_entry; /**< @brief The entry point of an executable. */
Elf32_Word p_align; Elf64_Off e_phoff; /**< @brief The offset of the program headers. */
} Elf32_Phdr; Elf64_Off e_shoff; /**< @brief The offset of the section headers. */
Elf64_Word e_flags; /**< @brief Various flags. */
Elf64_Half e_ehsize; /**< @brief Size of this header. */
Elf64_Half e_phentsize; /**< @brief Size of one program header table entry. */
Elf64_Half e_phnum; /**< @brief The number of entries in the program header table. */
Elf64_Half e_shentsize; /**< @brief Size of one section header table entry. */
Elf64_Half e_shnum; /**< @brief The number of entries in the section header table. */
Elf64_Half e_shstrndx;
} Elf64_Header;
/* p_type values */ /**
#define PT_NULL 0 /* Unused, skip me */ * Special section indices
#define PT_LOAD 1 /* Loadable segment */ */
#define PT_DYNAMIC 2 /* Dynamic linking information */ #define SHN_UNDEF 0
#define PT_INTERP 3 /* Interpreter (null-terminated string, pathname) */ #define SHN_LOPROC 0xFF00
#define PT_NOTE 4 /* Auxillary information */ #define SHN_HIPROC 0xFF1F
#define PT_SHLIB 5 /* Reserved. */ #define SHN_LOOS 0xFF20
#define PT_PHDR 6 /* Oh, it's me. Hello! Back-reference to the header table itself */ #define SHN_HIOS 0xFF3F
#define PT_LOPROC 0x70000000 #define SHN_ABS 0xFFF1
#define PT_HIPROC 0x7FFFFFFF #define SHN_COMMON 0xFFF2
/**
* Values for sh_type, sh_link, sh_info
*/
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_LOOS 0x60000000
#define SHT_HIOS 0x6FFFFFFF
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7FFFFFFF
/** Section Header */ /**
typedef struct { * Values for sh_flags
Elf32_Word sh_name; */
Elf32_Word sh_type; #define SHF_WRITE 0x00000001
Elf32_Word sh_flags; #define SHF_ALLOC 0x00000002
Elf32_Addr sh_addr; #define SHF_EXECINSTR 0x00000004
Elf32_Off sh_offset; #define SHF_MASKOS 0x0F000000
Elf32_Word sh_size; #define SHF_MASKPROC 0xF0000000
Elf32_Word sh_link; /* From the SysV x86-64 ABI */
Elf32_Word sh_info; #define SHF_X86_64_LARGE 0x10000000
Elf32_Word sh_addralign; #define SHF_X86_64_UNWIND 0x70000001
Elf32_Word sh_entsize;
} Elf32_Shdr;
typedef struct { typedef struct Elf64_Shdr {
uint32_t id; Elf64_Word sh_name;
uintptr_t ptr; Elf64_Word sh_type;
} Elf32_auxv; Elf64_Xword sh_flags;
Elf64_Addr sh_addr;
Elf64_Off sh_offset;
Elf64_Xword sh_size;
Elf64_Word sh_link;
Elf64_Word sh_info;
Elf64_Xword sh_addralign;
Elf64_Xword sh_entsize;
} Elf64_Shdr;
typedef struct { /**
Elf32_Word st_name; * Binding types.
Elf32_Addr st_value; * Contained in the high four bits of @p st_info
Elf32_Word st_size; */
unsigned char st_info; #define STB_LOCAL 0 /**< @brief Not visible outside the object file. */
unsigned char st_other; #define STB_GLOBAL 1 /**< @brief Global symbol, visible to all object files. */
Elf32_Half st_shndx; #define STB_WEAK 2 /**< @brief Global scope, but with lower precedence than global symbols. */
} Elf32_Sym; #define STB_LOOS 10
#define STB_HIOS 12
typedef struct { #define STB_LOPROC 13
Elf32_Addr r_offset; #define STB_HIPROC 15
Elf32_Word r_info;
} Elf32_Rel;
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
Elf32_Off d_off;
} d_un;
} Elf32_Dyn;
/* sh_type values */
#define SHT_NONE 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_NOBITS 8
#define SHT_REL 9
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char)(i))
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
#define ELF32_ST_BIND(i) ((i) >> 4)
#define ELF32_ST_TYPE(i) ((i) & 0xf)
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
#define STB_LOCAL 0
#define STB_GLOBAL 1
#define STB_WEAK 2
#define STB_NUM 3
#define STB_LOPROC 13
#define STB_HIPROC 15
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_COMMON 5
#define STT_TLS 6
#define STT_NUM 7
/**
* Symbol types.
* Contained in the low four bits of @p st_info
*/
#define STT_NOTYPE 0 /**< @brief No type specified (e.g., an absolute symbol) */
#define STT_OBJECT 1 /**< @brief Data object */
#define STT_FUNC 2 /**< @brief Function entry point */
#define STT_SECTION 3 /**< @brief Symbol is associated with a section */
#define STT_FILE 4 /**< @brief Source file associated with the object */
#define STT_LOOS 10
#define STT_HIOS 12
#define STT_LOPROC 13 #define STT_LOPROC 13
#define STT_HIPROC 15 #define STT_HIPROC 15
typedef struct Elf64_Sym {
Elf64_Word st_name; /**< @brief Symbol name */
unsigned char st_info; /**< @brief Type and binding attributes */
unsigned char st_other; /**< @brief Reserved */
Elf64_Half st_shndx; /**< @brief Section table index */
Elf64_Addr st_value; /**< @brief Symbol value */
Elf64_Xword st_size; /**< @brief Size of object (e.g., common) */
} Elf64_Sym;
/**
* Relocations
*/
#define ELF64_R_SYM(i) ((i) >> 32)
#define ELF64_R_TYPE(i) ((i) & 0xFFFFFFFFL)
#define ELF64_R_INFO(s,t) (((s) << 32) + ((t) & 0xFFFFFFFFL))
typedef struct Elf64_Rel {
Elf64_Addr r_offset; /**< @brief Address of reference */
Elf64_Xword r_info; /**< @brief Symbol index and type of relocation */
} Elf64_Rel;
typedef struct Elf64_Rela {
Elf64_Addr r_offset; /**< @brief Address of reference */
Elf64_Xword r_info; /**< @brief Symbol index and type of relocation */
Elf64_Sxword r_addend; /**< @brief Constant part of expression */
} Elf64_Rela;
/**
* x86-64 SysV Relocation types
*/
#define R_X86_64_NONE 0 /**< @brief @p none none */
#define R_X86_64_64 1 /**< @brief @p word64 S + A */
#define R_X86_64_PC32 2 /**< @brief @p word32 S + A - P */
#define R_X86_64_GOT32 3 /**< @brief @p word32 G + A */
#define R_X86_64_PLT32 4 /**< @brief @p word32 L + A - P */
#define R_X86_64_COPY 5 /**< @brief @p none none */
#define R_X86_64_GLOB_DAT 6 /**< @brief @p word64 S */
#define R_X86_64_JUMP_SLOT 7 /**< @brief @p word64 S */
#define R_X86_64_RELATIVE 8 /**< @brief @p word64 B + A */
#define R_X86_64_GOTPCREL 9 /**< @brief @p word32 G + GOT + A - P */
#define R_X86_64_32 10 /**< @brief @p word32 S + A */
#define R_X86_64_32S 11 /**< @brief @p word32 S + A */
/* vvv These should not appear in a valid file */
#define R_X86_64_16 12 /**< @brief @p word16 S + A */
#define R_X86_64_PC16 13 /**< @brief @p word16 S + A - P */
#define R_X86_64_8 14 /**< @brief @p word8 S + A */
#define R_X86_64_PC8 15 /**< @brief @p word8 S + A - P */
/* ^^^ These should not appear in a valid file */
#define R_X86_64_DTPMOD64 16 /**< @brief @p word64 */
#define R_X86_64_DTPOFF64 17 /**< @brief @p word64 */
#define R_X86_64_TPOFF64 18 /**< @brief @p word64 */
#define R_X86_64_TLSGD 19 /**< @brief @p word32 */
#define R_X86_64_TLSLD 20 /**< @brief @p word32 */
#define R_X86_64_DTPOFF32 21 /**< @brief @p word32 */
#define R_X86_64_GOTTPOFF 22 /**< @brief @p word32 */
#define R_X86_64_TPOFF32 23 /**< @brief @p word32 */
#define R_X86_64_PC64 24 /**< @brief @p word64 S + A - P */
#define R_X86_64_GOTOFF64 25 /**< @brief @p word64 S + A - GOT */
#define R_X86_64_GOTPC32 26 /**< @brief @p word32 GOT + A - P */
/* Large model */
#define R_X86_64_GOT64 27 /**< @brief @p word64 G + A */
#define R_X86_64_GOTPCREL64 28 /**< @brief @p word64 G + GOT - P + A */
#define R_X86_64_GOTPC64 29 /**< @brief @p word64 GOT - P + A */
#define R_X86_64_GOTPLT64 30 /**< @brief @p word64 G + A */
#define R_X86_64_PLTOFF64 31 /**< @brief @p word64 L - GOT + A */
/* ... */
#define R_X86_64_SIZE32 32 /**< @brief @p word32 Z + A */
#define R_X86_64_SIZE64 33 /**< @brief @p word64 Z + A */
#define R_X86_64_GOTPC32_TLSDESC 34 /**< @brief @p word32 */
#define R_X86_64_TLSDESC_CALL 35 /**< @brief @p none */
#define R_X86_64_TLSDESC 36 /**< @brief @p word64*2 */
#define R_X86_64_IRELATIVE 37 /**< @brief @p word64 indirect (B + A) */
/**
* Program header types
*/
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_TLS 7
#define PT_LOOS 0x60000000
#define PT_HIOS 0x6FFFFFFF
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7FFFFFFF
/* From the SysV x86-64 ABI */
#define PT_GNU_EH_FRAME 0x6474e550
#define PT_SUNW_EH_FRAME 0x6474e550
#define PT_SUNW_UNWIND 0x6464e550
/**
* Program header flags
*/
#define PF_X 0x01
#define PF_W 0x02
#define PF_R 0x04
#define PF_MASKOS 0x00FF0000
#define PF_MAKSPROC 0xFF000000
typedef struct Elf64_Phdr {
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
} Elf64_Phdr;
/**
* Dynamic table
*/
#define DT_NULL 0
#define DT_NEEDED 1
#define DT_PLTRELSZ 2
#define DT_PLTGOT 3
#define DT_HASH 4
#define DT_STRTAB 5
#define DT_SYMTAB 6
#define DT_RELA 7
#define DT_RELASZ 8
#define DT_RELAENT 9
#define DT_STRSZ 10
#define DT_SYMENT 11
#define DT_INIT 12
#define DT_FINI 13
#define DT_SONAME 14
#define DT_RPATH 15
#define DT_SYMBOLIC 16
#define DT_REL 17
#define DT_RELSZ 18
#define DT_RELENT 19
#define DT_PLTREL 20
#define DT_DEBUG 21
#define DT_TEXTREL 22
#define DT_JMPREL 23
#define DT_BIND_NOW 24
#define DT_INIT_ARRAY 25
#define DT_FINI_ARRAY 26
#define DT_INIT_ARRAYSZ 27
#define DT_FINI_ARRAYSZ 28
#define DT_LOOS 0x60000000
#define DT_HIOS 0x6FFFFFFF
#define DT_LOPROC 0x70000000
#define DT_HIPROC 0x7FFFFFFF
typedef struct Elf64_Dyn {
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;

View File

@ -1,174 +0,0 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#pragma once
#ifdef _KERNEL_
# include <kernel/types.h>
#else
# ifdef BOOTLOADER
# include <kernel/types.h>
# else
# include <stdint.h>
# endif
#endif
#define EXT2_SUPER_MAGIC 0xEF53
#define EXT2_DIRECT_BLOCKS 12
/* Super block struct. */
struct ext2_superblock {
uint32_t inodes_count;
uint32_t blocks_count;
uint32_t r_blocks_count;
uint32_t free_blocks_count;
uint32_t free_inodes_count;
uint32_t first_data_block;
uint32_t log_block_size;
uint32_t log_frag_size;
uint32_t blocks_per_group;
uint32_t frags_per_group;
uint32_t inodes_per_group;
uint32_t mtime;
uint32_t wtime;
uint16_t mnt_count;
uint16_t max_mnt_count;
uint16_t magic;
uint16_t state;
uint16_t errors;
uint16_t minor_rev_level;
uint32_t lastcheck;
uint32_t checkinterval;
uint32_t creator_os;
uint32_t rev_level;
uint16_t def_resuid;
uint16_t def_resgid;
/* EXT2_DYNAMIC_REV */
uint32_t first_ino;
uint16_t inode_size;
uint16_t block_group_nr;
uint32_t feature_compat;
uint32_t feature_incompat;
uint32_t feature_ro_compat;
uint8_t uuid[16];
uint8_t volume_name[16];
uint8_t last_mounted[64];
uint32_t algo_bitmap;
/* Performance Hints */
uint8_t prealloc_blocks;
uint8_t prealloc_dir_blocks;
uint16_t _padding;
/* Journaling Support */
uint8_t journal_uuid[16];
uint32_t journal_inum;
uint32_t jounral_dev;
uint32_t last_orphan;
/* Directory Indexing Support */
uint32_t hash_seed[4];
uint8_t def_hash_version;
uint16_t _padding_a;
uint8_t _padding_b;
/* Other Options */
uint32_t default_mount_options;
uint32_t first_meta_bg;
uint8_t _unused[760];
} __attribute__ ((packed));
typedef struct ext2_superblock ext2_superblock_t;
/* Block group descriptor. */
struct ext2_bgdescriptor {
uint32_t block_bitmap;
uint32_t inode_bitmap; // block no. of inode bitmap
uint32_t inode_table;
uint16_t free_blocks_count;
uint16_t free_inodes_count;
uint16_t used_dirs_count;
uint16_t pad;
uint8_t reserved[12];
} __attribute__ ((packed));
typedef struct ext2_bgdescriptor ext2_bgdescriptor_t;
/* File Types */
#define EXT2_S_IFSOCK 0xC000
#define EXT2_S_IFLNK 0xA000
#define EXT2_S_IFREG 0x8000
#define EXT2_S_IFBLK 0x6000
#define EXT2_S_IFDIR 0x4000
#define EXT2_S_IFCHR 0x2000
#define EXT2_S_IFIFO 0x1000
/* setuid, etc. */
#define EXT2_S_ISUID 0x0800
#define EXT2_S_ISGID 0x0400
#define EXT2_S_ISVTX 0x0200
/* rights */
#define EXT2_S_IRUSR 0x0100
#define EXT2_S_IWUSR 0x0080
#define EXT2_S_IXUSR 0x0040
#define EXT2_S_IRGRP 0x0020
#define EXT2_S_IWGRP 0x0010
#define EXT2_S_IXGRP 0x0008
#define EXT2_S_IROTH 0x0004
#define EXT2_S_IWOTH 0x0002
#define EXT2_S_IXOTH 0x0001
/* This is not actually the inode table.
* It represents an inode in an inode table on disk. */
struct ext2_inodetable {
uint16_t mode;
uint16_t uid;
uint32_t size; // file length in byte.
uint32_t atime;
uint32_t ctime;
uint32_t mtime;
uint32_t dtime;
uint16_t gid;
uint16_t links_count;
uint32_t blocks;
uint32_t flags;
uint32_t osd1;
uint32_t block[15];
uint32_t generation;
uint32_t file_acl;
uint32_t dir_acl;
uint32_t faddr;
uint8_t osd2[12];
} __attribute__ ((packed));
typedef struct ext2_inodetable ext2_inodetable_t;
/* Represents directory entry on disk. */
struct ext2_dir {
uint32_t inode;
uint16_t rec_len;
uint8_t name_len;
uint8_t file_type;
char name[]; /* Actually a set of characters, at most 255 bytes */
} __attribute__ ((packed));
typedef struct ext2_dir ext2_dir_t;
typedef struct {
uint32_t block_no;
uint32_t last_use;
uint8_t dirty;
uint8_t *block;
} ext2_disk_cache_entry_t;
typedef int (*ext2_block_io_t) (void *, uint32_t, uint8_t *);

View File

@ -0,0 +1,22 @@
#pragma once
/**
* @brief Initialize early subsystems.
*
* Should be called after the architecture-specific startup routine has
* enabled all hardware required for tasking switching and memory management.
*
* Initializes the scheduler, shared memory subsystem, and virtual file system;
* mounts generic device drivers, sets up the virtual /dev directory, parses
* the architecture-provided kernel arguments, and enables scheduling by
* launching the idle task and converting the current context to 'init'.
*/
void generic_startup(void);
/**
* @brief Starts init.
*
* Should be called after all architecture-specific initialization is completed.
* Parses the boot arguments and executes /bin/init.
*/
int generic_main(void);

View File

@ -0,0 +1,16 @@
/**
* @brief Kernel gzip decompressor
*
* This is a slimmed down version of libtoaru_inflate; it's an implementation
* of the tinf algorithm for decompressing gzip/DEFLATE payloads, with a
* very straightforward API: Point @c gzip_inputPtr at your gzip data,
* point @c gzip_outputPtr where you want the output to go, and then
* run @c gzip_decompress().
*/
#pragma once
#include <stdint.h>
extern int gzip_decompress(void);
extern uint8_t * gzip_inputPtr;
extern uint8_t * gzip_outputPtr;

View File

@ -0,0 +1,42 @@
#pragma once
#include <stddef.h>
#include <kernel/string.h>
#include <kernel/list.h>
typedef unsigned int (*hashmap_hash_t) (const void * key);
typedef int (*hashmap_comp_t) (const void * a, const void * b);
typedef void (*hashmap_free_t) (void *);
typedef void * (*hashmap_dupe_t) (const void *);
typedef struct hashmap_entry {
char * key;
void * value;
struct hashmap_entry * next;
} hashmap_entry_t;
typedef struct hashmap {
hashmap_hash_t hash_func;
hashmap_comp_t hash_comp;
hashmap_dupe_t hash_key_dup;
hashmap_free_t hash_key_free;
hashmap_free_t hash_val_free;
size_t size;
hashmap_entry_t ** entries;
} hashmap_t;
extern hashmap_t * hashmap_create(int size);
extern hashmap_t * hashmap_create_int(int size);
extern void * hashmap_set(hashmap_t * map, const void * key, void * value);
extern void * hashmap_get(hashmap_t * map, const void * key);
extern void * hashmap_remove(hashmap_t * map, const void * key);
extern int hashmap_has(hashmap_t * map, const void * key);
extern list_t * hashmap_keys(hashmap_t * map);
extern list_t * hashmap_values(hashmap_t * map);
extern void hashmap_free(hashmap_t * map);
extern unsigned int hashmap_string_hash(const void * key);
extern int hashmap_string_comp(const void * a, const void * b);
extern void * hashmap_string_dupe(const void * key);
extern int hashmap_is_empty(hashmap_t * map);

View File

@ -1,188 +0,0 @@
#pragma once
#include <kernel/system.h>
struct ethernet_packet {
uint8_t destination[6];
uint8_t source[6];
uint16_t type;
uint8_t payload[];
} __attribute__((packed));
struct ipv4_packet {
uint8_t version_ihl;
uint8_t dscp_ecn;
uint16_t length;
uint16_t ident;
uint16_t flags_fragment;
uint8_t ttl;
uint8_t protocol;
uint16_t checksum;
uint32_t source;
uint32_t destination;
uint8_t payload[];
} __attribute__ ((packed));
struct udp_packet {
uint16_t source_port;
uint16_t destination_port;
uint16_t length;
uint16_t checksum;
uint8_t payload[];
} __attribute__ ((packed));
struct dhcp_packet {
uint8_t op;
uint8_t htype;
uint8_t hlen;
uint8_t hops;
uint32_t xid;
uint16_t secs;
uint16_t flags;
uint32_t ciaddr;
uint32_t yiaddr;
uint32_t siaddr;
uint32_t giaddr;
uint8_t chaddr[16];
uint8_t sname[64];
uint8_t file[128];
uint32_t magic;
uint8_t options[];
} __attribute__ ((packed));
struct dns_packet {
uint16_t qid;
uint16_t flags;
uint16_t questions;
uint16_t answers;
uint16_t authorities;
uint16_t additional;
uint8_t data[];
} __attribute__ ((packed));
struct tcp_header {
uint16_t source_port;
uint16_t destination_port;
uint32_t seq_number;
uint32_t ack_number;
uint16_t flags;
uint16_t window_size;
uint16_t checksum;
uint16_t urgent;
uint8_t payload[];
} __attribute__((packed));
struct tcp_check_header {
uint32_t source;
uint32_t destination;
uint8_t zeros;
uint8_t protocol;
uint16_t tcp_len;
uint8_t tcp_header[];
};
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
// Note: Data offset is in upper 4 bits of flags field. Shift and subtract 5 since that is the min TCP size.
// If the value is more than 5, multiply by 4 because this field is specified in number of words
#define TCP_OPTIONS_LENGTH(tcp) (((((tcp)->flags) >> 12) - 5) * 4)
#define TCP_HEADER_LENGTH(tcp) ((((tcp)->flags) >> 12) * 4)
#define TCP_HEADER_LENGTH_FLIPPED(tcp) (((htons((tcp)->flags)) >> 12) * 4)
#define htonl(l) ( (((l) & 0xFF) << 24) | (((l) & 0xFF00) << 8) | (((l) & 0xFF0000) >> 8) | (((l) & 0xFF000000) >> 24))
#define htons(s) ( (((s) & 0xFF) << 8) | (((s) & 0xFF00) >> 8) )
#define ntohl(l) htonl((l))
#define ntohs(s) htons((s))
#define BROADCAST_MAC {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
#define IPV4_PROT_UDP 17
#define IPV4_PROT_TCP 6
#define DHCP_MAGIC 0x63825363
#define TCP_FLAGS_FIN (1 << 0)
#define TCP_FLAGS_SYN (1 << 1)
#define TCP_FLAGS_RES (1 << 2)
#define TCP_FLAGS_PSH (1 << 3)
#define TCP_FLAGS_ACK (1 << 4)
#define TCP_FLAGS_URG (1 << 5)
#define TCP_FLAGS_ECE (1 << 6)
#define TCP_FLAGS_CWR (1 << 7)
#define TCP_FLAGS_NS (1 << 8)
#define DATA_OFFSET_5 (0x5 << 12)
#define ETHERNET_TYPE_IPV4 0x0800
#define ETHERNET_TYPE_ARP 0x0806
extern uint32_t ip_aton(const char * in);
extern void ip_ntoa(uint32_t src_addr, char * out);
extern uint16_t calculate_ipv4_checksum(struct ipv4_packet * p);
uint16_t calculate_tcp_checksum(struct tcp_check_header * p, struct tcp_header * h, void * d, size_t d_words);
struct tcp_socket {
list_t* is_connected;
uint32_t seq_no;
uint32_t ack_no;
int status;
};
// Note: for now, not sure what to put in here, so removing from the union to get rid of compiler warnings about empty struct
// struct udp_socket {
// };
struct socket {
uint32_t ip;
uint8_t mac[6];
uint32_t port_dest;
uint32_t port_recv;
list_t* packet_queue;
spin_lock_t packet_queue_lock;
list_t* packet_wait;
int32_t status;
size_t bytes_available;
size_t bytes_read;
void * current_packet;
uint32_t sock_type;
union {
struct tcp_socket tcp_socket;
// struct udp_socket udp_socket;
} proto_sock;
list_t * alert_waiters;
};
struct sized_blob {
size_t size;
uint8_t blob[];
};
struct in_addr {
unsigned long s_addr; // load with inet_pton()
};
struct sockaddr {
uint16_t sa_family;
char sa_data[14];
};
struct sockaddr_in {
short sin_family; // e.g. AF_INET, AF_INET6
unsigned short sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see struct in_addr, below
char sin_zero[8]; // zero this if you want to
};
typedef struct {
uint8_t *payload;
size_t payload_size;
} tcpdata_t;

View File

@ -0,0 +1,50 @@
/**
* @brief General-purpose doubly-linked list.
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
typedef struct node {
struct node * next;
struct node * prev;
void * value;
struct ListHeader * owner;
} __attribute__((packed)) node_t;
typedef struct ListHeader {
node_t * head;
node_t * tail;
size_t length;
const char * name;
const void * metadata;
} __attribute__((packed)) list_t;
extern void list_destroy(list_t * list);
extern void list_free(list_t * list);
extern void list_append(list_t * list, node_t * item);
extern node_t * list_insert(list_t * list, void * item);
extern list_t * list_create(const char * name, const void * metadata);
extern node_t * list_find(list_t * list, void * value);
extern int list_index_of(list_t * list, void * value);
extern void list_remove(list_t * list, size_t index);
extern void list_delete(list_t * list, node_t * node);
extern node_t * list_pop(list_t * list);
extern node_t * list_dequeue(list_t * list);
extern list_t * list_copy(list_t * original);
extern void list_merge(list_t * target, list_t * source);
extern void * list_index(list_t * list, int index);
extern void list_append_after(list_t * list, node_t * before, node_t * node);
extern node_t * list_insert_after(list_t * list, node_t * before, void * item);
extern void list_append_before(list_t * list, node_t * after, node_t * node);
extern node_t * list_insert_before(list_t * list, node_t * after, void * item);
/* Known to conflict with some popular third-party libraries. */
#ifndef TOARU_LIST_NO_FOREACH
# define foreach(i, list) for (node_t * i = (list)->head; i != NULL; i = i->next)
# define foreachr(i, list) for (node_t * i = (list)->tail; i != NULL; i = i->prev)
#endif

View File

@ -1,27 +0,0 @@
#pragma once
typedef enum {
INFO = 0, /* Unimportant */
NOTICE, /* Important, but not bad */
WARNING, /* Not what was expected, but still okay */
ERROR, /* This is bad... */
CRITICAL, /* Shit */
INSANE
} log_type_t;
extern log_type_t debug_level;
extern void * debug_file;
extern void _debug_print(char * title, int line_no, log_type_t level, char *fmt, ...);
extern void (*debug_hook)(void *, char *);
extern void (*debug_video_crash)(char **);
#ifndef MODULE_NAME
#define MODULE_NAME __FILE__
#endif
#ifndef QUIET
#define debug_print(level, ...) _debug_print(MODULE_NAME, __LINE__, level, __VA_ARGS__)
#else
#define debug_print(level, ...)
#endif

View File

@ -1,16 +0,0 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#pragma once
#include <kernel/types.h>
extern uintptr_t heap_end;
extern void set_frame(uintptr_t frame_addr);
extern void clear_frame(uintptr_t frame_addr);
extern uint32_t test_frame(uintptr_t frame_addr);
extern uint32_t first_frame(void);
extern uintptr_t map_to_physical(uintptr_t virtual);

View File

@ -0,0 +1,14 @@
#pragma once
#include <kernel/types.h>
size_t arch_cpu_mhz(void);
const char * arch_get_cmdline(void);
const char * arch_get_loader(void);
void arch_pause(void);
void arch_fatal(void);
void arch_set_tls_base(uintptr_t tlsbase);
long arch_reboot(void);

View File

@ -0,0 +1,2 @@
#pragma once
#include <kernel/arch/x86_64/mmu.h>

View File

@ -1,6 +1,8 @@
#ifndef KERNEL_MOD_NET_H #ifndef KERNEL_MOD_NET_H
#define KERNEL_MOD_NET_H #define KERNEL_MOD_NET_H
#include <stdint.h>
typedef uint8_t* (*get_mac_func)(void); typedef uint8_t* (*get_mac_func)(void);
typedef struct ethernet_packet* (*get_packet_func)(void); typedef struct ethernet_packet* (*get_packet_func)(void);
typedef void (*send_packet_func)(uint8_t*, size_t); typedef void (*send_packet_func)(uint8_t*, size_t);

View File

@ -4,9 +4,8 @@
/* The format isn't really used for anything right now */ /* The format isn't really used for anything right now */
#define SND_FORMAT_L16SLE 0 /* Linear 16-bit signed little endian */ #define SND_FORMAT_L16SLE 0 /* Linear 16-bit signed little endian */
#include <stdint.h>
#include <kernel/mod/sound.h> #include <kernel/mod/sound.h>
#include <kernel/logging.h>
#include <kernel/system.h>
#define SND_KNOB_VENDOR 1024 #define SND_KNOB_VENDOR 1024

View File

@ -1,43 +0,0 @@
#pragma once
#include <kernel/types.h>
#include <toaru/hashmap.h>
typedef struct {
char * name;
int (* initialize)(void);
int (* finalize)(void);
} module_defs;
typedef struct {
module_defs * mod_info;
void * bin_data;
hashmap_t * symbols;
uintptr_t end;
size_t deps_length;
char * deps;
uintptr_t text_addr;
} module_data_t;
void (* symbol_find(const char * name))(void);
extern int module_quickcheck(void * blob);
extern void * module_load_direct(void * blob, size_t size);
extern void * module_load(char * filename);
extern void module_unload(char * name);
extern void modules_install(void);
#define MODULE_DEF(n,init,fini) \
module_defs module_info_ ## n = { \
.name = #n, \
.initialize = &init, \
.finalize = &fini \
}
extern hashmap_t * modules_get_list(void);
extern hashmap_t * modules_get_symbols(void);
#define MODULE_DEPENDS(n) \
static char _mod_dependency_ ## n [] __attribute__((section("moddeps"), used)) = #n

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <stdint.h>
typedef enum { typedef enum {
LEFT_CLICK = 0x01, LEFT_CLICK = 0x01,
RIGHT_CLICK = 0x02, RIGHT_CLICK = 0x02,

View File

@ -1,8 +1,6 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#pragma once #pragma once
#include <kernel/system.h> #include <kernel/types.h>
#define MULTIBOOT_MAGIC 0x1BADB002 #define MULTIBOOT_MAGIC 0x1BADB002
#define MULTIBOOT_EAX_MAGIC 0x2BADB002 #define MULTIBOOT_EAX_MAGIC 0x2BADB002
@ -13,7 +11,7 @@
#define MULTIBOOT_FLAG_AOUT 0x010 #define MULTIBOOT_FLAG_AOUT 0x010
#define MULTIBOOT_FLAG_ELF 0x020 #define MULTIBOOT_FLAG_ELF 0x020
#define MULTIBOOT_FLAG_MMAP 0x040 #define MULTIBOOT_FLAG_MMAP 0x040
#define MULTIBOOT_FLAG_DRIVE 0x080 #define MULTIBOOT_FLAG_DRIVER 0x080
#define MULTIBOOT_FLAG_CONFIG 0x100 #define MULTIBOOT_FLAG_CONFIG 0x100
#define MULTIBOOT_FLAG_LOADER 0x200 #define MULTIBOOT_FLAG_LOADER 0x200
#define MULTIBOOT_FLAG_APM 0x400 #define MULTIBOOT_FLAG_APM 0x400
@ -22,37 +20,44 @@
struct multiboot struct multiboot
{ {
uintptr_t flags; uint32_t flags;
uintptr_t mem_lower; uint32_t mem_lower;
uintptr_t mem_upper; uint32_t mem_upper;
uintptr_t boot_device; uint32_t boot_device;
uintptr_t cmdline; uint32_t cmdline;
uintptr_t mods_count; uint32_t mods_count;
uintptr_t mods_addr; uint32_t mods_addr;
uintptr_t num;
uintptr_t size; uint32_t num;
uintptr_t addr; uint32_t size;
uintptr_t shndx; uint32_t addr;
uintptr_t mmap_length; uint32_t shndx;
uintptr_t mmap_addr;
uintptr_t drives_length; uint32_t mmap_length;
uintptr_t drives_addr; uint32_t mmap_addr;
uintptr_t config_table;
uintptr_t boot_loader_name; uint32_t drives_length;
uintptr_t apm_table; uint32_t drives_addr;
uintptr_t vbe_control_info;
uintptr_t vbe_mode_info; uint32_t config_table;
uintptr_t vbe_mode;
uintptr_t vbe_interface_seg; uint32_t boot_loader_name;
uintptr_t vbe_interface_off;
uintptr_t vbe_interface_len; uint32_t apm_table;
uintptr_t framebuffer_addr;
uintptr_t framebuffer_pitch; uint32_t vbe_control_info;
uintptr_t framebuffer_width; uint32_t vbe_mode_info;
uintptr_t framebuffer_height; uint16_t vbe_mode;
uint8_t framebuffer_bpp; uint16_t vbe_interface_seg;
uint8_t framebuffer_type; uint16_t vbe_interface_off;
/* Palette stuff goes here but we don't use it */ uint16_t vbe_interface_len;
uint64_t framebuffer_addr;
uint32_t framebuffer_pitch;
uint32_t framebuffer_width;
uint32_t framebuffer_height;
uint8_t framebuffer_bpp;
uint8_t framebuffer_type;
} __attribute__ ((packed)); } __attribute__ ((packed));
typedef struct { typedef struct {
@ -81,10 +86,10 @@ typedef struct {
} __attribute__ ((packed)) vbe_info_t; } __attribute__ ((packed)) vbe_info_t;
typedef struct { typedef struct {
uintptr_t mod_start; uint32_t mod_start;
uintptr_t mod_end; uint32_t mod_end;
uintptr_t cmdline; uint32_t cmdline;
uintptr_t reserved; uint32_t reserved;
} __attribute__ ((packed)) mboot_mod_t; } __attribute__ ((packed)) mboot_mod_t;
typedef struct { typedef struct {
@ -94,8 +99,3 @@ typedef struct {
uint32_t type; uint32_t type;
} __attribute__ ((packed)) mboot_memmap_t; } __attribute__ ((packed)) mboot_memmap_t;
extern struct multiboot *copy_multiboot(struct multiboot *mboot_ptr);
extern void dump_multiboot(struct multiboot *mboot_ptr);
extern char * ramdisk;
extern struct multiboot * mboot_ptr;

View File

@ -0,0 +1,102 @@
#pragma once
#include <stdint.h>
#define E1000_REG_CTRL 0x0000
#define E1000_REG_STATUS 0x0008
#define E1000_REG_EEPROM 0x0014
#define E1000_REG_CTRL_EXT 0x0018
#define E1000_REG_ICR 0x00C0
#define E1000_REG_RCTRL 0x0100
#define E1000_REG_RXDESCLO 0x2800
#define E1000_REG_RXDESCHI 0x2804
#define E1000_REG_RXDESCLEN 0x2808
#define E1000_REG_RXDESCHEAD 0x2810
#define E1000_REG_RXDESCTAIL 0x2818
#define E1000_REG_TCTRL 0x0400
#define E1000_REG_TXDESCLO 0x3800
#define E1000_REG_TXDESCHI 0x3804
#define E1000_REG_TXDESCLEN 0x3808
#define E1000_REG_TXDESCHEAD 0x3810
#define E1000_REG_TXDESCTAIL 0x3818
#define E1000_REG_RXADDR 0x5400
#define E1000_NUM_RX_DESC 32
#define E1000_NUM_TX_DESC 8
#define RCTL_EN (1 << 1) /* Receiver Enable */
#define RCTL_SBP (1 << 2) /* Store Bad Packets */
#define RCTL_UPE (1 << 3) /* Unicast Promiscuous Enabled */
#define RCTL_MPE (1 << 4) /* Multicast Promiscuous Enabled */
#define RCTL_LPE (1 << 5) /* Long Packet Reception Enable */
#define RCTL_LBM_NONE (0 << 6) /* No Loopback */
#define RCTL_LBM_PHY (3 << 6) /* PHY or external SerDesc loopback */
#define RCTL_RDMTS_HALF (0 << 8) /* Free Buffer Threshold is 1/2 of RDLEN */
#define RCTL_RDMTS_QUARTER (1 << 8) /* Free Buffer Threshold is 1/4 of RDLEN */
#define RCTL_RDMTS_EIGHTH (2 << 8) /* Free Buffer Threshold is 1/8 of RDLEN */
#define RCTL_MO_36 (0 << 12) /* Multicast Offset - bits 47:36 */
#define RCTL_MO_35 (1 << 12) /* Multicast Offset - bits 46:35 */
#define RCTL_MO_34 (2 << 12) /* Multicast Offset - bits 45:34 */
#define RCTL_MO_32 (3 << 12) /* Multicast Offset - bits 43:32 */
#define RCTL_BAM (1 << 15) /* Broadcast Accept Mode */
#define RCTL_VFE (1 << 18) /* VLAN Filter Enable */
#define RCTL_CFIEN (1 << 19) /* Canonical Form Indicator Enable */
#define RCTL_CFI (1 << 20) /* Canonical Form Indicator Bit Value */
#define RCTL_DPF (1 << 22) /* Discard Pause Frames */
#define RCTL_PMCF (1 << 23) /* Pass MAC Control Frames */
#define RCTL_SECRC (1 << 26) /* Strip Ethernet CRC */
#define RCTL_BSIZE_256 (3 << 16)
#define RCTL_BSIZE_512 (2 << 16)
#define RCTL_BSIZE_1024 (1 << 16)
#define RCTL_BSIZE_2048 (0 << 16)
#define RCTL_BSIZE_4096 ((3 << 16) | (1 << 25))
#define RCTL_BSIZE_8192 ((2 << 16) | (1 << 25))
#define RCTL_BSIZE_16384 ((1 << 16) | (1 << 25))
#define TCTL_EN (1 << 1) /* Transmit Enable */
#define TCTL_PSP (1 << 3) /* Pad Short Packets */
#define TCTL_CT_SHIFT 4 /* Collision Threshold */
#define TCTL_COLD_SHIFT 12 /* Collision Distance */
#define TCTL_SWXOFF (1 << 22) /* Software XOFF Transmission */
#define TCTL_RTLC (1 << 24) /* Re-transmit on Late Collision */
#define CMD_EOP (1 << 0) /* End of Packet */
#define CMD_IFCS (1 << 1) /* Insert FCS */
#define CMD_IC (1 << 2) /* Insert Checksum */
#define CMD_RS (1 << 3) /* Report Status */
#define CMD_RPS (1 << 4) /* Report Packet Sent */
#define CMD_VLE (1 << 6) /* VLAN Packet Enable */
#define CMD_IDE (1 << 7) /* Interrupt Delay Enable */
#define ICR_TXDW (1 << 0)
#define ICR_TXQE (1 << 1) /* Transmit queue is empty */
#define ICR_LSC (1 << 2) /* Link status changed */
#define ICR_RXSEQ (1 << 3) /* Receive sequence count error */
#define ICR_RXDMT0 (1 << 4) /* Receive descriptor minimum threshold */
/* what's 5 (0x20)? */
#define ICR_RXO (1 << 6) /* Receive overrun */
#define ICR_RXT0 (1 << 7) /* Receive timer interrupt? */
struct e1000_rx_desc {
volatile uint64_t addr;
volatile uint16_t length;
volatile uint16_t checksum;
volatile uint8_t status;
volatile uint8_t errors;
volatile uint16_t special;
} __attribute__((packed)); /* this looks like it should pack fine as-is */
struct e1000_tx_desc {
volatile uint64_t addr;
volatile uint16_t length;
volatile uint8_t cso;
volatile uint8_t cmd;
volatile uint8_t status;
volatile uint8_t css;
volatile uint16_t special;
} __attribute__((packed));

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <stdint.h>
#define PCI_VENDOR_ID 0x00 // 2 #define PCI_VENDOR_ID 0x00 // 2
#define PCI_DEVICE_ID 0x02 // 2 #define PCI_DEVICE_ID 0x02 // 2
#define PCI_COMMAND 0x04 // 2 #define PCI_COMMAND 0x04 // 2
@ -59,10 +61,10 @@ static inline uint32_t pci_box_device(int bus, int slot, int func) {
uint32_t pci_read_field(uint32_t device, int field, int size); uint32_t pci_read_field(uint32_t device, int field, int size);
void pci_write_field(uint32_t device, int field, int size, uint32_t value); void pci_write_field(uint32_t device, int field, int size, uint32_t value);
uint16_t pci_find_type(uint32_t dev); uint16_t pci_find_type(uint32_t dev);
void pci_scan_hit(pci_func_t f, uint32_t dev, void * extra);
void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func, void * extra); void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func, void * extra);
void pci_scan_slot(pci_func_t f, int type, int bus, int slot, void * extra); void pci_scan_slot(pci_func_t f, int type, int bus, int slot, void * extra);
void pci_scan_bus(pci_func_t f, int type, int bus, void * extra); void pci_scan_bus(pci_func_t f, int type, int bus, void * extra);
void pci_scan(pci_func_t f, int type, void * extra); void pci_scan(pci_func_t f, int type, void * extra);
void pci_remap(void); void pci_remap(void);
int pci_get_interrupt(uint32_t device); int pci_get_interrupt(uint32_t device);

View File

@ -5,7 +5,10 @@
#pragma once #pragma once
#include <kernel/types.h> #include <stddef.h>
#include <kernel/vfs.h>
#include <kernel/list.h>
#include <kernel/spinlock.h>
typedef struct _pipe_device { typedef struct _pipe_device {
uint8_t * buffer; uint8_t * buffer;
@ -13,12 +16,16 @@ typedef struct _pipe_device {
size_t read_ptr; size_t read_ptr;
size_t size; size_t size;
size_t refcount; size_t refcount;
volatile int lock_read[2];
volatile int lock_write[2];
list_t * wait_queue_readers; list_t * wait_queue_readers;
list_t * wait_queue_writers; list_t * wait_queue_writers;
int dead; int dead;
list_t * alert_waiters; list_t * alert_waiters;
spin_lock_t lock_read;
spin_lock_t lock_write;
spin_lock_t alert_lock;
spin_lock_t wait_lock;
spin_lock_t ptr_lock;
} pipe_device_t; } pipe_device_t;
fs_node_t * make_pipe(size_t size); fs_node_t * make_pipe(size_t size);

View File

@ -1,10 +1,9 @@
#pragma once #pragma once
#include <va_list.h> #include <kernel/types.h>
#include <kernel/fs.h>
extern size_t vasprintf(char * buf, const char *fmt, va_list args);
extern int sprintf(char *buf, const char *fmt, ...);
extern int fprintf(fs_node_t * device, char *fmt, ...);
__attribute__((format(__printf__,1,2)))
extern int printf(const char *fmt, ...);
extern size_t (*printf_output)(size_t, uint8_t *);
__attribute__((format(__printf__,3,4)))
extern int snprintf(char * str, size_t size, const char * format, ...);

View File

@ -1,162 +1,220 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#pragma once #pragma once
#include <kernel/signal.h> #include <stdint.h>
#include <kernel/task.h> #include <kernel/types.h>
#include <kernel/vfs.h>
#include <kernel/tree.h>
#include <kernel/list.h>
#include <kernel/spinlock.h>
#include <kernel/arch/x86_64/pml.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/signal_defs.h>
#include <toaru/tree.h> #define PROC_REUSE_FDS 0x0001
#define KERNEL_STACK_SIZE 0x9000
#define USER_ROOT_UID 0
#define KERNEL_STACK_SIZE 0x8000 typedef struct {
intptr_t refcount;
union PML * directory;
spin_lock_t lock;
} page_directory_t;
typedef signed int pid_t; typedef struct {
typedef unsigned int user_t; uintptr_t sp; /* 0 */
typedef unsigned int status_t; uintptr_t bp; /* 8 */
uintptr_t ip; /* 16 */
uintptr_t tls_base; /* 24 */
uintptr_t saved[5]; /* XXX Arch dependent */
/**
* 32: rbx
* 40: r12
* 48: r13
* 56: r14
* 64: r15
*/
} kthread_context_t;
#define USER_ROOT_UID (user_t)0
/* Unix waitpid() options */
enum wait_option{
WCONTINUED,
WNOHANG,
WUNTRACED
};
/* x86 task */
typedef struct thread { typedef struct thread {
uintptr_t esp; /* Stack Pointer */ kthread_context_t context;
uintptr_t ebp; /* Base Pointer */ uint8_t fp_regs[512];
uintptr_t eip; /* Instruction Pointer */ page_directory_t * page_directory;
uint8_t fpu_enabled;
uint8_t fp_regs[512];
uint8_t padding[32]; /* I don't know */
page_directory_t * page_directory; /* Page Directory */
uintptr_t gsbase;
} thread_t; } thread_t;
/* Portable image struct */
typedef struct image { typedef struct image {
size_t size; /* Image size */ uintptr_t entry;
uintptr_t entry; /* Binary entry point */ uintptr_t heap;
uintptr_t heap; /* Heap pointer */ uintptr_t stack;
uintptr_t heap_actual; /* Actual heap location */
uintptr_t stack; /* Process kernel stack */
uintptr_t user_stack; /* User stack */
uintptr_t start;
uintptr_t shm_heap; uintptr_t shm_heap;
volatile int lock[2]; spin_lock_t lock;
} image_t; } image_t;
/* Resizable descriptor table */ typedef struct file_descriptors {
typedef struct descriptor_table {
fs_node_t ** entries; fs_node_t ** entries;
uint64_t * offsets; uint64_t * offsets;
int * modes; int * modes;
size_t length; size_t length;
size_t capacity; size_t capacity;
size_t refs; size_t refs;
spin_lock_t lock;
} fd_table_t; } fd_table_t;
/* XXX */ #define PROC_FLAG_IS_TASKLET 0x01
#define SIG_COUNT 10 #define PROC_FLAG_FINISHED 0x02
#define PROC_FLAG_STARTED 0x04
#define PROC_FLAG_RUNNING 0x08
#define PROC_FLAG_SLEEP_INT 0x10
#define PROC_FLAG_SUSPENDED 0x20
/* Signal Table */
typedef struct signal_table {
uintptr_t functions[NUMSIGNALS+1];
} sig_table_t;
/* Portable process struct */
typedef struct process { typedef struct process {
pid_t id; /* Process ID (pid) */ pid_t id; /* PID */
char * name; /* Process Name */ pid_t group; /* thread group */
char * description; /* Process description */ pid_t job; /* tty job */
user_t user; /* Effective user */ pid_t session; /* tty session */
user_t real_user; /* Real user ID */ int status; /* status code */
int mask; /* Umask */ unsigned int flags; /* finished, started, running, isTasklet */
int owner;
char ** cmdline; uid_t user;
uid_t real_user;
unsigned int mask;
pid_t group; /* Process thread group */ char * name;
pid_t job; /* Process job group */ char * description;
pid_t session; /* Session group */ char ** cmdline;
thread_t thread; /* Associated task information */ char * wd_name;
tree_node_t * tree_entry; /* Process Tree Entry */ fs_node_t * wd_node;
image_t image; /* Binary image information */
fs_node_t * wd_node; /* Working directory VFS node */
char * wd_name; /* Working directory path name */
fd_table_t * fds; /* File descriptor table */ fd_table_t * fds; /* File descriptor table */
status_t status; /* Process status */
sig_table_t signals; /* Signal table */ tree_node_t * tree_entry;
uint8_t finished; /* Status indicator */ struct regs * syscall_registers;
uint8_t started; struct regs * interrupt_registers;
uint8_t running; list_t * wait_queue;
struct regs * syscall_registers; /* Registers at interrupt */ list_t * shm_mappings;
list_t * wait_queue; list_t * node_waits;
list_t * shm_mappings; /* Shared memory chunk mappings */ list_t * signal_queue;
list_t * signal_queue; /* Queued signals */ char * signal_kstack;
thread_t signal_state;
char * signal_kstack; node_t sched_node;
node_t sched_node; node_t sleep_node;
node_t sleep_node; node_t * timed_sleep_node;
node_t * timed_sleep_node; node_t * timeout_node;
uint8_t is_tasklet;
volatile uint8_t sleep_interrupted;
list_t * node_waits;
int awoken_index;
node_t * timeout_node;
struct timeval start; struct timeval start;
uint8_t suspended; int awoken_index;
thread_t thread;
thread_t signal_state;
image_t image;
spin_lock_t sched_lock;
uintptr_t signals[NUMSIGNALS+1];
} process_t; } process_t;
typedef struct { typedef struct {
unsigned long end_tick; uint64_t end_tick;
unsigned long end_subtick; uint64_t end_subtick;
process_t * process; process_t * process;
int is_fswait; int is_fswait;
} sleeper_t; } sleeper_t;
struct ProcessorLocal {
/**
* @brief The running process on this core.
*
* The current_process is a pointer to the process struct for
* the process, userspace-thread, or kernel tasklet currently
* executing. Once the scheduler is active, this should always
* be set. If a core is not currently doing, its current_process
* should be the core's idle task.
*
* Because a process's data can be modified by nested interrupt
* contexts, we mark them as volatile to avoid making assumptions
* based on register-stored cached values.
*/
volatile process_t * current_process;
/**
* @brief Idle loop.
*
* This is a special kernel tasklet that sits in a loop
* waiting for an interrupt from a preemption source or hardware
* device. Its context should never be saved, it should never
* be added to a sleep queue, and it should be scheduled whenever
* there is nothing else to do.
*/
process_t * kernel_idle_task;
/**
* @brief Process this core was last scheduled to run.
*/
volatile process_t * previous_process;
int cpu_id;
union PML * current_pml;
#ifdef __x86_64__
int lapic_id;
/* Processor information loaded at startup. */
int cpu_model;
int cpu_family;
char cpu_model_name[48];
const char * cpu_manufacturer;
#endif
};
extern struct ProcessorLocal processor_local_data[32];
extern int processor_count;
/**
* @brief Core-local kernel data.
*
* x86-64: Marking this as __seg_gs makes it %gs-base-relative.
*/
static struct ProcessorLocal __seg_gs * const this_core = 0;
extern unsigned long process_append_fd(process_t * proc, fs_node_t * node);
extern long process_move_fd(process_t * proc, long src, long dest);
extern void initialize_process_tree(void); extern void initialize_process_tree(void);
extern process_t * spawn_process(volatile process_t * parent, int reuse_fds);
extern void debug_print_process_tree(void);
extern process_t * spawn_init(void);
extern process_t * spawn_kidle(void);
extern void set_process_environment(process_t * proc, page_directory_t * directory);
extern void make_process_ready(process_t * proc);
extern uint8_t process_available(void);
extern process_t * next_ready_process(void);
extern uint32_t process_append_fd(process_t * proc, fs_node_t * node);
extern process_t * process_from_pid(pid_t pid); extern process_t * process_from_pid(pid_t pid);
extern void delete_process(process_t * proc);
process_t * process_get_parent(process_t * process);
extern uint32_t process_move_fd(process_t * proc, int src, int dest);
extern int process_is_ready(process_t * proc);
extern void wakeup_sleepers(unsigned long seconds, unsigned long subseconds); extern void process_delete(process_t * proc);
extern void sleep_until(process_t * process, unsigned long seconds, unsigned long subseconds); extern void make_process_ready(volatile process_t * proc);
extern volatile process_t * next_ready_process(void);
extern volatile process_t * current_process; extern int wakeup_queue(list_t * queue);
extern process_t * kernel_idle_task; extern int wakeup_queue_interrupted(list_t * queue);
extern list_t * process_list; extern int sleep_on(list_t * queue);
extern int process_wait_nodes(process_t * process,fs_node_t * nodes[], int timeout);
extern int process_alert_node(process_t * process, void * value); extern int process_alert_node(process_t * process, void * value);
extern void sleep_until(process_t * process, unsigned long seconds, unsigned long subseconds);
extern void switch_task(uint8_t reschedule);
extern int process_wait_nodes(process_t * process,fs_node_t * nodes[], int timeout);
extern process_t * process_get_parent(process_t * process);
extern int process_is_ready(process_t * proc);
extern void wakeup_sleepers(unsigned long seconds, unsigned long subseconds);
extern void task_exit(int retval);
extern __attribute__((noreturn)) void switch_next(void);
extern int process_awaken_from_fswait(process_t * process, int index); extern int process_awaken_from_fswait(process_t * process, int index);
extern void process_release_directory(page_directory_t * dir);
typedef void (*tasklet_t) (void *, char *); extern process_t * spawn_worker_thread(void (*entrypoint)(void * argp), const char * name, void * argp);
extern int create_kernel_tasklet(tasklet_t tasklet, char * name, void * argp); extern pid_t fork(void);
extern pid_t clone(uintptr_t new_stack, uintptr_t thread_func, uintptr_t arg);
extern void release_directory(page_directory_t * dir);
extern void release_directory_for_exec(page_directory_t * dir);
extern void cleanup_process(process_t * proc, int retval);
extern void reap_process(process_t * proc);
extern int waitpid(int pid, int * status, int options); extern int waitpid(int pid, int * status, int options);
extern int exec(const char * path, int argc, char *const argv[], char *const env[], int interp_depth);
extern int is_valid_process(process_t * process); extern tree_t * process_tree; /* Parent->Children tree */
extern list_t * process_list; /* Flat storage */
extern list_t * process_queue; /* Ready queue */
extern list_t * sleep_queue;
extern void arch_enter_tasklet(void);
extern __attribute__((noreturn)) void arch_resume_user(void);
extern __attribute__((noreturn)) void arch_restore_context(volatile thread_t * buf);
extern __attribute__((returns_twice)) int arch_save_context(volatile thread_t * buf);
extern void arch_restore_floating(process_t * proc);
extern void arch_save_floating(process_t * proc);
extern void arch_set_kernel_stack(uintptr_t);
extern void arch_enter_user(uintptr_t entrypoint, int argc, char * argv[], char * envp[], uintptr_t stack);
__attribute__((noreturn))
extern void arch_enter_signal_handler(uintptr_t,int);
extern void arch_wakeup_others(void);

View File

@ -0,0 +1,12 @@
#pragma once
#include <kernel/vfs.h>
struct procfs_entry {
intptr_t id;
const char * name;
read_type_t func;
};
extern int procfs_install(struct procfs_entry * entry);
extern void procfs_initialize(void);

View File

@ -1,13 +1,14 @@
#pragma once #pragma once
#include <kernel/fs.h> #include <kernel/vfs.h>
#include <kernel/ringbuffer.h> #include <kernel/ringbuffer.h>
#include <sys/types.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/termios.h> #include <sys/termios.h>
typedef struct pty { typedef struct pty {
/* the PTY number */ /* the PTY number */
int name; intptr_t name;
/* Master and slave endpoints */ /* Master and slave endpoints */
fs_node_t * master; fs_node_t * master;

View File

@ -0,0 +1,7 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <kernel/vfs.h>
extern fs_node_t * ramdisk_mount(uintptr_t, size_t);

View File

@ -1,11 +1,16 @@
#pragma once #pragma once
#include <stddef.h>
#include <kernel/list.h>
#include <kernel/vfs.h>
#include <kernel/spinlock.h>
typedef struct { typedef struct {
unsigned char * buffer; unsigned char * buffer;
size_t write_ptr; size_t write_ptr;
size_t read_ptr; size_t read_ptr;
size_t size; size_t size;
volatile int lock[2]; spin_lock_t lock;
list_t * wait_queue_readers; list_t * wait_queue_readers;
list_t * wait_queue_writers; list_t * wait_queue_writers;
int internal_stop; int internal_stop;

View File

@ -2,7 +2,8 @@
*/ */
#pragma once #pragma once
#include <kernel/system.h> #include <stddef.h>
#include <stdint.h>
#include <kernel/types.h> #include <kernel/types.h>
#define SHM_PATH_SEPARATOR "." #define SHM_PATH_SEPARATOR "."
@ -13,9 +14,8 @@ struct shm_node;
typedef struct { typedef struct {
struct shm_node * parent; struct shm_node * parent;
volatile uint8_t lock; volatile uint8_t lock;
int32_t ref_count; ssize_t ref_count;
size_t num_frames;
uint32_t num_frames;
uintptr_t *frames; uintptr_t *frames;
} shm_chunk_t; } shm_chunk_t;
@ -27,8 +27,7 @@ typedef struct shm_node {
typedef struct { typedef struct {
shm_chunk_t * chunk; shm_chunk_t * chunk;
uint8_t volatile lock; uint8_t volatile lock;
size_t num_vaddrs;
uint32_t num_vaddrs;
uintptr_t *vaddrs; uintptr_t *vaddrs;
} shm_mapping_t; } shm_mapping_t;

View File

@ -1,11 +1,20 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#pragma once #pragma once
#include <kernel/types.h> #include <stdint.h>
void return_from_signal_handler(void); #include <sys/types.h>
void fix_signal_stacks(void); #include <kernel/arch/x86_64/regs.h>
#include <sys/signal_defs.h> typedef struct {
int signum;
uintptr_t handler;
struct regs registers_before;
} signal_t;
extern void fix_signal_stacks(void);
extern int send_signal(pid_t process, int signal, int force_root);
extern int group_send_signal(pid_t group, int signal, int force_root);
extern void handle_signal(process_t * proc, signal_t * sig);
__attribute__((noreturn))
extern void return_from_signal_handler(void);

View File

@ -0,0 +1,19 @@
#pragma once
typedef volatile struct {
volatile int latch[1];
int owner;
const char * func;
} spin_lock_t;
#define spin_init(lock) do { (lock).owner = 0; (lock).latch[0] = 0; (lock).func = NULL; } while (0)
#define DEBUG_LOCKS
#ifdef DEBUG_LOCKS
#define spin_lock(lock) do { while (__sync_lock_test_and_set((lock).latch, 0x01)); (lock).owner = this_core->cpu_id+1; (lock).func = __func__; } while (0)
#define spin_unlock(lock) do { (lock).func = NULL; (lock).owner = -1; __sync_lock_release((lock).latch); } while (0)
#else
#define spin_lock(lock) do { while (__sync_lock_test_and_set((lock).latch, 0x01)); } while(0)
#define spin_unlock(lock) __sync_lock_release((lock).latch);
#endif
#include <kernel/process.h>

View File

@ -1,14 +1,10 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#pragma once #pragma once
#include <kernel/types.h> #include <kernel/types.h>
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define MAX(A, B) ((A) > (B) ? (A) : (B))
extern void * memcpy(void * restrict dest, const void * restrict src, size_t n); extern void * memcpy(void * restrict dest, const void * restrict src, size_t n);
extern void * memset(void * dest, int c, size_t n); extern void * memset(void * dest, int c, size_t n);
extern unsigned short * memsetw(unsigned short * dest, unsigned short val, int count);
extern void * memchr(const void * src, int c, size_t n); extern void * memchr(const void * src, int c, size_t n);
extern void * memrchr(const void * m, int c, size_t n); extern void * memrchr(const void * m, int c, size_t n);
extern void * memmove(void *dest, const void *src, size_t n); extern void * memmove(void *dest, const void *src, size_t n);
@ -32,6 +28,11 @@ extern size_t strlen(const char * s);
extern int atoi(const char * s); extern int atoi(const char * s);
/* Non-standard broken strtok_r */
extern char * strtok_r(char * str, const char * delim, char ** saveptr); extern char * strtok_r(char * str, const char * delim, char ** saveptr);
extern void * __attribute__ ((malloc)) malloc(uintptr_t size);
extern void * __attribute__ ((malloc)) realloc(void * ptr, uintptr_t size);
extern void * __attribute__ ((malloc)) calloc(uintptr_t nmemb, uintptr_t size);
extern void * __attribute__ ((malloc)) valloc(uintptr_t size);
extern void free(void * ptr);
extern uint8_t startswith(const char * str, const char * accept);

View File

@ -0,0 +1,11 @@
#pragma once
extern char kernel_symbols_start[];
extern char kernel_symbols_end[];
typedef struct {
uintptr_t addr;
char name[];
} kernel_symbol_t;

View File

@ -0,0 +1,32 @@
#pragma once
#include <kernel/types.h>
#include <kernel/process.h>
#define FD_INRANGE(FD) \
((FD) < (int)this_core->current_process->fds->length && (FD) >= 0)
#define FD_ENTRY(FD) \
(this_core->current_process->fds->entries[(FD)])
#define FD_CHECK(FD) \
(FD_INRANGE(FD) && FD_ENTRY(FD))
#define FD_OFFSET(FD) \
(this_core->current_process->fds->offsets[(FD)])
#define FD_MODE(FD) \
(this_core->current_process->fds->modes[(FD)])
#define PTR_INRANGE(PTR) \
((uintptr_t)(PTR) > this_core->current_process->image.entry && ((uintptr_t)(PTR) < 0x8000000000000000))
#define PTR_VALIDATE(PTR) \
ptr_validate((void *)(PTR), __func__)
extern void ptr_validate(void * ptr, const char * syscall);
extern long arch_syscall_number(struct regs * r);
extern long arch_syscall_arg0(struct regs * r);
extern long arch_syscall_arg1(struct regs * r);
extern long arch_syscall_arg2(struct regs * r);
extern long arch_syscall_arg3(struct regs * r);
extern long arch_syscall_arg4(struct regs * r);
extern long arch_stack_pointer(struct regs * r);
extern long arch_user_ip(struct regs * r);
extern void arch_syscall_return(struct regs * r, long retval);

Some files were not shown because too many files have changed in this diff Show More