mirror of
https://github.com/kenshineto/kern.git
synced 2025-04-20 17:27:24 +00:00
convert build system to zig
This commit is contained in:
parent
6af21e6a4f
commit
f89a4592c9
5 changed files with 388 additions and 314 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.zig-cache
|
||||||
|
bin
|
328
Makefile
328
Makefile
|
@ -1,319 +1,31 @@
|
||||||
#
|
|
||||||
# Makefile for the 20245 operating system.
|
|
||||||
#
|
|
||||||
|
|
||||||
########################################
|
.PHONY: build clean qemu
|
||||||
# Compilation/assembly definable options
|
.SILENT:
|
||||||
########################################
|
|
||||||
|
|
||||||
#
|
QEMU = qemu-system-i386
|
||||||
# General options:
|
QEMUOPTS = -drive file=bin/disk.img,index=0,media=disk,format=raw
|
||||||
# CLEAR_BSS include code to clear all BSS space
|
|
||||||
# GET_MMAP get BIOS memory map via int 0x15 0xE820
|
|
||||||
# OS_CONFIG OS-related (vs. just standalone) variations
|
|
||||||
# FORCE_INLINING force "inline" functions to be inlined even if
|
|
||||||
# we aren't compiling with at least -O2
|
|
||||||
# MAKE_IDENTITY_MAP Compile vmtables.c with an "identity" page
|
|
||||||
# map table for the first 4MB of the address space.
|
|
||||||
#
|
|
||||||
|
|
||||||
GEN_OPTIONS = -DCLEAR_BSS -DGET_MMAP -DOS_CONFIG
|
qemu: bin/disk.img
|
||||||
|
|
||||||
#
|
|
||||||
# Debugging options:
|
|
||||||
# ANNOUNCE_ENTRY announce entry and exit from kernel functions
|
|
||||||
# RPT_INT_UNEXP report any 'unexpected' interrupts
|
|
||||||
# RPT_INT_MYSTERY report interrupt 0x27 specifically
|
|
||||||
# TRACE_CX context restore tracing
|
|
||||||
# SANITY=n enable "sanity check" level 'n' (0/1/2/3/4)
|
|
||||||
# T_* tracing options (see below)
|
|
||||||
#
|
|
||||||
# Some modules have their own internal debugging options, described
|
|
||||||
# in their introductory comments.
|
|
||||||
#
|
|
||||||
# Define SANITY as 0 for minimal runtime checking (critical errors only).
|
|
||||||
# If not defined, SANITY defaults to 9999.
|
|
||||||
#
|
|
||||||
|
|
||||||
DBG_OPTIONS = -DRPT_INT_UNEXP
|
|
||||||
# DBG_OPTIONS += -DTRACE_CX
|
|
||||||
|
|
||||||
#
|
|
||||||
# T_ options are used to define bits in a "tracing" bitmask, to allow
|
|
||||||
# checking of individual conditions. The following are defined:
|
|
||||||
#
|
|
||||||
# T_PCB PCB alloc/dealloc
|
|
||||||
# T_VM VM-related tasks
|
|
||||||
# T_QUE PCB queue manipulation
|
|
||||||
# T_SCH, T_DSP Scheduler and dispatcher
|
|
||||||
# T_SCALL, T_SRET System call entry and exit
|
|
||||||
# T_EXIT Process exit actions
|
|
||||||
# T_FORK, T_EXEC Fork and exec actions
|
|
||||||
# T_INIT Module init function tracing
|
|
||||||
# T_KM, T_KMFR, T_KMIN Kmem module tracing
|
|
||||||
# T_SIO, T_SIOR, T_SIOW General SIO module checks
|
|
||||||
# T_USER, T_ELF User module operations
|
|
||||||
#
|
|
||||||
# You can add compilation options "on the fly" by using EXTRAS=thing
|
|
||||||
# on the command line. For example, to compile with -H (to show the
|
|
||||||
# hierarchy of #includes):
|
|
||||||
#
|
|
||||||
# make EXTRAS=-H
|
|
||||||
#
|
|
||||||
|
|
||||||
TRACE_OPTIONS = -DT_INIT -DT_USER -DT_ELF -DT_KMIN -DT_VM
|
|
||||||
|
|
||||||
USER_OPTIONS = $(GEN_OPTIONS) $(DBG_OPTIONS) $(TRACE_OPTIONS) $(EXTRAS)
|
|
||||||
|
|
||||||
##############################################################
|
|
||||||
# YOU SHOULD NOT NEED TO CHANGE ANYTHING BELOW THIS POINT!!! #
|
|
||||||
##############################################################
|
|
||||||
|
|
||||||
#
|
|
||||||
# Compilation/assembly control
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# We only want to include from the common header directory
|
|
||||||
#
|
|
||||||
INCLUDES = -I./include
|
|
||||||
|
|
||||||
#
|
|
||||||
# All our object code will live here
|
|
||||||
#
|
|
||||||
BUILDDIR = build
|
|
||||||
LIBDIR = $(BUILDDIR)/lib
|
|
||||||
|
|
||||||
#
|
|
||||||
# Things we need to convert to object form
|
|
||||||
#
|
|
||||||
SUBDIRS :=
|
|
||||||
|
|
||||||
#
|
|
||||||
# Compilation/assembly/linking commands and options
|
|
||||||
#
|
|
||||||
CPP = cpp
|
|
||||||
CPPFLAGS = $(USER_OPTIONS) -nostdinc $(INCLUDES)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Compiler/assembler/etc. settings for 32-bit binaries
|
|
||||||
#
|
|
||||||
CC = gcc -pipe
|
|
||||||
CFLAGS = -m32 -fno-pie -std=c99 -fno-stack-protector -fno-builtin -Wall -Wstrict-prototypes -MD $(CPPFLAGS)
|
|
||||||
# CFLAGS += -O2
|
|
||||||
|
|
||||||
AS = as
|
|
||||||
ASFLAGS = --32
|
|
||||||
|
|
||||||
LD = ld
|
|
||||||
LDFLAGS = -melf_i386 -no-pie -nostdlib -L$(LIBDIR)
|
|
||||||
|
|
||||||
AR = ar
|
|
||||||
#ARFLAGS = rvU
|
|
||||||
ARFLAGS = rsU
|
|
||||||
|
|
||||||
# other programs we use
|
|
||||||
OBJDUMP = objdump
|
|
||||||
OBJCOPY = objcopy
|
|
||||||
NM = nm
|
|
||||||
READELF = readelf
|
|
||||||
PERL = perl
|
|
||||||
|
|
||||||
# delete target files if there is an error, or if make is interrupted
|
|
||||||
.DELETE_ON_ERROR:
|
|
||||||
|
|
||||||
# don't delete intermediate files
|
|
||||||
.PRECIOUS: %.o $(BUILDDIR)/boot/%.o $(BUILDDIR)/kernel/%.o \
|
|
||||||
$(BUILDDIR)/lib/%.o $(BUILDDIR)/user/%.o
|
|
||||||
|
|
||||||
#
|
|
||||||
# Update $(BUILDDIR)/.vars.X if variable X has changed since the last time
|
|
||||||
# 'make' was run.
|
|
||||||
#
|
|
||||||
# Rules that use variable X should depend on $(BUILDDIR)/.vars.X. If
|
|
||||||
# the variable's value has changed, this will update the vars file and
|
|
||||||
# force a rebuild of the rule that depends on it.
|
|
||||||
#
|
|
||||||
|
|
||||||
$(BUILDDIR)/.vars.%: FORCE
|
|
||||||
echo "$($*)" | cmp -s $@ || echo "$($*)" > $@
|
|
||||||
|
|
||||||
.PRECIOUS: $(BUILDDIR)/.vars.%
|
|
||||||
|
|
||||||
.PHONY: FORCE
|
|
||||||
|
|
||||||
#
|
|
||||||
# Transformation rules - these ensure that all necessary compilation
|
|
||||||
# flags are specified
|
|
||||||
#
|
|
||||||
# Note use of 'cpp' to convert .S files to temporary .s files: this allows
|
|
||||||
# use of #include/#define/#ifdef statements. However, the line numbers of
|
|
||||||
# error messages reflect the .s file rather than the original .S file.
|
|
||||||
# (If the .s file already exists before a .S file is assembled, then
|
|
||||||
# the temporary .s file is not deleted. This is useful for figuring
|
|
||||||
# out the line numbers of error messages, but take care not to accidentally
|
|
||||||
# start fixing things by editing the .s file.)
|
|
||||||
#
|
|
||||||
# The .c.X rule produces a .X file which contains the original C source
|
|
||||||
# code from the file being compiled mixed in with the generated
|
|
||||||
# assembly language code. Can be helpful when you need to figure out
|
|
||||||
# exactly what C statement generated which assembly statements!
|
|
||||||
#
|
|
||||||
|
|
||||||
.SUFFIXES: .S .b .X .i
|
|
||||||
|
|
||||||
.c.X:
|
|
||||||
$(CC) $(CFLAGS) -g -c -Wa,-adhln $*.c > $*.X
|
|
||||||
|
|
||||||
.c.s:
|
|
||||||
$(CC) $(CFLAGS) -S $*.c
|
|
||||||
|
|
||||||
#.S.s:
|
|
||||||
# $(CPP) $(CPPFLAGS) -o $*.s $*.S
|
|
||||||
|
|
||||||
#.S.o:
|
|
||||||
# $(CPP) $(CPPFLAGS) -o $*.s $*.S
|
|
||||||
# $(AS) $(ASFLAGS) -o $*.o $*.s -a=$*.lst
|
|
||||||
# $(RM) -f $*.s
|
|
||||||
|
|
||||||
.s.b:
|
|
||||||
$(AS) $(ASFLAGS) -o $*.o $*.s -a=$*.lst
|
|
||||||
$(LD) $(LDFLAGS) -Ttext 0x0 -s --oformat binary -e begtext -o $*.b $*.o
|
|
||||||
|
|
||||||
#.c.o:
|
|
||||||
# $(CC) $(CFLAGS) -c $*.c
|
|
||||||
|
|
||||||
.c.i:
|
|
||||||
$(CC) -E $(CFLAGS) -c $*.c > $*.i
|
|
||||||
|
|
||||||
#
|
|
||||||
# Location of the QEMU binary
|
|
||||||
#
|
|
||||||
QEMU = /home/course/csci352/bin/qemu-system-i386
|
|
||||||
|
|
||||||
# try to generate a unique GDB port
|
|
||||||
GDBPORT = $(shell expr `id -u` % 5000 + 25000)
|
|
||||||
|
|
||||||
# QEMU's gdb stub command line changed in 0.11
|
|
||||||
QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
|
|
||||||
then echo "-gdb tcp::$(GDBPORT)"; \
|
|
||||||
else echo "-s -p $(GDBPORT)"; fi)
|
|
||||||
|
|
||||||
# options for QEMU
|
|
||||||
#
|
|
||||||
# run 'make' with -DQEMUEXTRA=xxx to add option 'xxx' when QEMU is run
|
|
||||||
#
|
|
||||||
# does not include a '-serial' option, as that may or may not be needed
|
|
||||||
QEMUOPTS = -drive file=disk.img,index=0,media=disk,format=raw $(QEMUEXTRA)
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# RULES SECTION
|
|
||||||
########################################
|
|
||||||
|
|
||||||
#
|
|
||||||
# All the individual parts
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# We have a bit of a chicken/egg problem here. When we create the
|
|
||||||
# user.img file, a new version of include/userids.h is generated
|
|
||||||
# in build/new_userids.h; this is compared to the existing userids.h
|
|
||||||
# file, and if they differ, it is copied into include/userids.h.
|
|
||||||
# This, unfortunately, should trigger a rebuild of anything that
|
|
||||||
# includes <userids.h>, but that is all of the user/*.c files along
|
|
||||||
# with kernel/kernel.c. We could move the user.img creation earlier,
|
|
||||||
# which would automatically be incorporated into the build of the
|
|
||||||
# kernel, but it wouldn't automatically trigger recreating the
|
|
||||||
# userland stuff. We settle for having the build process tell the
|
|
||||||
# user that a rebuild is required.
|
|
||||||
#
|
|
||||||
|
|
||||||
all: lib bootstrap kernel userland util user.img disk.img
|
|
||||||
|
|
||||||
# Rules etc. for the various sections of the system
|
|
||||||
include lib/Make.mk
|
|
||||||
include boot/Make.mk
|
|
||||||
include user/Make.mk
|
|
||||||
include kernel/Make.mk
|
|
||||||
include util/Make.mk
|
|
||||||
|
|
||||||
#
|
|
||||||
# Rules for building the disk image
|
|
||||||
#
|
|
||||||
|
|
||||||
disk.img: $(BUILDDIR)/kernel/kernel.b $(BUILDDIR)/boot/boot user.img BuildImage
|
|
||||||
./BuildImage -d usb -o disk.img -b $(BUILDDIR)/boot/boot \
|
|
||||||
$(BUILDDIR)/kernel/kernel.b 0x10000 \
|
|
||||||
user.img 0x30000
|
|
||||||
|
|
||||||
#
|
|
||||||
# Rules for running with QEMU
|
|
||||||
#
|
|
||||||
|
|
||||||
# how to create the .gdbinit config file if we need it
|
|
||||||
.gdbinit: util/gdbinit.tmpl
|
|
||||||
sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@
|
|
||||||
|
|
||||||
# "ordinary" gdb
|
|
||||||
gdb:
|
|
||||||
gdb -q -n -x .gdbinit
|
|
||||||
|
|
||||||
# gdb with the super-fancy Text User Interface
|
|
||||||
gdb-tui:
|
|
||||||
gdb -q -n -x .gdbinit -tui
|
|
||||||
|
|
||||||
qemu: disk.img
|
|
||||||
$(QEMU) -serial mon:stdio $(QEMUOPTS)
|
$(QEMU) -serial mon:stdio $(QEMUOPTS)
|
||||||
|
|
||||||
qemu-nox: disk.img
|
|
||||||
$(QEMU) -nographic $(QEMUOPTS)
|
|
||||||
|
|
||||||
qemu-gdb: disk.img .gdbinit
|
|
||||||
@echo "*** Now run 'gdb'." 1>&2
|
|
||||||
$(QEMU) -serial mon:stdio $(QEMUOPTS) -S $(QEMUGDB)
|
|
||||||
|
|
||||||
qemu-nox-gdb: disk.img .gdbinit
|
|
||||||
@echo "*** Now run 'gdb'." 1>&2
|
|
||||||
$(QEMU) -nographic $(QEMUOPTS) -S $(QEMUGDB)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Create a printable namelist from the kernel file
|
|
||||||
#
|
|
||||||
# kernel.nl: only global symbols
|
|
||||||
# kernel.nll: all symbols
|
|
||||||
#
|
|
||||||
|
|
||||||
kernel.nl: $(BUILDDIR)/kernel/kernel
|
|
||||||
nm -Bng $(BUILDDIR)/kernel/kernel.o | pr -w80 -3 > kernel.nl
|
|
||||||
|
|
||||||
kernel.nll: $(BUILDDIR)/kernel/kernel
|
|
||||||
nm -Bn $(BUILDDIR)/kernel/kernel.o | pr -w80 -3 > kernel.nll
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate a disassembly
|
|
||||||
#
|
|
||||||
|
|
||||||
kernel.dis: $(BUILDDIR)/kernel/kernel
|
|
||||||
objdump -d $(BUILDDIR)/kernel/kernel > kernel.dis
|
|
||||||
|
|
||||||
#
|
|
||||||
# Cleanup etc.
|
|
||||||
#
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILDDIR) .gdbinit *.nl *.nll *.lst *.i *.X *.dis
|
rm -fr .zig-cache
|
||||||
|
rm -fr bin
|
||||||
|
|
||||||
realclean: clean
|
build:
|
||||||
rm -f LOG *.img $(UTIL_BIN)
|
zig build
|
||||||
|
|
||||||
#
|
bin/boot.bin: build
|
||||||
# Automatically generate dependencies for header files included
|
cd bin && \
|
||||||
# from C source files.
|
objcopy -S -O binary -j .text boot boot.bin
|
||||||
#
|
|
||||||
$(BUILDDIR)/.deps: $(foreach dir, $(SUBDIRS), $(wildcard $(BUILDDIR)/$(dir)/*.d))
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(PERL) util/mergedep.pl $@ $^
|
|
||||||
|
|
||||||
-include $(BUILDDIR)/.deps
|
bin/user.img: build
|
||||||
|
cd bin && \
|
||||||
|
./mkblob init shell
|
||||||
|
|
||||||
|
bin/disk.img: build bin/boot.bin bin/user.img
|
||||||
|
cd bin && \
|
||||||
|
./BuildImage -d usb -o disk.img -b boot.bin \
|
||||||
|
kernel 0x10000 user.img 0x40000
|
||||||
|
|
||||||
.PHONY: all clean realclean
|
|
||||||
|
|
9
boot/boot.ld
Normal file
9
boot/boot.ld
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||||||
|
OUTPUT_ARCH(i386)
|
||||||
|
ENTRY(bootentry)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x0;
|
||||||
|
.text : { *(.text .stub .text.*) }
|
||||||
|
}
|
351
build.zig
Normal file
351
build.zig
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
|
const c_flags = &[_][]const u8{
|
||||||
|
// lang
|
||||||
|
"-std=c99",
|
||||||
|
// warnings
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-pedantic",
|
||||||
|
// flags
|
||||||
|
"-fno-pie",
|
||||||
|
"-fno-stack-protector",
|
||||||
|
"-fno-omit-frame-pointer",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-fno-builtin",
|
||||||
|
};
|
||||||
|
|
||||||
|
const ld_flags = &[_][]const u8{
|
||||||
|
"-nmagic",
|
||||||
|
"-nostdlib",
|
||||||
|
"--no-warn-rwx-segments",
|
||||||
|
};
|
||||||
|
|
||||||
|
const boot_src = &[_][]const u8{"boot/boot.S"};
|
||||||
|
|
||||||
|
const kernel_src = &[_][]const u8{
|
||||||
|
"kernel/cio.c",
|
||||||
|
"kernel/clock.c",
|
||||||
|
"kernel/isrs.S",
|
||||||
|
"kernel/kernel.c",
|
||||||
|
"kernel/kmem.c",
|
||||||
|
"kernel/list.c",
|
||||||
|
"kernel/procs.c",
|
||||||
|
"kernel/sio.c",
|
||||||
|
"kernel/startup.S",
|
||||||
|
"kernel/support.c",
|
||||||
|
"kernel/syscalls.c",
|
||||||
|
"kernel/user.c",
|
||||||
|
"kernel/vm.c",
|
||||||
|
"kernel/vmtables.c",
|
||||||
|
"lib/klibc.c",
|
||||||
|
};
|
||||||
|
|
||||||
|
const lib_src = &[_][]const u8{
|
||||||
|
"lib/bound.c",
|
||||||
|
"lib/cvtdec0.c",
|
||||||
|
"lib/cvtdec.c",
|
||||||
|
"lib/cvthex.c",
|
||||||
|
"lib/cvtoct.c",
|
||||||
|
"lib/cvtuns0.c",
|
||||||
|
"lib/cvtuns.c",
|
||||||
|
"lib/memclr.c",
|
||||||
|
"lib/memcpy.c",
|
||||||
|
"lib/memset.c",
|
||||||
|
"lib/pad.c",
|
||||||
|
"lib/padstr.c",
|
||||||
|
"lib/sprint.c",
|
||||||
|
"lib/str2int.c",
|
||||||
|
"lib/strcat.c",
|
||||||
|
"lib/strcmp.c",
|
||||||
|
"lib/strcpy.c",
|
||||||
|
"lib/strlen.c",
|
||||||
|
};
|
||||||
|
|
||||||
|
const ulib_src = &[_][]const u8{
|
||||||
|
"lib/entry.S",
|
||||||
|
"lib/ulibc.c",
|
||||||
|
"lib/ulibs.S",
|
||||||
|
};
|
||||||
|
|
||||||
|
const Prog = struct {
|
||||||
|
name: []const u8,
|
||||||
|
source: []const []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
const util_progs = &[_]Prog{
|
||||||
|
// mkblob
|
||||||
|
Prog{
|
||||||
|
.name = "mkblob",
|
||||||
|
.source = &[_][]const u8{"util/mkblob.c"},
|
||||||
|
},
|
||||||
|
// listblob
|
||||||
|
Prog{
|
||||||
|
.name = "listblob",
|
||||||
|
.source = &[_][]const u8{"util/listblob.c"},
|
||||||
|
},
|
||||||
|
// BuildImage
|
||||||
|
Prog{
|
||||||
|
.name = "BuildImage",
|
||||||
|
.source = &[_][]const u8{"util/BuildImage.c"},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const user_progs = &[_]Prog{
|
||||||
|
// idle
|
||||||
|
Prog{
|
||||||
|
.name = "idle",
|
||||||
|
.source = &[_][]const u8{"user/idle.c"},
|
||||||
|
},
|
||||||
|
// init
|
||||||
|
Prog{
|
||||||
|
.name = "init",
|
||||||
|
.source = &[_][]const u8{"user/init.c"},
|
||||||
|
},
|
||||||
|
// progABC
|
||||||
|
Prog{
|
||||||
|
.name = "progABC",
|
||||||
|
.source = &[_][]const u8{"user/progABC.c"},
|
||||||
|
},
|
||||||
|
// progDE
|
||||||
|
Prog{
|
||||||
|
.name = "progDE",
|
||||||
|
.source = &[_][]const u8{"user/progDE.c"},
|
||||||
|
},
|
||||||
|
// progFG
|
||||||
|
Prog{
|
||||||
|
.name = "progFG",
|
||||||
|
.source = &[_][]const u8{"user/progFG.c"},
|
||||||
|
},
|
||||||
|
// progH
|
||||||
|
Prog{
|
||||||
|
.name = "progH",
|
||||||
|
.source = &[_][]const u8{"user/progH.c"},
|
||||||
|
},
|
||||||
|
// progI
|
||||||
|
Prog{
|
||||||
|
.name = "progI",
|
||||||
|
.source = &[_][]const u8{"user/progI.c"},
|
||||||
|
},
|
||||||
|
// progJ
|
||||||
|
Prog{
|
||||||
|
.name = "progJ",
|
||||||
|
.source = &[_][]const u8{"user/progJ.c"},
|
||||||
|
},
|
||||||
|
// progKL
|
||||||
|
Prog{
|
||||||
|
.name = "progKL",
|
||||||
|
.source = &[_][]const u8{"user/progKL.c"},
|
||||||
|
},
|
||||||
|
// progKL
|
||||||
|
Prog{
|
||||||
|
.name = "progKL",
|
||||||
|
.source = &[_][]const u8{"user/progKL.c"},
|
||||||
|
},
|
||||||
|
// progMN
|
||||||
|
Prog{
|
||||||
|
.name = "progMN",
|
||||||
|
.source = &[_][]const u8{"user/progMN.c"},
|
||||||
|
},
|
||||||
|
// progP
|
||||||
|
Prog{
|
||||||
|
.name = "progP",
|
||||||
|
.source = &[_][]const u8{"user/progP.c"},
|
||||||
|
},
|
||||||
|
// progQ
|
||||||
|
Prog{
|
||||||
|
.name = "progQ",
|
||||||
|
.source = &[_][]const u8{"user/progQ.c"},
|
||||||
|
},
|
||||||
|
// progR
|
||||||
|
Prog{
|
||||||
|
.name = "progR",
|
||||||
|
.source = &[_][]const u8{"user/progR.c"},
|
||||||
|
},
|
||||||
|
// progS
|
||||||
|
Prog{
|
||||||
|
.name = "progS",
|
||||||
|
.source = &[_][]const u8{"user/progS.c"},
|
||||||
|
},
|
||||||
|
// progTUV
|
||||||
|
Prog{
|
||||||
|
.name = "progTUV",
|
||||||
|
.source = &[_][]const u8{"user/progTUV.c"},
|
||||||
|
},
|
||||||
|
// progW
|
||||||
|
Prog{
|
||||||
|
.name = "progW",
|
||||||
|
.source = &[_][]const u8{"user/progW.c"},
|
||||||
|
},
|
||||||
|
// progX
|
||||||
|
Prog{
|
||||||
|
.name = "progX",
|
||||||
|
.source = &[_][]const u8{"user/progX.c"},
|
||||||
|
},
|
||||||
|
// progY
|
||||||
|
Prog{
|
||||||
|
.name = "progY",
|
||||||
|
.source = &[_][]const u8{"user/progY.c"},
|
||||||
|
},
|
||||||
|
// progZ
|
||||||
|
Prog{
|
||||||
|
.name = "progZ",
|
||||||
|
.source = &[_][]const u8{"user/progZ.c"},
|
||||||
|
},
|
||||||
|
// shell
|
||||||
|
Prog{
|
||||||
|
.name = "shell",
|
||||||
|
.source = &[_][]const u8{"user/shell.c"},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const AddSourcesOpts = struct { exe: *std.Build.Step.Compile, sources: []const []const []const u8, c_flags: []const []const u8 };
|
||||||
|
|
||||||
|
fn add_sources(b: *std.Build, opts: AddSourcesOpts) void {
|
||||||
|
// add asm and c source files
|
||||||
|
for (opts.sources) |source| {
|
||||||
|
for (source) |file| {
|
||||||
|
if (std.mem.endsWith(u8, file, ".c")) {
|
||||||
|
// c file
|
||||||
|
opts.exe.addCSourceFile(.{ .file = b.path(file), .flags = opts.c_flags });
|
||||||
|
} else {
|
||||||
|
// assembly file
|
||||||
|
opts.exe.addAssemblyFile(b.path(file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const BuildKernBinaryOpts = struct {
|
||||||
|
name: []const u8,
|
||||||
|
target: std.Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
sources: []const []const []const u8,
|
||||||
|
linker: ?[]const u8 = null,
|
||||||
|
entry: []const u8 = "_start",
|
||||||
|
};
|
||||||
|
|
||||||
|
fn build_kern_binary(b: *std.Build, opts: BuildKernBinaryOpts) void {
|
||||||
|
// create compile step
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = opts.name,
|
||||||
|
.target = opts.target,
|
||||||
|
.optimize = opts.optimize,
|
||||||
|
.strip = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// add include path
|
||||||
|
exe.addIncludePath(b.path("include/"));
|
||||||
|
exe.entry = .{ .symbol_name = opts.entry };
|
||||||
|
|
||||||
|
// add asm and c source files
|
||||||
|
add_sources(b, .{
|
||||||
|
.exe = exe,
|
||||||
|
.sources = opts.sources,
|
||||||
|
.c_flags = c_flags,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (opts.linker != null) {
|
||||||
|
exe.setLinkerScript(b.path(opts.linker.?));
|
||||||
|
}
|
||||||
|
|
||||||
|
const step = b.addInstallArtifact(exe, .{ .dest_dir = .{
|
||||||
|
.override = .{ .custom = "../bin" },
|
||||||
|
} });
|
||||||
|
b.getInstallStep().dependOn(&step.step);
|
||||||
|
}
|
||||||
|
|
||||||
|
const BuildNativeBinaryOpts = struct {
|
||||||
|
name: []const u8,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
sources: []const []const []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn build_native_binary(b: *std.Build, opts: BuildNativeBinaryOpts) void {
|
||||||
|
// create compile step
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = opts.name,
|
||||||
|
.target = b.graph.host,
|
||||||
|
.optimize = opts.optimize,
|
||||||
|
.strip = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// include libc
|
||||||
|
exe.linkLibC();
|
||||||
|
|
||||||
|
// add asm and c source files
|
||||||
|
add_sources(b, .{
|
||||||
|
.exe = exe,
|
||||||
|
.sources = opts.sources,
|
||||||
|
.c_flags = &.{},
|
||||||
|
});
|
||||||
|
|
||||||
|
const step = b.addInstallArtifact(exe, .{ .dest_dir = .{
|
||||||
|
.override = .{ .custom = "../bin" },
|
||||||
|
} });
|
||||||
|
b.getInstallStep().dependOn(&step.step);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) !void {
|
||||||
|
|
||||||
|
// context
|
||||||
|
const target = b.standardTargetOptions(.{
|
||||||
|
.default_target = .{
|
||||||
|
.cpu_arch = std.Target.Cpu.Arch.x86,
|
||||||
|
.os_tag = std.Target.Os.Tag.freestanding,
|
||||||
|
.abi = std.Target.Abi.gnu,
|
||||||
|
.ofmt = std.Target.ObjectFormat.elf,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const optimize = std.builtin.OptimizeMode.ReleaseSmall;
|
||||||
|
|
||||||
|
// boot
|
||||||
|
build_kern_binary(b, .{
|
||||||
|
.name = "boot",
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.sources = &.{
|
||||||
|
boot_src,
|
||||||
|
},
|
||||||
|
.linker = "boot/boot.ld",
|
||||||
|
.entry = "bootentry",
|
||||||
|
});
|
||||||
|
|
||||||
|
// kernel
|
||||||
|
build_kern_binary(b, .{
|
||||||
|
.name = "kernel",
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.sources = &.{
|
||||||
|
kernel_src,
|
||||||
|
lib_src,
|
||||||
|
},
|
||||||
|
.linker = "kernel/kernel.ld",
|
||||||
|
});
|
||||||
|
|
||||||
|
// user_progs
|
||||||
|
for (user_progs) |prog| {
|
||||||
|
build_kern_binary(b, .{
|
||||||
|
.name = prog.name,
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.sources = &.{
|
||||||
|
prog.source,
|
||||||
|
lib_src,
|
||||||
|
ulib_src,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// util_progs
|
||||||
|
for (util_progs) |prog| {
|
||||||
|
build_native_binary(b, .{
|
||||||
|
.name = prog.name,
|
||||||
|
.optimize = optimize,
|
||||||
|
.sources = &.{
|
||||||
|
prog.source,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
12
kernel/sio.c
12
kernel/sio.c
|
@ -106,7 +106,7 @@ static uint8_t ier;
|
||||||
|
|
||||||
// queue for read-blocked processes
|
// queue for read-blocked processes
|
||||||
#ifdef QNAME
|
#ifdef QNAME
|
||||||
QTYPE QNAME;
|
extern QTYPE QNAME;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -253,7 +253,7 @@ static void sio_isr( int vector, int ecode ) {
|
||||||
sprint( b256, "sio isr: IIR %02x\n", ((uint32_t) iir) & 0xff );
|
sprint( b256, "sio isr: IIR %02x\n", ((uint32_t) iir) & 0xff );
|
||||||
PANIC( 0, b256 );
|
PANIC( 0, b256 );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// should never reach this point!
|
// should never reach this point!
|
||||||
|
@ -329,7 +329,7 @@ void sio_init( void ) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
outb( UA4_LCR, UA4_LCR_WLS_8 | UA4_LCR_1_STOP_BIT | UA4_LCR_NO_PARITY );
|
outb( UA4_LCR, UA4_LCR_WLS_8 | UA4_LCR_1_STOP_BIT | UA4_LCR_NO_PARITY );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Set the ISEN bit to enable the interrupt request signal,
|
** Set the ISEN bit to enable the interrupt request signal,
|
||||||
** and the DTR and RTS bits to enable two-way communication.
|
** and the DTR and RTS bits to enable two-way communication.
|
||||||
|
@ -450,7 +450,7 @@ int sio_readc( void ) {
|
||||||
// assume there is no character available
|
// assume there is no character available
|
||||||
ch = -1;
|
ch = -1;
|
||||||
|
|
||||||
//
|
//
|
||||||
// If there is a character, return it
|
// If there is a character, return it
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -675,7 +675,7 @@ void sio_dump( bool_t full ) {
|
||||||
|
|
||||||
if( incount ) {
|
if( incount ) {
|
||||||
cio_puts( "SIO input queue: \"" );
|
cio_puts( "SIO input queue: \"" );
|
||||||
ptr = innext;
|
ptr = innext;
|
||||||
for( n = 0; n < incount; ++n ) {
|
for( n = 0; n < incount; ++n ) {
|
||||||
put_char_or_code( *ptr++ );
|
put_char_or_code( *ptr++ );
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,7 @@ void sio_dump( bool_t full ) {
|
||||||
if( outcount ) {
|
if( outcount ) {
|
||||||
cio_puts( "SIO output queue: \"" );
|
cio_puts( "SIO output queue: \"" );
|
||||||
cio_puts( " ot: \"" );
|
cio_puts( " ot: \"" );
|
||||||
ptr = outnext;
|
ptr = outnext;
|
||||||
for( n = 0; n < outcount; ++n ) {
|
for( n = 0; n < outcount; ++n ) {
|
||||||
put_char_or_code( *ptr++ );
|
put_char_or_code( *ptr++ );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue