misaka: initial merge
This commit is contained in:
parent
229c4f9631
commit
b35f7ac8c9
40
.github/workflows/build.yml
vendored
40
.github/workflows/build.yml
vendored
@ -8,37 +8,19 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- name: Clone Kuroko
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: kuroko-lang/kuroko
|
||||
path: kuroko
|
||||
- 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
|
||||
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
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: image
|
||||
path: ./image.iso
|
||||
- name: Draft Release notes
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
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
|
||||
name: build
|
||||
path: |
|
||||
ramdisk.tar
|
||||
misaka-kernel
|
||||
|
96
.gitignore
vendored
96
.gitignore
vendored
@ -1,80 +1,28 @@
|
||||
*.so
|
||||
*.a
|
||||
*.aux
|
||||
*.idx
|
||||
*.ilg
|
||||
*.ind
|
||||
*.log
|
||||
*.o
|
||||
*.iso
|
||||
*.efi
|
||||
*.a
|
||||
*.out
|
||||
*.pdf
|
||||
*.so
|
||||
*.swp
|
||||
*.swn
|
||||
*.toc
|
||||
*.ko
|
||||
*.pcap
|
||||
.gdb_history
|
||||
/tags
|
||||
|
||||
/.make/*
|
||||
/base/bin/*
|
||||
/base/lib/kuroko
|
||||
/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
|
||||
/ramdisk.tar
|
||||
/ramdisk.igz
|
||||
/misaka-kernel.64
|
||||
/misaka-kernel
|
||||
/kernel/symbols.S
|
||||
/util/build
|
||||
/util/local
|
||||
/util/devtable
|
||||
/util/tmp-gcc
|
||||
/util/kuroko
|
||||
/kernel/symbols.S
|
||||
/base/usr/python
|
||||
/util/cross
|
||||
/base/bin/*
|
||||
/base/usr/bin/*
|
||||
/base/usr/lib/*
|
||||
/base/usr/share/python-demos
|
||||
|
||||
# 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
|
||||
/.make/
|
||||
|
8
.gitmodules
vendored
8
.gitmodules
vendored
@ -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"]
|
||||
path = kuroko
|
||||
url = git@github.com:kuroko-lang/kuroko
|
||||
url = ../../kuroko-lang/kuroko
|
||||
|
550
Makefile
550
Makefile
@ -1,170 +1,190 @@
|
||||
ifeq ($(TOOLCHAIN),)
|
||||
ifeq ($(shell util/check.sh),y)
|
||||
export PATH := $(shell util/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
|
||||
TOOLCHAIN=util
|
||||
BASE=base
|
||||
export PATH := $(shell $(TOOLCHAIN)/activate.sh)
|
||||
|
||||
# Prevents Make from removing intermediary files on failure
|
||||
.SECONDARY:
|
||||
include build/x86_64.mk
|
||||
|
||||
# Disable built-in rules
|
||||
.SUFFIXES:
|
||||
CC = ${TARGET}-gcc
|
||||
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
|
||||
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_ASMOBJS = $(filter-out kernel/symbols.o,$(patsubst %.S,%.o,$(wildcard kernel/arch/${ARCH}/*.S)))
|
||||
|
||||
##
|
||||
# C library objects from libc/ C sources (and setjmp, which is assembly)
|
||||
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
|
||||
KERNEL_SOURCES = $(wildcard kernel/*.c) $(wildcard kernel/*/*.c) $(wildcard kernel/${ARCH}/*/*.c)
|
||||
KERNEL_SOURCES += $(wildcard kernel/arch/${ARCH}/*.S)
|
||||
|
||||
##
|
||||
# APPS = C sources from apps/
|
||||
# APPS_X = binaries
|
||||
# APPS_Y = generated makefiles for binaries
|
||||
# APPS_SH = shell scripts to copy to base/bin/ and mark executable
|
||||
# APPS_SH_X = destinations for shell scripts
|
||||
APPS=$(patsubst apps/%.c,%,$(wildcard apps/*.c))
|
||||
APPS_X=$(foreach app,$(APPS),base/bin/$(app))
|
||||
MODULES = $(patsubst %.c,%.ko,$(wildcard modules/*.c))
|
||||
|
||||
# Configs you can override.
|
||||
SMP ?= 1
|
||||
RAM ?= 3G
|
||||
EXTRA_ARGS ?=
|
||||
|
||||
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_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_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_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)
|
||||
|
||||
SOURCE_FILES = $(wildcard kernel/*.c kernel/*/*.c kernel/*/*/*.c modules/*.c)
|
||||
SOURCE_FILES += $(wildcard apps/*.c linker/*.c libc/*.c libc/*/*.c lib/*.c)
|
||||
KRK_MODS = $(patsubst kuroko/src/modules/module_%.c,$(BASE)/lib/kuroko/%.so,$(wildcard kuroko/src/modules/module_*.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)
|
||||
ctags -f tags $(SOURCE_FILES) $(wildcard kuroko/src/*.c kuroko/src/*.h)
|
||||
CFLAGS= -O2 -std=gnu11 -I. -Iapps -fplan9-extensions -Wall -Wextra -Wno-unused-parameter
|
||||
|
||||
##
|
||||
# Files that must be present in the ramdisk (apps, libraries)
|
||||
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/*.c))
|
||||
LIBC_OBJS += $(patsubst %.c,%.o,$(wildcard libc/*/*.c))
|
||||
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})
|
||||
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
|
||||
CRTS = $(BASE)/lib/crt0.o $(BASE)/lib/crti.o $(BASE)/lib/crtn.o
|
||||
|
||||
KCFLAGS = -O2 -std=c99
|
||||
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
|
||||
LC = $(BASE)/lib/libc.so $(GCC_SHARED) $(LIBSTDCXX)
|
||||
|
||||
##
|
||||
# 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))
|
||||
.PHONY: all system clean run shell
|
||||
|
||||
##
|
||||
# Kernel objects from kernel/ assembly sources
|
||||
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)
|
||||
all: system
|
||||
system: misaka-kernel $(MODULES) ramdisk.igz
|
||||
|
||||
# Kernel
|
||||
%.ko: %.c
|
||||
${CC} -c ${KERNEL_CFLAGS} -o $@ $<
|
||||
|
||||
fatbase/kernel: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o ${EXTRALIB}
|
||||
${KCC} -T kernel/link.ld ${KCFLAGS} -nostdlib -o $@ ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o ${LGCC}
|
||||
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)
|
||||
python3 util/createramdisk.py
|
||||
|
||||
##
|
||||
# Symbol table for the kernel. Instead of relying on getting
|
||||
# the symbol table from our bootloader (eg. through ELF
|
||||
# headers provided via multiboot structure), we have a dedicated
|
||||
# object that build with all the symbols. This allows us to
|
||||
# build the kernel as a flat binary or load it with less-capable
|
||||
# multiboot loaders and still get symbols, which we need to
|
||||
# load kernel modules and link them properly.
|
||||
kernel/symbols.o: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} util/generate_symbols.krk ${EXTRALIB} | util/kuroko
|
||||
KRK_SRC = $(sort $(wildcard kuroko/src/*.c))
|
||||
$(BASE)/bin/kuroko: $(KRK_SRC) $(CRTS) | $(LC)
|
||||
$(CC) -O2 -g -o $@ -Wl,--export-dynamic -Ikuroko/src $(KRK_SRC) kuroko/src/vendor/rline.c
|
||||
|
||||
$(BASE)/lib/kuroko/%.so: kuroko/src/modules/module_%.c| dirs $(LC)
|
||||
$(CC) -O2 -shared -fPIC -Ikuroko/src -o $@ $<
|
||||
|
||||
$(BASE)/lib/libkuroko.so: $(KRK_SRC) | $(LC)
|
||||
$(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
|
||||
${KCC} -T kernel/link.ld ${KCFLAGS} -nostdlib -o .toaruos-kernel ${KERNEL_ASMOBJS} ${KERNEL_OBJS} ${LGCC}
|
||||
${KNM} .toaruos-kernel -g | util/kuroko util/generate_symbols.krk > kernel/symbols.S
|
||||
${KAS} ${KASFLAGS} 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
|
||||
${CC} -T kernel/arch/${ARCH}/link.ld ${KERNEL_CFLAGS} -o misaka-kernel.64 ${KERNEL_ASMOBJS} ${KERNEL_OBJS} -lgcc
|
||||
${NM} misaka-kernel.64 -g | kuroko util/gensym.krk > kernel/symbols.S
|
||||
${CC} -c kernel/symbols.S -o $@
|
||||
|
||||
kernel/%.o: kernel/%.S
|
||||
${KAS} ${ASFLAGS} $< -o $@
|
||||
echo ${PATH}
|
||||
${CC} -c $< -o $@
|
||||
|
||||
HEADERS = $(wildcard base/usr/include/kernel/*.h)
|
||||
|
||||
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:
|
||||
@mkdir -p $@
|
||||
libc/%.o: libc/%.c base/usr/include/syscall.h
|
||||
$(CC) -O2 -std=gnu11 -Wall -Wextra -Wno-unused-parameter -fPIC -c -o $@ $<
|
||||
|
||||
##
|
||||
# Modules need to be installed on the boot image
|
||||
MODULES = $(patsubst modules/%.c,fatbase/mod/%.ko,$(wildcard modules/*.c))
|
||||
.PHONY: libc
|
||||
libc: $(BASE)/lib/libc.a $(BASE)/lib/libc.so
|
||||
|
||||
fatbase/mod/%.ko: modules/%.c ${HEADERS} | fatbase/mod
|
||||
${KCC} -nostdlib ${KCFLAGS} -c -o $@ $<
|
||||
$(BASE)/lib/libc.a: ${LIBC_OBJS} $(CRTS)
|
||||
$(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 $@
|
||||
base/tmp:
|
||||
$(BASE)/tmp:
|
||||
mkdir -p $@
|
||||
base/proc:
|
||||
$(BASE)/proc:
|
||||
mkdir -p $@
|
||||
base/bin:
|
||||
$(BASE)/bin:
|
||||
mkdir -p $@
|
||||
base/lib:
|
||||
$(BASE)/lib:
|
||||
mkdir -p $@
|
||||
base/cdrom:
|
||||
$(BASE)/cdrom:
|
||||
mkdir -p $@
|
||||
base/var:
|
||||
$(BASE)/var:
|
||||
mkdir -p $@
|
||||
base/lib/kuroko:
|
||||
$(BASE)/lib/kuroko:
|
||||
mkdir -p $@
|
||||
$(BASE)/usr/lib:
|
||||
mkdir -p $@
|
||||
fatbase/efi/boot:
|
||||
mkdir -p $@
|
||||
@ -172,271 +192,49 @@ cdrom:
|
||||
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
|
||||
|
||||
# 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 $< > $@
|
||||
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
|
||||
|
||||
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
|
||||
-include ${APPS_Y}
|
||||
-include ${LIBS_Y}
|
||||
-include ${KRK_MODS_Y}
|
||||
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 $< $@
|
||||
chmod +x $@
|
||||
|
||||
base/bin/%.krk: apps/%.krk
|
||||
$(BASE)/bin/%.krk: apps/%.krk
|
||||
cp $< $@
|
||||
chmod +x $@
|
||||
|
||||
# Ramdisk
|
||||
fatbase/ramdisk.igz: ${RAMDISK_FILES} $(shell find base) Makefile util/createramdisk.py | dirs
|
||||
python3 util/createramdisk.py
|
||||
gzip -c fatbase/ramdisk.img > fatbase/ramdisk.igz
|
||||
rm fatbase/ramdisk.img
|
||||
.PHONY: libs
|
||||
libs: $(LIBS_X)
|
||||
|
||||
# CD image
|
||||
.PHONY: apps
|
||||
apps: $(APPS_X)
|
||||
|
||||
ifeq (,$(wildcard /usr/lib32/crt0-efi-ia32.o))
|
||||
$(error Missing GNU-EFI.)
|
||||
endif
|
||||
.PHONY: libstdcxx
|
||||
libstdcxx: $(LIBSTDCXX)
|
||||
|
||||
EFI_XORRISO=-eltorito-alt-boot -e fat.img -no-emul-boot -isohybrid-gpt-basdat
|
||||
EFI_BOOT=cdrom/fat.img
|
||||
EFI_UPDATE=util/update-extents.py
|
||||
util/local/${TARGET}/lib/libstdc++.so.6.0.28: | $(BASE)/lib/libm.so
|
||||
cd util/build/gcc && make all-target-libstdc++-v3 && make install-target-libstdc++-v3
|
||||
|
||||
image.iso: ${EFI_BOOT} cdrom/boot.sys fatbase/netinit ${MODULES} util/update-extents.py
|
||||
xorriso -as mkisofs -R -J -c bootcat \
|
||||
-b boot.sys -no-emul-boot -boot-load-size full \
|
||||
${EFI_XORRISO} \
|
||||
-o image.iso cdrom
|
||||
${EFI_UPDATE}
|
||||
|
||||
# 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
|
||||
SOURCE_FILES = $(wildcard kernel/*.c kernel/*/*.c kernel/*/*/*.c kernel/*/*/*/*.c)
|
||||
SOURCE_FILES += $(wildcard apps/*.c linker/*.c libc/*.c libc/*/*.c lib/*.c lib/kuroko/*.c)
|
||||
SOURCE_FILES += $(wildcard kuroko/src/*.c kuroko/src/*.h kuroko/src/*/*.c kuroko/src/*/*.h)
|
||||
SOURCE_FILES += $(wildcard $(BASE)/usr/include/*.h $(BASE)/usr/include/*/*.h $(BASE)/usr/include/*/*/*.h)
|
||||
tags: $(SOURCE_FILES)
|
||||
ctags -f tags $(SOURCE_FILES)
|
||||
|
@ -171,7 +171,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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->focused = wf->focused;
|
||||
redraw();
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include <toaru/list.h>
|
||||
#include <toaru/spinlock.h>
|
||||
|
||||
//#define _DEBUG_YUTANI
|
||||
#define _DEBUG_YUTANI
|
||||
#ifdef _DEBUG_YUTANI
|
||||
#include <toaru/trace.h>
|
||||
#define TRACE_APP_NAME "yutani"
|
||||
@ -175,7 +175,7 @@ static int next_wid(void) {
|
||||
return _next++;
|
||||
}
|
||||
|
||||
uint32_t yutani_current_time(yutani_globals_t * yg) {
|
||||
uint64_t yutani_current_time(yutani_globals_t * yg) {
|
||||
struct timeval t;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
uint32_t diff = now - start_time; /* Milliseconds */
|
||||
uint64_t now = yutani_current_time(yg);
|
||||
uint64_t diff = now - start_time; /* Milliseconds */
|
||||
|
||||
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.
|
||||
*/
|
||||
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));
|
||||
|
||||
win->wid = next_wid();
|
||||
win->owner = owner;
|
||||
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_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:
|
||||
{
|
||||
frame = yutani_animation_lengths[window->anim_mode] - frame;
|
||||
}
|
||||
} /* fallthrough */
|
||||
case YUTANI_EFFECT_SQUEEZE_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) {
|
||||
/* 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);
|
||||
@ -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.
|
||||
*/
|
||||
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) {
|
||||
node_t * n = list_find(client_list, w);
|
||||
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) {
|
||||
/* 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. */
|
||||
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.
|
||||
*/
|
||||
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) {
|
||||
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);
|
||||
@ -1335,7 +1335,7 @@ static void notify_subscribers(yutani_globals_t * yg) {
|
||||
yutani_msg_buildx_notify(response);
|
||||
list_t * remove = NULL;
|
||||
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 (!remove) {
|
||||
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.
|
||||
*/
|
||||
uint32_t key_code = ((ke->event.modifiers << 24) | (ke->event.keycode));
|
||||
if (hashmap_has(yg->key_binds, (void*)key_code)) {
|
||||
struct key_bind * bind = hashmap_get(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*)(uintptr_t)key_code);
|
||||
|
||||
yutani_msg_buildx_key_event_alloc(response);
|
||||
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
|
||||
* 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));
|
||||
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) {
|
||||
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->response = req->response;
|
||||
|
||||
hashmap_set(yg->key_binds, (void*)key_code, bind);
|
||||
hashmap_set(yg->key_binds, (void*)(uintptr_t)key_code, bind);
|
||||
} else {
|
||||
bind->owner = owner;
|
||||
bind->response = req->response;
|
||||
@ -2103,7 +2103,7 @@ int main(int argc, char * argv[]) {
|
||||
yg->width = yg->backend_ctx->width;
|
||||
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);
|
||||
|
||||
yg->backend_framebuffer = yg->backend_ctx->backbuffer;
|
||||
@ -2388,10 +2388,10 @@ int main(int argc, char * argv[]) {
|
||||
switch(m->type) {
|
||||
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);
|
||||
if (!client_list) {
|
||||
TRACE("Client is new: %x", p->source);
|
||||
TRACE("Client is new: %p", p->source);
|
||||
client_list = list_create();
|
||||
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:
|
||||
{
|
||||
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_msg_buildx_window_init_alloc(response);
|
||||
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:
|
||||
{
|
||||
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) {
|
||||
mark_window(yg, w);
|
||||
}
|
||||
@ -2429,7 +2429,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_FLIP_REGION:
|
||||
{
|
||||
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) {
|
||||
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.");
|
||||
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) {
|
||||
window_move(yg, win, wm->x, wm->y);
|
||||
} else {
|
||||
@ -2468,7 +2468,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_CLOSE:
|
||||
{
|
||||
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) {
|
||||
window_mark_for_close(yg, w);
|
||||
window_remove_from_client(yg, w);
|
||||
@ -2478,7 +2478,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_STACK:
|
||||
{
|
||||
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) {
|
||||
reorder_window(yg, w, ws->z);
|
||||
}
|
||||
@ -2487,7 +2487,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_RESIZE_REQUEST:
|
||||
{
|
||||
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) {
|
||||
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);
|
||||
@ -2498,7 +2498,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_RESIZE_OFFER:
|
||||
{
|
||||
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) {
|
||||
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);
|
||||
@ -2509,7 +2509,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_RESIZE_ACCEPT:
|
||||
{
|
||||
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) {
|
||||
uint32_t newbufid = server_window_resize(yg, w, wr->width, wr->height);
|
||||
yutani_msg_buildx_window_resize_alloc(response);
|
||||
@ -2521,7 +2521,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_RESIZE_DONE:
|
||||
{
|
||||
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) {
|
||||
server_window_resize_finish(yg, w, wr->width, wr->height);
|
||||
}
|
||||
@ -2542,7 +2542,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_SUBSCRIBE:
|
||||
{
|
||||
foreach(node, yg->window_subscribers) {
|
||||
if ((uint32_t)node->value == p->source) {
|
||||
if ((uintptr_t)node->value == p->source) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2560,7 +2560,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_ADVERTISE:
|
||||
{
|
||||
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->client_strings) free(w->client_strings);
|
||||
|
||||
@ -2587,7 +2587,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS:
|
||||
{
|
||||
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) {
|
||||
set_focused_window(yg, w);
|
||||
}
|
||||
@ -2602,7 +2602,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_DRAG_START:
|
||||
{
|
||||
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) {
|
||||
/* Start dragging */
|
||||
mouse_start_drag(yg, w);
|
||||
@ -2612,7 +2612,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_UPDATE_SHAPE:
|
||||
{
|
||||
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) {
|
||||
/* Set shape parameter */
|
||||
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:
|
||||
{
|
||||
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 (yg->focused_window == w) {
|
||||
int32_t x, y;
|
||||
@ -2643,7 +2643,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_SHOW_MOUSE:
|
||||
{
|
||||
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 (wa->show_mouse == -1) {
|
||||
w->show_mouse = w->default_mouse;
|
||||
@ -2662,7 +2662,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_RESIZE_START:
|
||||
{
|
||||
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 (yg->focused_window == w && !yg->resizing_window) {
|
||||
yg->resizing_window = w;
|
||||
@ -2675,7 +2675,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_SPECIAL_REQUEST:
|
||||
{
|
||||
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) {
|
||||
case YUTANI_SPECIAL_REQUEST_MAXIMIZE:
|
||||
if (w) {
|
||||
|
6
apps/demo.c
Normal file
6
apps/demo.c
Normal 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
4
apps/demo.krk
Normal 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
374
apps/dhcp_bitbanger.c
Normal 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;
|
||||
}
|
@ -38,7 +38,7 @@ static int print_human_readable_size(char * _out, size_t s) {
|
||||
}
|
||||
|
||||
static void print_size(uint64_t size, char * name) {
|
||||
char sizes[8];
|
||||
char sizes[30];
|
||||
if (!human) {
|
||||
sprintf(sizes, "%-7llu", size/1024LLU);
|
||||
} else {
|
||||
|
@ -289,7 +289,7 @@ int main(int argc, char * argv[]) {
|
||||
struct http_req my_req;
|
||||
parse_url(argv[optind], &my_req);
|
||||
|
||||
char file[100];
|
||||
char file[600];
|
||||
sprintf(file, "/dev/net/%s", my_req.domain);
|
||||
|
||||
if (fetch_options.calculate_output) {
|
||||
|
@ -85,7 +85,7 @@ static int nav_bar_cursor_x = 0;
|
||||
static int nav_bar_focused = 0;
|
||||
|
||||
/* 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 */
|
||||
static int _button_hilights[4] = {3,3,3,3};
|
||||
@ -435,7 +435,7 @@ static void update_status(void) {
|
||||
char tmp_size[50];
|
||||
if (selected_count == 0) {
|
||||
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) {
|
||||
print_human_readable_size(tmp_size, selected->size);
|
||||
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:
|
||||
{
|
||||
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) {
|
||||
win->focused = wf->focused;
|
||||
redraw_files();
|
||||
@ -1994,7 +1994,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_MOUSE_EVENT:
|
||||
{
|
||||
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;
|
||||
_decor_get_bounds(win, &bounds);
|
||||
|
||||
|
@ -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
|
@ -118,13 +118,13 @@ static void write_buffer(void) {
|
||||
|
||||
static int parser_open(struct markup_state * self, void * user, struct markup_tag * tag) {
|
||||
if (!strcmp(tag->name, "b")) {
|
||||
list_insert(state, (void*)current_state);
|
||||
list_insert(state, (void*)(uintptr_t)current_state);
|
||||
current_state |= (1 << 0);
|
||||
} else if (!strcmp(tag->name, "i")) {
|
||||
list_insert(state, (void*)current_state);
|
||||
list_insert(state, (void*)(uintptr_t)current_state);
|
||||
current_state |= (1 << 1);
|
||||
} else if (!strcmp(tag->name, "h1")) {
|
||||
list_insert(state, (void*)current_state);
|
||||
list_insert(state, (void*)(uintptr_t)current_state);
|
||||
current_state |= (1 << 2);
|
||||
} else if (!strcmp(tag->name, "br")) {
|
||||
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) {
|
||||
if (!strcmp(tag_name, "b")) {
|
||||
node_t * nstate = list_pop(state);
|
||||
current_state = (int)nstate->value;
|
||||
current_state = (int)(uintptr_t)nstate->value;
|
||||
free(nstate);
|
||||
} else if (!strcmp(tag_name, "i")) {
|
||||
node_t * nstate = list_pop(state);
|
||||
current_state = (int)nstate->value;
|
||||
current_state = (int)(uintptr_t)nstate->value;
|
||||
free(nstate);
|
||||
} else if (!strcmp(tag_name, "h1")) {
|
||||
write_buffer();
|
||||
cursor_x = BASE_X;
|
||||
cursor_y += current_line_height();
|
||||
node_t * nstate = list_pop(state);
|
||||
current_state = (int)nstate->value;
|
||||
current_state = (int)(uintptr_t)nstate->value;
|
||||
free(nstate);
|
||||
}
|
||||
return 0;
|
||||
@ -413,7 +413,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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) {
|
||||
win->focused = wf->focused;
|
||||
redraw_window();
|
||||
@ -431,7 +431,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_MOUSE_EVENT:
|
||||
{
|
||||
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) {
|
||||
int result = decor_handle_event(yctx, m);
|
||||
|
11
apps/ifconfig.c
Normal file
11
apps/ifconfig.c
Normal 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... */
|
||||
}
|
@ -190,7 +190,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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) {
|
||||
win->focused = wf->focused;
|
||||
decors();
|
||||
|
@ -24,19 +24,19 @@ int main(int argc, char * argv[]) {
|
||||
{
|
||||
Value * result = json_parse("-123");
|
||||
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");
|
||||
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");
|
||||
assert(result && result->type == JSON_TYPE_NUMBER);
|
||||
assert(fabs(result->number - (0.124) < 0.0001));
|
||||
assert(fabs(result->number - (0.124)) < 0.0001);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -299,7 +299,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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) {
|
||||
win->focused = wf->focused;
|
||||
decors();
|
||||
|
@ -31,7 +31,7 @@ typedef struct process {
|
||||
#define LINE_LEN 4096
|
||||
|
||||
p_t * build_entry(struct dirent * dent) {
|
||||
char tmp[256];
|
||||
char tmp[300];
|
||||
FILE * f;
|
||||
char line[LINE_LEN];
|
||||
|
||||
|
1166
apps/kuroko.c
1166
apps/kuroko.c
File diff suppressed because it is too large
Load Diff
12
apps/lspci.c
12
apps/lspci.c
@ -63,10 +63,16 @@ struct {
|
||||
{0x15ad, 0x0405, "SVGA II Adapter"},
|
||||
{0x15ad, 0x0790, "PCI bridge"},
|
||||
{0x15ad, 0x07a0, "PCI Express Root Port"},
|
||||
{0x8086, 0x100e, "Gigabit Ethernet Controller (e1000)"},
|
||||
{0x8086, 0x100f, "Gigabit Ethernet Controller (e1000)"},
|
||||
{0x8086, 0x1004, "82543GC 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, 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, 0x7010, "IDE Interface"},
|
||||
{0x8086, 0x7110, "PIIX4 ISA"},
|
||||
|
@ -217,7 +217,7 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
char * root_type = hashmap_get(cmdline,"root_type");
|
||||
if (!root_type) {
|
||||
root_type = "ext2";
|
||||
root_type = "tar";
|
||||
}
|
||||
|
||||
char tmp[1024];
|
||||
|
66
apps/misaka-test.c
Normal file
66
apps/misaka-test.c
Normal 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;
|
||||
}
|
@ -423,8 +423,8 @@ static int install_packages(int argc, char * argv[]) {
|
||||
}
|
||||
fprintf(stderr, "\nContinue? [Y/n] ");
|
||||
fflush(stderr);
|
||||
char resp[4];
|
||||
fgets(resp, 4, stdin);
|
||||
char resp[5];
|
||||
fgets(resp, 5, stdin);
|
||||
if (!(!strcmp(resp,"\n") || !strcmp(resp,"y\n") || !strcmp(resp,"Y\n") || !strcmp(resp,"yes\n"))) {
|
||||
fprintf(stderr, "Aborting.\n");
|
||||
return 1;
|
||||
|
@ -552,7 +552,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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) {
|
||||
win->focused = wf->focused;
|
||||
redraw_packages();
|
||||
@ -571,7 +571,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_MOUSE_EVENT:
|
||||
{
|
||||
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) {
|
||||
int result = decor_handle_event(yctx, m);
|
||||
|
@ -26,7 +26,7 @@ typedef struct process {
|
||||
#define LINE_LEN 4096
|
||||
|
||||
p_t * build_entry(struct dirent * dent) {
|
||||
char tmp[256];
|
||||
char tmp[300];
|
||||
FILE * f;
|
||||
char line[LINE_LEN];
|
||||
|
||||
|
@ -163,7 +163,7 @@ int main (int argc, char ** argv) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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) {
|
||||
win->focused = wf->focused;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ void update_stuff(void) {
|
||||
|
||||
if (colliding(&ball, &left)) {
|
||||
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;
|
||||
ball.vel_y = intersect * 8.0;
|
||||
@ -186,7 +186,7 @@ void update_stuff(void) {
|
||||
|
||||
if (colliding(&ball, &right)) {
|
||||
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);
|
||||
ball.vel_y = intersect * 3.0;
|
||||
|
@ -55,7 +55,7 @@ void print_username(int uid) {
|
||||
}
|
||||
|
||||
struct process * process_entry(struct dirent *dent) {
|
||||
char tmp[256];
|
||||
char tmp[300];
|
||||
FILE * f;
|
||||
char line[LINE_LEN];
|
||||
|
||||
|
@ -29,7 +29,7 @@ typedef struct process {
|
||||
#define LINE_LEN 4096
|
||||
|
||||
p_t * build_entry(struct dirent * dent) {
|
||||
char tmp[256];
|
||||
char tmp[300];
|
||||
FILE * f;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
@ -161,7 +161,7 @@ int main (int argc, char * argv[]) {
|
||||
if (proc->ppid == 0 && proc->pid == 1) {
|
||||
tree_set_root(procs, proc);
|
||||
} 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) {
|
||||
tree_node_insert_child(procs, parent, proc);
|
||||
}
|
||||
|
866
apps/readelf.c
866
apps/readelf.c
@ -1,256 +1,688 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2013-2018 K Lange
|
||||
/**
|
||||
* @file readelf.c
|
||||
* @brief Display information about a 64-bit Elf binary or object.
|
||||
*
|
||||
* readelf - Show information about ELF objects
|
||||
*
|
||||
* 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.
|
||||
* Implementation of a `readelf` utility.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <kernel/elf.h>
|
||||
|
||||
/**
|
||||
* Show usage for the readelf application.
|
||||
* @param argc Argument count (unused)
|
||||
* @param argv Arguments to binary
|
||||
*/
|
||||
void usage(int argc, char ** argv) {
|
||||
/* Show usage */
|
||||
printf("%s [filename]\n", argv[0]);
|
||||
printf("\tDisplays information on ELF binaries such as section names,\n");
|
||||
printf("\tlocations, sizes, and loading positions in memory.\n");
|
||||
exit(1);
|
||||
|
||||
static const char * elf_classToStr(unsigned char ei_class) {
|
||||
static char buf[64];
|
||||
switch (ei_class) {
|
||||
case ELFCLASS32: return "ELF32";
|
||||
case ELFCLASS64: return "ELF64";
|
||||
default:
|
||||
sprintf(buf, "unknown (%d)", ei_class);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Application entry point.
|
||||
* @returns 0 on sucess, 1 on failure
|
||||
*/
|
||||
int main(int argc, char ** argv) {
|
||||
/* Process arguments */
|
||||
if (argc < 2) usage(argc,argv);
|
||||
static const char * elf_dataToStr(unsigned char ei_data) {
|
||||
static char buf[64];
|
||||
switch (ei_data) {
|
||||
case ELFDATA2LSB: return "2's complement, little endian";
|
||||
case ELFDATA2MSB: return "2's complement, big endian";
|
||||
default:
|
||||
sprintf(buf, "unknown (%d)", ei_data);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
FILE * binary; /**< File pointer for requested executable */
|
||||
size_t binary_size; /**< Size of the file */
|
||||
char * binary_buf; /**< Buffer to store the binary in memory */
|
||||
Elf32_Header * header; /**< ELF header */
|
||||
char * string_table = NULL; /**< The section header string table */
|
||||
char * sym_string_table = NULL; /**< The symbol string table */
|
||||
static char * elf_versionToStr(unsigned char ei_version) {
|
||||
static char buf[64];
|
||||
switch (ei_version) {
|
||||
case 1: return "1 (current)";
|
||||
default:
|
||||
sprintf(buf, "unknown (%d)", ei_version);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
/* Open the requested binary */
|
||||
binary = fopen(argv[1], "r");
|
||||
static char * elf_osabiToStr(unsigned char ei_osabi) {
|
||||
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));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Jump to the end so we can get the size */
|
||||
fseek(binary, 0, SEEK_END);
|
||||
binary_size = ftell(binary);
|
||||
fseek(binary, 0, SEEK_SET);
|
||||
/**
|
||||
* Validate header.
|
||||
*/
|
||||
Elf64_Header header;
|
||||
fread(&header, sizeof(Elf64_Header), 1, f);
|
||||
|
||||
/* Some sanity checks */
|
||||
if (binary_size < 4 || binary_size > 0xFFFFFFF) {
|
||||
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");
|
||||
if (memcmp("\x7F" "ELF",&header,4)) {
|
||||
fprintf(stderr, "%s: %s: not an elf\n", argv[0], argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Let's print out some of the header information, shall we? */
|
||||
printf("\033[1mELF Header\033[0m\n");
|
||||
printf("ELF Header:\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 */
|
||||
printf("[Type %d] ", header->e_type);
|
||||
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;
|
||||
if (header.e_ident[EI_CLASS] != ELFCLASS64) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Machine Type */
|
||||
switch (header->e_machine) {
|
||||
case EM_386:
|
||||
printf("Intel x86\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown machine: %d\n", header->e_machine);
|
||||
break;
|
||||
/* Byte-order dependent from here on out... */
|
||||
printf(" Type: %s\n", elf_typeToStr(header.e_type));
|
||||
printf(" Machine: %s\n", elf_machineToStr(header.e_machine));
|
||||
printf(" Version: 0x%x\n", header.e_version);
|
||||
printf(" Entry point address: 0x%lx\n", header.e_entry);
|
||||
printf(" Start of program headers: %lu (bytes into file)\n", header.e_phoff);
|
||||
printf(" Start of section headers: %lu (bytes into file)\n", header.e_shoff);
|
||||
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(§ionHeader, 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) {
|
||||
printf("ELF version is 1, as it should be.\n");
|
||||
}
|
||||
/**
|
||||
* Program Headers
|
||||
*/
|
||||
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("Binary entry point in virtual memory is at 0x%x\n", (unsigned int)header->e_entry);
|
||||
printf(" %-14.14s 0x%016lx 0x%016lx 0x%016lx\n",
|
||||
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 */
|
||||
printf("Program header table is at +0x%x and one entry is 0x%x bytes.\n"
|
||||
"There are %d total program headers.\n",
|
||||
(unsigned int)header->e_phoff, (unsigned int)header->e_phentsize, (unsigned int)header->e_phnum);
|
||||
|
||||
/* Section header table offset */
|
||||
printf("Section header table is at +0x%x and one entry is 0x%x bytes.\n"
|
||||
"There are %d total section headers.\n",
|
||||
(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;
|
||||
if (programHeader.p_type == PT_INTERP) {
|
||||
/* Read interpreter string */
|
||||
char * tmp = malloc(programHeader.p_filesz);
|
||||
fseek(f, programHeader.p_offset, SEEK_SET);
|
||||
fread(tmp, programHeader.p_filesz, 1, f);
|
||||
printf(" [Requesting program interpreter: %.*s]\n",
|
||||
(int)programHeader.p_filesz, tmp);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
/* Grab the program header */
|
||||
Elf32_Phdr * phdr = (Elf32_Phdr *)((uintptr_t)binary_buf + (header->e_phoff + x));
|
||||
}
|
||||
|
||||
/* Print the header type */
|
||||
switch (phdr->p_type) {
|
||||
case PT_LOAD:
|
||||
printf("[Loadable Segment]\n");
|
||||
/* TODO Section to segment mapping? */
|
||||
|
||||
/**
|
||||
* 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(§ionHeader, 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;
|
||||
case PT_DYNAMIC:
|
||||
printf("[Dynamic Loading Information]\n");
|
||||
case SHT_RELA:
|
||||
{
|
||||
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;
|
||||
case PT_INTERP:
|
||||
printf("[Interpreter Path]\n");
|
||||
case SHT_SYMTAB:
|
||||
{
|
||||
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;
|
||||
default:
|
||||
printf("[Unused Segement]\n");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
export-cmd DESKTOP cat /var/run/.wallpaper.pid
|
||||
|
||||
if not empty? "$DESKTOP" then kill -SIGUSR2 $DESKTOP
|
@ -121,7 +121,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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->focused = wf->focused;
|
||||
decors();
|
||||
|
@ -52,7 +52,7 @@ int main(int argc, char * argv[]) {
|
||||
/* Send ioctl */
|
||||
if (init) {
|
||||
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) {
|
||||
perror("ioctl");
|
||||
return 1;
|
||||
|
@ -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
|
||||
|
@ -1109,6 +1109,7 @@ int shell_exec(char * buffer, size_t size, FILE * file, char ** out_buffer) {
|
||||
*out_buffer = ++p;
|
||||
goto _done;
|
||||
}
|
||||
goto _just_add;
|
||||
case '#':
|
||||
if (!quoted && !backtick) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
char home_path[512];
|
||||
char home_path[1200];
|
||||
sprintf(home_path, "/home/%s", username);
|
||||
if (chdir(home_path)) {
|
||||
goto cd_error;
|
||||
|
@ -208,7 +208,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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->focused = wf->focused;
|
||||
redraw();
|
||||
|
@ -25,7 +25,7 @@ int main(int argc, char ** argv) {
|
||||
unsigned int seconds = (unsigned int)time;
|
||||
unsigned int subsecs = (unsigned int)((time - (float)seconds) * 100);
|
||||
|
||||
ret = syscall_nanosleep(seconds, subsecs);
|
||||
ret = syscall_sleep(seconds, subsecs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -18,24 +18,11 @@
|
||||
|
||||
#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.
|
||||
*/
|
||||
static int framebuffer_fd = -1;
|
||||
static int width, height, depth;
|
||||
static long width, height, depth;
|
||||
static char * framebuffer;
|
||||
|
||||
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) {
|
||||
if (framebuffer_fd != -1) {
|
||||
int x = 20;
|
||||
int y = 20 + char_height * line;
|
||||
while (*c) {
|
||||
write_char(x, y, *c, FG_COLOR);
|
||||
c++;
|
||||
x += char_width;
|
||||
}
|
||||
while (x < width - char_width) {
|
||||
write_char(x, y, ' ', FG_COLOR);
|
||||
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++;
|
||||
}
|
||||
if (framebuffer_fd < 0) return;
|
||||
int x = 20;
|
||||
int y = 20 + char_height * line;
|
||||
while (*c) {
|
||||
write_char(x, y, *c, FG_COLOR);
|
||||
c++;
|
||||
x += char_width;
|
||||
}
|
||||
while (x < width - char_width) {
|
||||
write_char(x, y, ' ', FG_COLOR);
|
||||
x += char_width;
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_screen(void) {
|
||||
if (framebuffer_fd != -1) {
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
set_point(x,y,BG_COLOR);
|
||||
}
|
||||
}
|
||||
if (framebuffer_fd < 0) return;
|
||||
|
||||
} else {
|
||||
for (int y = 0; y < 24; ++y) {
|
||||
for (int x = 0; x < 80; ++x) {
|
||||
placech(' ', x, y, 0); /* Clear */
|
||||
}
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
set_point(x,y,BG_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void check_framebuffer(void) {
|
||||
int tmpfd = open("/proc/framebuffer", O_RDONLY);
|
||||
if (tmpfd > 0) {
|
||||
framebuffer_fd = open("/dev/fb0", O_RDONLY);
|
||||
ioctl(framebuffer_fd, IO_VID_WIDTH, &width);
|
||||
ioctl(framebuffer_fd, IO_VID_HEIGHT, &height);
|
||||
ioctl(framebuffer_fd, IO_VID_DEPTH, &depth);
|
||||
ioctl(framebuffer_fd, IO_VID_ADDR, &framebuffer);
|
||||
ioctl(framebuffer_fd, IO_VID_SIGNAL, NULL);
|
||||
} else {
|
||||
framebuffer_fd = -1;
|
||||
}
|
||||
framebuffer_fd = open("/dev/fb0", O_RDONLY);
|
||||
if (framebuffer_fd < 0) return;
|
||||
|
||||
ioctl(framebuffer_fd, IO_VID_WIDTH, &width);
|
||||
ioctl(framebuffer_fd, IO_VID_HEIGHT, &height);
|
||||
ioctl(framebuffer_fd, IO_VID_DEPTH, &depth);
|
||||
ioctl(framebuffer_fd, IO_VID_ADDR, &framebuffer);
|
||||
ioctl(framebuffer_fd, IO_VID_SIGNAL, NULL);
|
||||
}
|
||||
|
||||
static FILE * pex_endpoint = NULL;
|
||||
@ -139,6 +103,7 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
if (!fork()) {
|
||||
check_framebuffer();
|
||||
//printf("splash daemon is running, framebuffer (%ldx%ld) is at %p\n", width, height, framebuffer);
|
||||
clear_screen();
|
||||
update_message("ToaruOS is starting up...", 0);
|
||||
|
||||
|
16
apps/tar.c
16
apps/tar.c
@ -299,13 +299,13 @@ int main(int argc, char * argv[]) {
|
||||
if (verbose) {
|
||||
fprintf(stdout, "%.155s%.100s\n", file->prefix, file->filename);
|
||||
}
|
||||
char name[1024] = {0};
|
||||
char name[1025] = {0};
|
||||
if (last_was_long) {
|
||||
strncat(name, tmpname, 1023);
|
||||
strncat(name, tmpname, 1024);
|
||||
last_was_long = 0;
|
||||
} else {
|
||||
strncat(name, file->prefix, 155);
|
||||
strncat(name, file->filename, 100);
|
||||
strncat(name, file->prefix, 167);
|
||||
strncat(name, file->filename, 512);
|
||||
}
|
||||
|
||||
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') {
|
||||
if (!to_stdout && (!only_matches || matches_files(argc,argv,optind,name))) {
|
||||
char tmp[101] = {0};
|
||||
strncat(tmp, file->link, 100);
|
||||
char tmp[356] = {0};
|
||||
strncat(tmp, file->link, 355);
|
||||
FILE * mf = fopen(name,"w");
|
||||
if (!mf) {
|
||||
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));
|
||||
} else if (file->type[0] == '2') {
|
||||
if (!to_stdout && (!only_matches || matches_files(argc,argv,optind,name))) {
|
||||
char tmp[101] = {0};
|
||||
strncat(tmp, file->link, 100);
|
||||
char tmp[356] = {0};
|
||||
strncat(tmp, file->link, 355);
|
||||
if (symlink(tmp, name) < 0) {
|
||||
fprintf(stderr, "%s: %s: %s: %s: %s\n", argv[0], fname, name, tmp, strerror(errno));
|
||||
}
|
||||
|
Binary file not shown.
@ -1302,7 +1302,7 @@ int main(int argc, char ** argv) {
|
||||
/* Prune any keyboard input we got before the terminal started. */
|
||||
struct stat 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];
|
||||
read(kfd, tmp, 1);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
/* 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 xx = 0; xx < char_width; ++xx) {
|
||||
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) {
|
||||
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) {
|
||||
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));
|
||||
memcpy(cell_data, data, char_width * char_height * sizeof(uint32_t));
|
||||
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 */
|
||||
@ -1945,7 +1949,7 @@ static void * handle_incoming(void) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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) {
|
||||
win->focused = wf->focused;
|
||||
render_decors();
|
||||
@ -2461,8 +2465,8 @@ int main(int argc, char ** argv) {
|
||||
|
||||
if (res[1]) {
|
||||
/* Read from PTY */
|
||||
int r = read(fd_master, buf, 4096);
|
||||
for (int i = 0; i < r; ++i) {
|
||||
ssize_t r = read(fd_master, buf, 4096);
|
||||
for (ssize_t i = 0; i < r; ++i) {
|
||||
ansi_put(ansi_state, buf[i]);
|
||||
}
|
||||
display_flip();
|
||||
|
6
apps/test-cxx.c++
Normal file
6
apps/test-cxx.c++
Normal file
@ -0,0 +1,6 @@
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
std::cout << "Hello, world!";
|
||||
return 0;
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
#include <pthread.h>
|
||||
#include <sys/sysfunc.h>
|
||||
|
||||
__thread int myvalue;
|
||||
__thread volatile int myvalue;
|
||||
|
||||
void * getaddressinthread(void * _unused) {
|
||||
fprintf(stderr, "in thread before:\n");
|
||||
|
@ -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"
|
@ -325,6 +325,9 @@ int main(int argc, char * argv[]) {
|
||||
decor_get_bounds(NULL, &bounds);
|
||||
|
||||
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_sprite(&logo, "/usr/share/logo_login.png");
|
||||
@ -335,9 +338,6 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
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");
|
||||
|
||||
ctx = init_graphics_yutani_double_buffer(window);
|
||||
@ -371,7 +371,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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) {
|
||||
yutani_focus_window(yctx, window->wid);
|
||||
} else if (win) {
|
||||
|
@ -327,7 +327,7 @@ int main(int argc, char * argv[]) {
|
||||
case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
|
||||
{
|
||||
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->focused = wf->focused;
|
||||
redraw();
|
||||
|
@ -11,6 +11,7 @@
|
||||
typedef struct JSON_Value Value;
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
return 1;
|
||||
|
||||
Value * config = json_parse_file("/etc/weather.json");
|
||||
if (!config) {
|
||||
|
@ -2,4 +2,4 @@ remote_order=local,remote
|
||||
|
||||
[remotes]
|
||||
local=/cdrom/extra
|
||||
remote=http://toaruos.org/msk/1.10.x
|
||||
remote=http://toaruos.org/msk/2.0.x
|
||||
|
@ -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"
|
@ -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
|
@ -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
|
@ -1,6 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
fprintf(stdout, "Hello, %s!\n", "world");
|
||||
return 0;
|
||||
}
|
@ -32,6 +32,6 @@ extern int toupper(int c);
|
||||
#define _X 0100
|
||||
#define _B 0200
|
||||
|
||||
extern char _ctype_[256];
|
||||
extern unsigned char _ctype_[256];
|
||||
|
||||
_End_C_Header
|
||||
|
@ -135,7 +135,7 @@ _Begin_C_Header
|
||||
|
||||
#ifndef _KERNEL_
|
||||
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
|
||||
|
||||
_End_C_Header
|
||||
|
@ -5,12 +5,23 @@
|
||||
#include <stddef.h>
|
||||
|
||||
_Begin_C_Header
|
||||
#define PRIi8 "i"
|
||||
#define PRIi8 "i"
|
||||
#define PRIi16 "i"
|
||||
#define PRIi32 "i"
|
||||
#define PRIi64 "lli"
|
||||
#define PRIi64 "li"
|
||||
|
||||
#define PRIx64 "llx"
|
||||
#define PRIu64 "llu"
|
||||
#define PRId64 "lld"
|
||||
#define PRIx8 "x"
|
||||
#define PRIx16 "x"
|
||||
#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
|
||||
|
53
base/usr/include/kernel/arch/x86_64/acpi.h
Normal file
53
base/usr/include/kernel/arch/x86_64/acpi.h
Normal 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;
|
||||
}
|
||||
|
5
base/usr/include/kernel/arch/x86_64/cmos.h
Normal file
5
base/usr/include/kernel/arch/x86_64/cmos.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/types.h>
|
||||
|
||||
uint32_t read_cmos(void);
|
87
base/usr/include/kernel/arch/x86_64/irq.h
Normal file
87
base/usr/include/kernel/arch/x86_64/irq.h
Normal 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 *);
|
41
base/usr/include/kernel/arch/x86_64/mmu.h
Normal file
41
base/usr/include/kernel/arch/x86_64/mmu.h
Normal 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);
|
23
base/usr/include/kernel/arch/x86_64/pml.h
Normal file
23
base/usr/include/kernel/arch/x86_64/pml.h
Normal 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;
|
||||
};
|
||||
|
12
base/usr/include/kernel/arch/x86_64/ports.h
Normal file
12
base/usr/include/kernel/arch/x86_64/ports.h
Normal 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);
|
||||
|
18
base/usr/include/kernel/arch/x86_64/regs.h
Normal file
18
base/usr/include/kernel/arch/x86_64/regs.h
Normal 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;
|
||||
};
|
@ -1,9 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
int args_present(char * karg);
|
||||
char * args_value(char * karg);
|
||||
void args_parse(char * _arg);
|
||||
|
||||
void early_stage_args(void);
|
||||
void late_stage_args(void);
|
||||
int args_present(const char * karg);
|
||||
char * args_value(const char * karg);
|
||||
void args_parse(const char * arg);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Different bits of our build environment
|
||||
* require different header files for definitions
|
||||
/**
|
||||
* @typedef Elf64_Addr
|
||||
* @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_
|
||||
# include <kernel/types.h>
|
||||
#else
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef uint16_t Elf64_Half;
|
||||
typedef uint32_t Elf64_Word;
|
||||
typedef int32_t Elf64_Sword;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
typedef int64_t Elf64_Sxword;
|
||||
|
||||
/*
|
||||
* Unless otherwise stated, the definitions herein
|
||||
* are sourced from the Portable Formats Specification,
|
||||
* version 1.1 - ELF: Executable and Linkable Format
|
||||
*/
|
||||
|
||||
/*
|
||||
* ELF Magic Signature
|
||||
/**
|
||||
* Values for e_ident[EI_MAGn]
|
||||
*/
|
||||
#define ELFMAG0 0x7f
|
||||
#define ELFMAG1 'E'
|
||||
#define ELFMAG2 'L'
|
||||
#define ELFMAG3 'F'
|
||||
#define EI_NIDENT 16
|
||||
|
||||
/*
|
||||
* ELF Datatypes
|
||||
/**
|
||||
* Values for e_ident[EI_CLASS]
|
||||
*/
|
||||
typedef uint32_t Elf32_Word;
|
||||
typedef uint32_t Elf32_Addr;
|
||||
typedef uint32_t Elf32_Off;
|
||||
typedef uint32_t Elf32_Sword;
|
||||
typedef uint16_t Elf32_Half;
|
||||
#define ELFCLASS32 1
|
||||
#define ELFCLASS64 2
|
||||
|
||||
/*
|
||||
* ELF Header
|
||||
/**
|
||||
* Values for e_ident[EI_DATA]
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
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;
|
||||
#define ELFDATA2LSB 1
|
||||
#define ELFDATA2MSB 2
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
#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
|
||||
/**
|
||||
* e_ident fields
|
||||
*/
|
||||
#define EM_NONE 0
|
||||
#define EM_386 3
|
||||
#define EI_MAG0 0
|
||||
#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 EV_CURRENT 1
|
||||
#define EM_X86_64 62
|
||||
|
||||
/** Program Header */
|
||||
typedef struct {
|
||||
Elf32_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
Elf32_Word p_flags;
|
||||
Elf32_Word p_align;
|
||||
} Elf32_Phdr;
|
||||
/**
|
||||
* @brief Elf object file header.
|
||||
*/
|
||||
typedef struct Elf64_Header {
|
||||
uint8_t e_ident[EI_NIDENT]; /**< @brief Identifies the layout of the rest of the file. */
|
||||
Elf64_Half e_type; /**< @brief What kind of file this is, eg. object or executable... */
|
||||
Elf64_Half e_machine; /**< @brief The architecture this file is for. */
|
||||
Elf64_Word e_version; /**< @brief The version of the standard this file confirms to. */
|
||||
Elf64_Addr e_entry; /**< @brief The entry point of an executable. */
|
||||
Elf64_Off e_phoff; /**< @brief The offset of the program headers. */
|
||||
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 */
|
||||
#define PT_LOAD 1 /* Loadable segment */
|
||||
#define PT_DYNAMIC 2 /* Dynamic linking information */
|
||||
#define PT_INTERP 3 /* Interpreter (null-terminated string, pathname) */
|
||||
#define PT_NOTE 4 /* Auxillary information */
|
||||
#define PT_SHLIB 5 /* Reserved. */
|
||||
#define PT_PHDR 6 /* Oh, it's me. Hello! Back-reference to the header table itself */
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7FFFFFFF
|
||||
/**
|
||||
* Special section indices
|
||||
*/
|
||||
#define SHN_UNDEF 0
|
||||
#define SHN_LOPROC 0xFF00
|
||||
#define SHN_HIPROC 0xFF1F
|
||||
#define SHN_LOOS 0xFF20
|
||||
#define SHN_HIOS 0xFF3F
|
||||
#define SHN_ABS 0xFFF1
|
||||
#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 {
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
} Elf32_Shdr;
|
||||
/**
|
||||
* Values for sh_flags
|
||||
*/
|
||||
#define SHF_WRITE 0x00000001
|
||||
#define SHF_ALLOC 0x00000002
|
||||
#define SHF_EXECINSTR 0x00000004
|
||||
#define SHF_MASKOS 0x0F000000
|
||||
#define SHF_MASKPROC 0xF0000000
|
||||
/* From the SysV x86-64 ABI */
|
||||
#define SHF_X86_64_LARGE 0x10000000
|
||||
#define SHF_X86_64_UNWIND 0x70000001
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
uintptr_t ptr;
|
||||
} Elf32_auxv;
|
||||
typedef struct Elf64_Shdr {
|
||||
Elf64_Word sh_name;
|
||||
Elf64_Word sh_type;
|
||||
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;
|
||||
Elf32_Addr st_value;
|
||||
Elf32_Word st_size;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf32_Half st_shndx;
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct {
|
||||
Elf32_Addr r_offset;
|
||||
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
|
||||
/**
|
||||
* Binding types.
|
||||
* Contained in the high four bits of @p st_info
|
||||
*/
|
||||
#define STB_LOCAL 0 /**< @brief Not visible outside the object file. */
|
||||
#define STB_GLOBAL 1 /**< @brief Global symbol, visible to all object files. */
|
||||
#define STB_WEAK 2 /**< @brief Global scope, but with lower precedence than global symbols. */
|
||||
#define STB_LOOS 10
|
||||
#define STB_HIOS 12
|
||||
#define STB_LOPROC 13
|
||||
#define STB_HIPROC 15
|
||||
|
||||
/**
|
||||
* 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_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;
|
||||
|
||||
|
||||
|
@ -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 *);
|
||||
|
22
base/usr/include/kernel/generic.h
Normal file
22
base/usr/include/kernel/generic.h
Normal 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);
|
16
base/usr/include/kernel/gzip.h
Normal file
16
base/usr/include/kernel/gzip.h
Normal 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;
|
42
base/usr/include/kernel/hashmap.h
Normal file
42
base/usr/include/kernel/hashmap.h
Normal 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);
|
||||
|
@ -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;
|
||||
|
50
base/usr/include/kernel/list.h
Normal file
50
base/usr/include/kernel/list.h
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
14
base/usr/include/kernel/misc.h
Normal file
14
base/usr/include/kernel/misc.h
Normal 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);
|
2
base/usr/include/kernel/mmu.h
Normal file
2
base/usr/include/kernel/mmu.h
Normal file
@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
#include <kernel/arch/x86_64/mmu.h>
|
@ -1,6 +1,8 @@
|
||||
#ifndef KERNEL_MOD_NET_H
|
||||
#define KERNEL_MOD_NET_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t* (*get_mac_func)(void);
|
||||
typedef struct ethernet_packet* (*get_packet_func)(void);
|
||||
typedef void (*send_packet_func)(uint8_t*, size_t);
|
||||
|
@ -4,9 +4,8 @@
|
||||
/* The format isn't really used for anything right now */
|
||||
#define SND_FORMAT_L16SLE 0 /* Linear 16-bit signed little endian */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <kernel/mod/sound.h>
|
||||
#include <kernel/logging.h>
|
||||
#include <kernel/system.h>
|
||||
|
||||
#define SND_KNOB_VENDOR 1024
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
LEFT_CLICK = 0x01,
|
||||
RIGHT_CLICK = 0x02,
|
||||
|
@ -1,8 +1,6 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <kernel/system.h>
|
||||
#include <kernel/types.h>
|
||||
|
||||
#define MULTIBOOT_MAGIC 0x1BADB002
|
||||
#define MULTIBOOT_EAX_MAGIC 0x2BADB002
|
||||
@ -13,7 +11,7 @@
|
||||
#define MULTIBOOT_FLAG_AOUT 0x010
|
||||
#define MULTIBOOT_FLAG_ELF 0x020
|
||||
#define MULTIBOOT_FLAG_MMAP 0x040
|
||||
#define MULTIBOOT_FLAG_DRIVE 0x080
|
||||
#define MULTIBOOT_FLAG_DRIVER 0x080
|
||||
#define MULTIBOOT_FLAG_CONFIG 0x100
|
||||
#define MULTIBOOT_FLAG_LOADER 0x200
|
||||
#define MULTIBOOT_FLAG_APM 0x400
|
||||
@ -22,37 +20,44 @@
|
||||
|
||||
struct multiboot
|
||||
{
|
||||
uintptr_t flags;
|
||||
uintptr_t mem_lower;
|
||||
uintptr_t mem_upper;
|
||||
uintptr_t boot_device;
|
||||
uintptr_t cmdline;
|
||||
uintptr_t mods_count;
|
||||
uintptr_t mods_addr;
|
||||
uintptr_t num;
|
||||
uintptr_t size;
|
||||
uintptr_t addr;
|
||||
uintptr_t shndx;
|
||||
uintptr_t mmap_length;
|
||||
uintptr_t mmap_addr;
|
||||
uintptr_t drives_length;
|
||||
uintptr_t drives_addr;
|
||||
uintptr_t config_table;
|
||||
uintptr_t boot_loader_name;
|
||||
uintptr_t apm_table;
|
||||
uintptr_t vbe_control_info;
|
||||
uintptr_t vbe_mode_info;
|
||||
uintptr_t vbe_mode;
|
||||
uintptr_t vbe_interface_seg;
|
||||
uintptr_t vbe_interface_off;
|
||||
uintptr_t vbe_interface_len;
|
||||
uintptr_t framebuffer_addr;
|
||||
uintptr_t framebuffer_pitch;
|
||||
uintptr_t framebuffer_width;
|
||||
uintptr_t framebuffer_height;
|
||||
uint8_t framebuffer_bpp;
|
||||
uint8_t framebuffer_type;
|
||||
/* Palette stuff goes here but we don't use it */
|
||||
uint32_t flags;
|
||||
uint32_t mem_lower;
|
||||
uint32_t mem_upper;
|
||||
uint32_t boot_device;
|
||||
uint32_t cmdline;
|
||||
uint32_t mods_count;
|
||||
uint32_t mods_addr;
|
||||
|
||||
uint32_t num;
|
||||
uint32_t size;
|
||||
uint32_t addr;
|
||||
uint32_t shndx;
|
||||
|
||||
uint32_t mmap_length;
|
||||
uint32_t mmap_addr;
|
||||
|
||||
uint32_t drives_length;
|
||||
uint32_t drives_addr;
|
||||
|
||||
uint32_t config_table;
|
||||
|
||||
uint32_t boot_loader_name;
|
||||
|
||||
uint32_t apm_table;
|
||||
|
||||
uint32_t vbe_control_info;
|
||||
uint32_t vbe_mode_info;
|
||||
uint16_t vbe_mode;
|
||||
uint16_t vbe_interface_seg;
|
||||
uint16_t vbe_interface_off;
|
||||
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));
|
||||
|
||||
typedef struct {
|
||||
@ -81,10 +86,10 @@ typedef struct {
|
||||
} __attribute__ ((packed)) vbe_info_t;
|
||||
|
||||
typedef struct {
|
||||
uintptr_t mod_start;
|
||||
uintptr_t mod_end;
|
||||
uintptr_t cmdline;
|
||||
uintptr_t reserved;
|
||||
uint32_t mod_start;
|
||||
uint32_t mod_end;
|
||||
uint32_t cmdline;
|
||||
uint32_t reserved;
|
||||
} __attribute__ ((packed)) mboot_mod_t;
|
||||
|
||||
typedef struct {
|
||||
@ -94,8 +99,3 @@ typedef struct {
|
||||
uint32_t type;
|
||||
} __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;
|
||||
|
||||
|
102
base/usr/include/kernel/net/e1000.h
Normal file
102
base/usr/include/kernel/net/e1000.h
Normal 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));
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PCI_VENDOR_ID 0x00 // 2
|
||||
#define PCI_DEVICE_ID 0x02 // 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);
|
||||
void pci_write_field(uint32_t device, int field, int size, uint32_t value);
|
||||
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_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(pci_func_t f, int type, void * extra);
|
||||
void pci_remap(void);
|
||||
int pci_get_interrupt(uint32_t device);
|
||||
|
||||
|
@ -5,7 +5,10 @@
|
||||
|
||||
#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 {
|
||||
uint8_t * buffer;
|
||||
@ -13,12 +16,16 @@ typedef struct _pipe_device {
|
||||
size_t read_ptr;
|
||||
size_t size;
|
||||
size_t refcount;
|
||||
volatile int lock_read[2];
|
||||
volatile int lock_write[2];
|
||||
list_t * wait_queue_readers;
|
||||
list_t * wait_queue_writers;
|
||||
int dead;
|
||||
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;
|
||||
|
||||
fs_node_t * make_pipe(size_t size);
|
||||
|
@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <va_list.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, ...);
|
||||
#include <kernel/types.h>
|
||||
|
||||
__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, ...);
|
||||
|
@ -1,162 +1,220 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kernel/signal.h>
|
||||
#include <kernel/task.h>
|
||||
#include <stdint.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 unsigned int user_t;
|
||||
typedef unsigned int status_t;
|
||||
typedef struct {
|
||||
uintptr_t sp; /* 0 */
|
||||
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 {
|
||||
uintptr_t esp; /* Stack Pointer */
|
||||
uintptr_t ebp; /* Base Pointer */
|
||||
uintptr_t eip; /* Instruction Pointer */
|
||||
|
||||
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;
|
||||
|
||||
kthread_context_t context;
|
||||
uint8_t fp_regs[512];
|
||||
page_directory_t * page_directory;
|
||||
} thread_t;
|
||||
|
||||
/* Portable image struct */
|
||||
typedef struct image {
|
||||
size_t size; /* Image size */
|
||||
uintptr_t entry; /* Binary entry point */
|
||||
uintptr_t heap; /* Heap pointer */
|
||||
uintptr_t heap_actual; /* Actual heap location */
|
||||
uintptr_t stack; /* Process kernel stack */
|
||||
uintptr_t user_stack; /* User stack */
|
||||
uintptr_t start;
|
||||
uintptr_t entry;
|
||||
uintptr_t heap;
|
||||
uintptr_t stack;
|
||||
uintptr_t shm_heap;
|
||||
volatile int lock[2];
|
||||
spin_lock_t lock;
|
||||
} image_t;
|
||||
|
||||
/* Resizable descriptor table */
|
||||
typedef struct descriptor_table {
|
||||
typedef struct file_descriptors {
|
||||
fs_node_t ** entries;
|
||||
uint64_t * offsets;
|
||||
int * modes;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
size_t refs;
|
||||
uint64_t * offsets;
|
||||
int * modes;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
size_t refs;
|
||||
spin_lock_t lock;
|
||||
} fd_table_t;
|
||||
|
||||
/* XXX */
|
||||
#define SIG_COUNT 10
|
||||
#define PROC_FLAG_IS_TASKLET 0x01
|
||||
#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 {
|
||||
pid_t id; /* Process ID (pid) */
|
||||
char * name; /* Process Name */
|
||||
char * description; /* Process description */
|
||||
user_t user; /* Effective user */
|
||||
user_t real_user; /* Real user ID */
|
||||
int mask; /* Umask */
|
||||
pid_t id; /* PID */
|
||||
pid_t group; /* thread group */
|
||||
pid_t job; /* tty job */
|
||||
pid_t session; /* tty session */
|
||||
int status; /* status code */
|
||||
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 */
|
||||
pid_t job; /* Process job group */
|
||||
pid_t session; /* Session group */
|
||||
char * name;
|
||||
char * description;
|
||||
char ** cmdline;
|
||||
|
||||
thread_t thread; /* Associated task information */
|
||||
tree_node_t * tree_entry; /* Process Tree Entry */
|
||||
image_t image; /* Binary image information */
|
||||
fs_node_t * wd_node; /* Working directory VFS node */
|
||||
char * wd_name; /* Working directory path name */
|
||||
char * wd_name;
|
||||
fs_node_t * wd_node;
|
||||
fd_table_t * fds; /* File descriptor table */
|
||||
status_t status; /* Process status */
|
||||
sig_table_t signals; /* Signal table */
|
||||
uint8_t finished; /* Status indicator */
|
||||
uint8_t started;
|
||||
uint8_t running;
|
||||
struct regs * syscall_registers; /* Registers at interrupt */
|
||||
list_t * wait_queue;
|
||||
list_t * shm_mappings; /* Shared memory chunk mappings */
|
||||
list_t * signal_queue; /* Queued signals */
|
||||
thread_t signal_state;
|
||||
char * signal_kstack;
|
||||
node_t sched_node;
|
||||
node_t sleep_node;
|
||||
node_t * timed_sleep_node;
|
||||
uint8_t is_tasklet;
|
||||
volatile uint8_t sleep_interrupted;
|
||||
list_t * node_waits;
|
||||
int awoken_index;
|
||||
node_t * timeout_node;
|
||||
|
||||
tree_node_t * tree_entry;
|
||||
struct regs * syscall_registers;
|
||||
struct regs * interrupt_registers;
|
||||
list_t * wait_queue;
|
||||
list_t * shm_mappings;
|
||||
list_t * node_waits;
|
||||
list_t * signal_queue;
|
||||
char * signal_kstack;
|
||||
|
||||
node_t sched_node;
|
||||
node_t sleep_node;
|
||||
node_t * timed_sleep_node;
|
||||
node_t * timeout_node;
|
||||
|
||||
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;
|
||||
|
||||
typedef struct {
|
||||
unsigned long end_tick;
|
||||
unsigned long end_subtick;
|
||||
uint64_t end_tick;
|
||||
uint64_t end_subtick;
|
||||
process_t * process;
|
||||
int is_fswait;
|
||||
} 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 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 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 sleep_until(process_t * process, unsigned long seconds, unsigned long subseconds);
|
||||
|
||||
extern volatile process_t * current_process;
|
||||
extern process_t * kernel_idle_task;
|
||||
extern list_t * process_list;
|
||||
|
||||
extern int process_wait_nodes(process_t * process,fs_node_t * nodes[], int timeout);
|
||||
extern void process_delete(process_t * proc);
|
||||
extern void make_process_ready(volatile process_t * proc);
|
||||
extern volatile process_t * next_ready_process(void);
|
||||
extern int wakeup_queue(list_t * queue);
|
||||
extern int wakeup_queue_interrupted(list_t * queue);
|
||||
extern int sleep_on(list_t * queue);
|
||||
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);
|
||||
|
||||
typedef void (*tasklet_t) (void *, char *);
|
||||
extern int create_kernel_tasklet(tasklet_t tasklet, char * name, void * argp);
|
||||
|
||||
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 void process_release_directory(page_directory_t * dir);
|
||||
extern process_t * spawn_worker_thread(void (*entrypoint)(void * argp), const 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 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);
|
||||
|
||||
|
12
base/usr/include/kernel/procfs.h
Normal file
12
base/usr/include/kernel/procfs.h
Normal 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);
|
@ -1,13 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/fs.h>
|
||||
#include <kernel/vfs.h>
|
||||
#include <kernel/ringbuffer.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/termios.h>
|
||||
|
||||
typedef struct pty {
|
||||
/* the PTY number */
|
||||
int name;
|
||||
intptr_t name;
|
||||
|
||||
/* Master and slave endpoints */
|
||||
fs_node_t * master;
|
||||
|
7
base/usr/include/kernel/ramdisk.h
Normal file
7
base/usr/include/kernel/ramdisk.h
Normal 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);
|
@ -1,11 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <kernel/list.h>
|
||||
#include <kernel/vfs.h>
|
||||
#include <kernel/spinlock.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned char * buffer;
|
||||
size_t write_ptr;
|
||||
size_t read_ptr;
|
||||
size_t size;
|
||||
volatile int lock[2];
|
||||
spin_lock_t lock;
|
||||
list_t * wait_queue_readers;
|
||||
list_t * wait_queue_writers;
|
||||
int internal_stop;
|
||||
|
@ -2,7 +2,8 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <kernel/system.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <kernel/types.h>
|
||||
|
||||
#define SHM_PATH_SEPARATOR "."
|
||||
@ -13,9 +14,8 @@ struct shm_node;
|
||||
typedef struct {
|
||||
struct shm_node * parent;
|
||||
volatile uint8_t lock;
|
||||
int32_t ref_count;
|
||||
|
||||
uint32_t num_frames;
|
||||
ssize_t ref_count;
|
||||
size_t num_frames;
|
||||
uintptr_t *frames;
|
||||
} shm_chunk_t;
|
||||
|
||||
@ -27,8 +27,7 @@ typedef struct shm_node {
|
||||
typedef struct {
|
||||
shm_chunk_t * chunk;
|
||||
uint8_t volatile lock;
|
||||
|
||||
uint32_t num_vaddrs;
|
||||
size_t num_vaddrs;
|
||||
uintptr_t *vaddrs;
|
||||
} shm_mapping_t;
|
||||
|
||||
|
@ -1,11 +1,20 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kernel/types.h>
|
||||
void return_from_signal_handler(void);
|
||||
void fix_signal_stacks(void);
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#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);
|
||||
|
||||
|
19
base/usr/include/kernel/spinlock.h
Normal file
19
base/usr/include/kernel/spinlock.h
Normal 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>
|
@ -1,14 +1,10 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#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 * 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 * memrchr(const void * m, int c, 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);
|
||||
|
||||
/* Non-standard broken strtok_r */
|
||||
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);
|
11
base/usr/include/kernel/symboltable.h
Normal file
11
base/usr/include/kernel/symboltable.h
Normal 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;
|
||||
|
||||
|
32
base/usr/include/kernel/syscall.h
Normal file
32
base/usr/include/kernel/syscall.h
Normal 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
Loading…
Reference in New Issue
Block a user