new development tools
This commit is contained in:
parent
6cc262b43b
commit
1ba806ca1b
32
QA.sh
32
QA.sh
@ -1,7 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$JEHANNE" = "" ]; then
|
||||
echo ./hacking/QA.sh requires the shell started by ./hacking/devshell.sh
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trap : 2
|
||||
|
||||
$JEHANNE/hacking/bin/ufs -root=$JEHANNE &
|
||||
$JEHANNE/hacking/bin/ufs -d=0 -root=$JEHANNE &
|
||||
ufspid=$!
|
||||
|
||||
export machineflag=pc
|
||||
@ -14,23 +20,41 @@ if [ "$(uname)" = "Linux" ] && [ -e /dev/kvm ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
cd $JEHANNE/arch/$ARCH/kern/
|
||||
if [ "$DISK" = "" ]; then
|
||||
export DISK=$JEHANNE/hacking/sample-disk.img
|
||||
fi
|
||||
|
||||
if [ -a $DISK ]; then
|
||||
bootDisk="-device ahci,id=ahci -drive id=boot,file=$DISK,index=0,cache=writeback,if=none -device ide-drive,drive=boot,bus=ahci.0"
|
||||
fi
|
||||
|
||||
if [ "$KERNDIR" = "" ]; then
|
||||
KERNDIR=$JEHANNE/arch/$ARCH/kern/
|
||||
fi
|
||||
if [ "$KERNEL" = "" ]; then
|
||||
KERNEL=jehanne.32bit
|
||||
fi
|
||||
|
||||
cd $KERNDIR
|
||||
read -r cmd <<EOF
|
||||
$kvmdo qemu-system-x86_64 -s -cpu Opteron_G1 -smp 1 -m 2048 $kvmflag \
|
||||
-serial stdio \
|
||||
--nographic \
|
||||
--monitor /dev/null \
|
||||
--machine $machineflag \
|
||||
$bootDisk \
|
||||
-net nic,model=rtl8139 \
|
||||
-net user,hostfwd=tcp::5555-:1522 \
|
||||
-net dump,file=/tmp/vm0.pcap \
|
||||
-redir tcp:9999::9 \
|
||||
-redir tcp:17010::17010 \
|
||||
-redir tcp:17013::17013 \
|
||||
-append "nobootprompt=tcp maxcores=1024 fs=10.0.2.2 auth=10.0.2.2 nvram=/boot/nvram nvrlen=512 nvroff=0" \
|
||||
-kernel jehanne.32bit $*
|
||||
-append "nobootprompt=tcp maxcores=1024 fs=10.0.2.2 auth=10.0.2.2 nvram=/boot/nvram nvrlen=512 nvroff=0 $KAPPEND" \
|
||||
-kernel $KERNEL $*
|
||||
EOF
|
||||
|
||||
#-no-reboot -D $JEHANNE/../qemu.log -d int,cpu_reset,in_asm \
|
||||
|
||||
echo $cmd
|
||||
eval $cmd
|
||||
|
||||
|
@ -1,12 +1,67 @@
|
||||
#!/bin/bash
|
||||
|
||||
BUILD_GO_TOOLS=true
|
||||
BUILD_DRAWTERM=true
|
||||
|
||||
while test $# -gt 0
|
||||
do
|
||||
case "$1" in
|
||||
--help) echo "$0 [ --no-tools | --no-drawterm | --help ]"
|
||||
exit 0
|
||||
;;
|
||||
--no-tools) BUILD_GO_TOOLS=false
|
||||
;;
|
||||
--no-drawterm) BUILD_DRAWTERM=false
|
||||
;;
|
||||
--*) echo "bad option $1" && exit 1
|
||||
;;
|
||||
*) echo "unexpected argument $1" && exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
cd `dirname $0`
|
||||
if [ -z "$UTILITIES" ]; then
|
||||
UTILITIES=`pwd`
|
||||
fi
|
||||
git clean -x -d -f $UTILITIES
|
||||
echo -n Building development tools...
|
||||
GOBIN="$UTILITIES/bin" GOPATH="$UTILITIES/third_party:$UTILITIES" go get -d jehanne/cmd/...
|
||||
GOBIN="$UTILITIES/bin" GOPATH="$UTILITIES/third_party:$UTILITIES" go install jehanne/cmd/...
|
||||
GOBIN="$UTILITIES/bin" GOPATH="$UTILITIES/third_party:$UTILITIES" go install github.com/lionkov/ninep/srv/examples/ufs
|
||||
if [ "$BUILD_GO_TOOLS$BUILD_DRAWTERM" = "truetrue" ]; then
|
||||
git clean -x -d -f $UTILITIES/bin
|
||||
fi
|
||||
if [ "$BUILD_GO_TOOLS" = "true" ]; then
|
||||
echo -n Building development tools...
|
||||
(
|
||||
GOBIN="$UTILITIES/bin" GOPATH="$UTILITIES/third_party:$UTILITIES" go get -d jehanne/cmd/... &&
|
||||
GOBIN="$UTILITIES/bin" GOPATH="$UTILITIES/third_party:$UTILITIES" go install jehanne/cmd/... &&
|
||||
GOBIN="$UTILITIES/bin" GOPATH="$UTILITIES/third_party:$UTILITIES" go install github.com/lionkov/ninep/srv/examples/ufs
|
||||
)
|
||||
STATUS="$?"
|
||||
if [ ! $STATUS -eq "0" ]
|
||||
then
|
||||
echo "FAIL"
|
||||
exit $STATUS
|
||||
else
|
||||
echo "done."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo " DONE."
|
||||
if [ "$BUILD_DRAWTERM" = "true" ]; then
|
||||
echo -n Building drawterm...
|
||||
(
|
||||
cd $UTILITIES/third_party/src/github.com/0intro/drawterm/ &&
|
||||
git clean -xdf > ../drawterm.build.log 2>&1 &&
|
||||
CONF=unix make >> ../drawterm.build.log 2>&1 &&
|
||||
mv drawterm $UTILITIES/bin
|
||||
)
|
||||
STATUS="$?"
|
||||
if [ $STATUS -eq "0" ]
|
||||
then
|
||||
rm $UTILITIES/third_party/src/github.com/0intro/drawterm.build.log
|
||||
echo "done."
|
||||
else
|
||||
echo "FAIL"
|
||||
cat $UTILITIES/third_party/src/github.com/0intro/drawterm.build.log
|
||||
exit $STATUS
|
||||
fi
|
||||
fi
|
||||
exit $STATUS
|
||||
|
192
cross/init.sh
Executable file
192
cross/init.sh
Executable file
@ -0,0 +1,192 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This file is part of Jehanne.
|
||||
#
|
||||
# Copyright (C) 2016 Giacomo Tesio <giacomo@tesio.it>
|
||||
#
|
||||
# Jehanne is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 2 of the License.
|
||||
#
|
||||
# Jehanne is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if [ "$JEHANNE" = "" ]; then
|
||||
echo $0 requires the shell started by ./hacking/devshell.sh
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# WELLCOME TO HELL ! ! !
|
||||
#
|
||||
|
||||
# If you want to understand _WHY_ Jehanne exists, you should try to
|
||||
# create a GCC crosscompiler in Debian without requiring root access or Tex.
|
||||
# And this despite the extreme quality of Debian GNU/Linux!
|
||||
|
||||
# fetch all sources
|
||||
(cd src && fetch)
|
||||
|
||||
# To create a Jehanne version of GCC, we need specific OUTDATED versions
|
||||
# of Autotools that won't compile easily in a modern Linux distro.
|
||||
|
||||
function failOnError {
|
||||
# $1 -> exit status on a previous command
|
||||
# $2 -> task description
|
||||
if [ $1 -ne 0 ]; then
|
||||
echo "ERROR $2"
|
||||
exit $1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# build m4 1.4.14
|
||||
# - workaround a bug in lib/stdio.in.h, see http://lists.gnu.org/archive/html/bug-m4/2012-08/msg00008.html
|
||||
# - workaround a bug in src/m4.h, see https://bugs.archlinux.org/task/19829
|
||||
# both bugs exists thanks to changes in external code
|
||||
if [ ! -f tmp/bin/m4 ]; then
|
||||
(
|
||||
cd src/m4 &&
|
||||
sed -i '/_GL_WARN_ON_USE (gets/d' lib/stdio.in.h &&
|
||||
( grep -q '#include <sys/stat.h>' src/m4.h || sed -i 's:.*\#include <sys/types\.h>.*:&\n#include <sys/stat.h>:g' src/m4.h ) &&
|
||||
./configure --prefix=$JEHANNE/hacking/cross/tmp &&
|
||||
make && make install
|
||||
)
|
||||
failOnError $? "building m4"
|
||||
fi
|
||||
# build autoconf 2.64
|
||||
# - hack git-version-gen to avoid the -dirty flag in version on make
|
||||
# - autoreconf
|
||||
# - disable doc build
|
||||
# - disable man build
|
||||
if [ ! -f tmp/bin/autoconf ]; then
|
||||
(
|
||||
cd src/autoconf &&
|
||||
cp ../../patch/autoconf/build-aux/git-version-gen build-aux/git-version-gen &&
|
||||
autoreconf &&
|
||||
./configure --prefix=$JEHANNE/hacking/cross/tmp &&
|
||||
cp ../../patch/MakeNothing.in ../autoconf/doc/Makefile.in &&
|
||||
cp ../../patch/MakeNothing.in ../autoconf/man/Makefile.in &&
|
||||
make && make install
|
||||
)
|
||||
failOnError $? "building autoconf"
|
||||
fi
|
||||
# build automake 1.11.1
|
||||
# - autoreconf to avoid conflicts with installed automake
|
||||
# - automake; configure; make (that will fail) and then automake again
|
||||
# to workaround this hell
|
||||
# - disable doc build
|
||||
# - disable disable tests build
|
||||
if [ ! -f tmp/bin/automake ]; then
|
||||
(
|
||||
cd src/automake &&
|
||||
echo > doc/Makefile.am &&
|
||||
touch NEWS AUTHORS && autoreconf -i &&
|
||||
automake &&
|
||||
(./configure --prefix=$JEHANNE/hacking/cross/tmp && make; automake) &&
|
||||
./configure --prefix=$JEHANNE/hacking/cross/tmp &&
|
||||
cp ../../patch/MakeNothing.in doc/Makefile.in &&
|
||||
cp ../../patch/MakeNothing.in tests/Makefile.in &&
|
||||
make && make install
|
||||
)
|
||||
failOnError $? "building automake"
|
||||
fi
|
||||
# build libtool 2.4
|
||||
if [ ! -f tmp/bin/libtool ]; then
|
||||
(
|
||||
cd src/libtool &&
|
||||
./configure --prefix=$JEHANNE/hacking/cross/tmp &&
|
||||
make && make install
|
||||
)
|
||||
failOnError $? "building libtool"
|
||||
fi
|
||||
|
||||
# FINALLY! We have our OUTDATED autotools in tmp/bin
|
||||
export PATH=$JEHANNE/hacking/cross/tmp/bin:$PATH
|
||||
export CROSS_DIR=$JEHANNE/hacking/cross
|
||||
if [ "$BUILD_DIRS_ROOT" = "" ]; then
|
||||
export BUILD_DIRS_ROOT=$JEHANNE/hacking/cross/src
|
||||
fi
|
||||
if [ ! -d $BUILD_DIRS_ROOT ]; then
|
||||
mkdir $BUILD_DIRS_ROOT
|
||||
fi
|
||||
|
||||
function dynpatch {
|
||||
# $1 -> path from cross/src
|
||||
# $2 -> string to search
|
||||
( cd $JEHANNE/hacking/cross/src &&
|
||||
grep -q jehanne $1 ||
|
||||
sed -n -i -e "/$2/r ../patch/$1" -e '1x' -e '2,${x;p}' -e '${x;p}' $1
|
||||
)
|
||||
}
|
||||
|
||||
# Patch and build binutils
|
||||
if [ "$BINUTILS_BUILD_DIR" = "" ]; then
|
||||
export BINUTILS_BUILD_DIR=$BUILD_DIRS_ROOT/build-binutils
|
||||
fi
|
||||
if [ ! -d $BINUTILS_BUILD_DIR ]; then
|
||||
mkdir $BINUTILS_BUILD_DIR
|
||||
fi
|
||||
if [ ! -f toolchain/bin/x86_64-jehanne-ar ]; then
|
||||
(
|
||||
sed -i '/jehanne/b; /ELF_TARGET_ID/,/elf_backend_can_gc_sections/s/0x200000/0x1000 \/\/ jehanne hack/g' src/binutils/bfd/elf64-x86-64.c &&
|
||||
sed -i '/jehanne/b; s/| -tirtos/| -tirtos* | -jehanne/g' src/binutils/config.sub &&
|
||||
dynpatch 'binutils/bfd/config.bfd' '\# END OF targmatch.h' &&
|
||||
dynpatch 'binutils/gas/configure.tgt' ' i860-\*-\*)' &&
|
||||
( grep -q jehanne src/binutils/ld/configure.tgt || patch -p1 < patch/binutils/ld/configure.tgt ) &&
|
||||
cp patch/binutils/ld/emulparams/elf_x86_64_jehanne.sh src/binutils/ld/emulparams/ &&
|
||||
cp patch/binutils/ld/emulparams/elf_i386_jehanne.sh src/binutils/ld/emulparams/ &&
|
||||
dynpatch 'binutils/ld/Makefile.am' 'eelf_x86_64.c: ' &&
|
||||
(grep 'eelf_i386_jehanne.c \\' src/binutils/ld/Makefile.am || sed -i 's/.*ALL_EMULATION_SOURCES = \\.*/&\n\teelf_i386_jehanne.c \\/' src/binutils/ld/Makefile.am) &&
|
||||
(grep 'eelf_x86_64_jehanne.c \\' src/binutils/ld/Makefile.am || sed -i 's/.*ALL_64_EMULATION_SOURCES = \\.*/&\n\teelf_x86_64_jehanne.c \\/' src/binutils/ld/Makefile.am) &&
|
||||
cd src/binutils/ld && automake && cd ../ &&
|
||||
cd $BINUTILS_BUILD_DIR &&
|
||||
$CROSS_DIR/src/binutils/configure --disable-shared --enable-static --prefix=$JEHANNE/hacking/cross/toolchain --with-sysroot=$JEHANNE --target=x86_64-jehanne --enable-interwork --enable-multilib --disable-nls --disable-werror &&
|
||||
cp $CROSS_DIR/patch/MakeNothing.in $CROSS_DIR/src/binutils/bfd/doc/Makefile &&
|
||||
cp $CROSS_DIR/patch/MakeNothing.in $CROSS_DIR/src/binutils/bfd/po/Makefile &&
|
||||
cp $CROSS_DIR/patch/MakeNothing.in $CROSS_DIR/src/binutils/gas/doc/Makefile &&
|
||||
cp $CROSS_DIR/patch/MakeNothing.in $CROSS_DIR/src/binutils/binutils/doc/Makefile &&
|
||||
make MAKEINFO=true MAKEINFOHTML=true TEXI2DVI=true TEXI2PDF=true DVIPS=true &&
|
||||
make MAKEINFO=true MAKEINFOHTML=true TEXI2DVI=true TEXI2PDF=true DVIPS=true install
|
||||
)
|
||||
failOnError $? "building binutils"
|
||||
fi
|
||||
|
||||
# Patch and build gcc
|
||||
if [ "$GCC_BUILD_DIR" = "" ]; then
|
||||
export GCC_BUILD_DIR=$BUILD_DIRS_ROOT/build-gcc
|
||||
fi
|
||||
if [ ! -d $GCC_BUILD_DIR ]; then
|
||||
mkdir $GCC_BUILD_DIR
|
||||
fi
|
||||
(
|
||||
pwd &&
|
||||
( grep -q jehanne src/gcc/gcc/config.gcc || patch -p1 < patch/gcc/gcc/config.gcc ) &&
|
||||
cd src &&
|
||||
cp ../patch/gcc/contrib/download_prerequisites gcc/contrib/download_prerequisites &&
|
||||
( cd gcc && ./contrib/download_prerequisites ) &&
|
||||
dynpatch 'gcc/config.sub' '-none)' &&
|
||||
cp ../patch/gcc/gcc/config/jehanne.h gcc/gcc/config &&
|
||||
dynpatch 'gcc/libstdc++-v3/crossconfig.m4' ' \*)' &&
|
||||
cd gcc/libstdc++-v3 && autoconf -i && cd ../../ &&
|
||||
( pwd && grep -q jehanne gcc/libgcc/config.host ||
|
||||
sed -i -f ../patch/gcc/libgcc/config.host.sed gcc/libgcc/config.host
|
||||
) &&
|
||||
dynpatch 'gcc/fixincludes/mkfixinc.sh' 'i\?86-\*-cygwin\*' &&
|
||||
cd $GCC_BUILD_DIR &&
|
||||
$CROSS_DIR/src/gcc/configure --disable-shared --enable-static --target=x86_64-jehanne --prefix=$JEHANNE/hacking/cross/toolchain --with-sysroot=$JEHANNE --enable-languages=c,c++ &&
|
||||
make MAKEINFO=true MAKEINFOHTML=true TEXI2DVI=true TEXI2PDF=true DVIPS=true all-gcc all-target-libgcc &&
|
||||
make MAKEINFO=true MAKEINFOHTML=true TEXI2DVI=true TEXI2PDF=true DVIPS=true install-gcc install-target-libgcc
|
||||
# &&
|
||||
# make MAKEINFO=true MAKEINFOHTML=true TEXI2DVI=true TEXI2PDF=true DVIPS=true all-target-libstdc++-v3 &&
|
||||
# make MAKEINFO=true MAKEINFOHTML=true TEXI2DVI=true TEXI2PDF=true DVIPS=true install-target-libstdc++-v3
|
||||
)
|
||||
failOnError $? "building gcc"
|
||||
|
||||
# add sh
|
||||
ln -sf /bin/bash $JEHANNE/hacking/cross/toolchain/bin/x86_64-jehanne-sh
|
4
cross/patch/MakeNothing.in
Normal file
4
cross/patch/MakeNothing.in
Normal file
@ -0,0 +1,4 @@
|
||||
all:
|
||||
echo "make all does nothing HERE"
|
||||
install:
|
||||
echo "make install does nothing HERE"
|
2
cross/patch/autoconf/build-aux/git-version-gen
Executable file
2
cross/patch/autoconf/build-aux/git-version-gen
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
echo "2.64" | tr -d '\012'
|
7
cross/patch/binutils/bfd/config.bfd
Normal file
7
cross/patch/binutils/bfd/config.bfd
Normal file
@ -0,0 +1,7 @@
|
||||
#ifdef BFD64
|
||||
x86_64-*-jehanne*)
|
||||
targ_defvec=x86_64_elf64_vec
|
||||
targ_selvecs=i386_elf32_vec
|
||||
want64=true
|
||||
;;
|
||||
#endif
|
3
cross/patch/binutils/gas/configure.tgt
Normal file
3
cross/patch/binutils/gas/configure.tgt
Normal file
@ -0,0 +1,3 @@
|
||||
i386-*-jehanne*) fmt=elf em=gnu ;;
|
||||
|
||||
|
8
cross/patch/binutils/ld/Makefile.am
Normal file
8
cross/patch/binutils/ld/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
eelf_i386_jehanne.c: $(srcdir)/emulparams/elf_i386_jehanne.sh \
|
||||
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} elf_i386_jehanne "$(tdir_elf_i386_jehanne)"
|
||||
|
||||
eelf_x86_64_jehanne.c: $(srcdir)/emulparams/elf_x86_64_jehanne.sh \
|
||||
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} elf_x86_64_jehanne "$(tdir_elf_x86_64_jehanne)"
|
||||
|
25
cross/patch/binutils/ld/configure.tgt
Normal file
25
cross/patch/binutils/ld/configure.tgt
Normal file
@ -0,0 +1,25 @@
|
||||
diff --git a/src/binutils/ld/configure.tgt b/src/binutils/ld/configure.tgt
|
||||
index 6b6bbf2..29b5f30 100644
|
||||
--- a/src/binutils/ld/configure.tgt
|
||||
+++ b/src/binutils/ld/configure.tgt
|
||||
@@ -383,6 +383,9 @@ x86_64-*-nacl*) targ_emul=elf32_x86_64_nacl
|
||||
targ_extra_libpath=$targ_extra_emuls
|
||||
tdir_elf_i386_nacl=`echo ${targ_alias} | sed -e 's/x86_64/i386/'`
|
||||
;;
|
||||
+x86_64*-jehanne*) targ_emul=elf_x86_64_jehanne
|
||||
+ targ_extra_emuls="elf_i386_jehanne elf_x86_64 elf_i386"
|
||||
+ ;;
|
||||
i860-*-coff) targ_emul=coff_i860 ;;
|
||||
i860-stardent-sysv4* | i860-stardent-elf*)
|
||||
targ_emul=elf32_i860
|
||||
@@ -852,6 +855,10 @@ ia64-*-aix*)
|
||||
NATIVE_LIB_DIRS='/usr/local/lib /usr/lib/ia64l64 /lib /usr/lib'
|
||||
;;
|
||||
|
||||
+x86_64-*-jehanne*)
|
||||
+ NATIVE_LIB_DIRS='/arch/amd64/lib'
|
||||
+ ;;
|
||||
+
|
||||
sparc*-*-solaris2*)
|
||||
NATIVE_LIB_DIRS='/usr/local/lib /usr/ccs/lib /lib /usr/lib'
|
||||
;;
|
4
cross/patch/binutils/ld/emulparams/elf_i386_jehanne.sh
Normal file
4
cross/patch/binutils/ld/emulparams/elf_i386_jehanne.sh
Normal file
@ -0,0 +1,4 @@
|
||||
. ${srcdir}/emulparams/elf_i386.sh
|
||||
GENERATE_SHLIB_SCRIPT=
|
||||
GENERATE_PIE_SCRIPT=yes
|
||||
ENTRY=_main
|
4
cross/patch/binutils/ld/emulparams/elf_x86_64_jehanne.sh
Normal file
4
cross/patch/binutils/ld/emulparams/elf_x86_64_jehanne.sh
Normal file
@ -0,0 +1,4 @@
|
||||
. ${srcdir}/emulparams/elf_x86_64.sh
|
||||
GENERATE_SHLIB_SCRIPT=
|
||||
GENERATE_PIE_SCRIPT=yes
|
||||
ENTRY=_main
|
3
cross/patch/gcc/config.sub
vendored
Normal file
3
cross/patch/gcc/config.sub
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
-jehanne*)
|
||||
os=-jehanne
|
||||
;;
|
71
cross/patch/gcc/contrib/download_prerequisites
Normal file
71
cross/patch/gcc/contrib/download_prerequisites
Normal file
@ -0,0 +1,71 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Download some prerequisites needed by gcc.
|
||||
# Run this from the top level of the gcc source tree and the gcc
|
||||
# build will do the right thing.
|
||||
#
|
||||
# (C) 2010 Free Software Foundation
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
# If you want to build GCC with the Graphite loop optimizations,
|
||||
# set GRAPHITE_LOOP_OPT=yes to download optional prerequisties
|
||||
# ISL Library and CLooG.
|
||||
GRAPHITE_LOOP_OPT=yes
|
||||
|
||||
if [ ! -e gcc/BASE-VER ] ; then
|
||||
echo "You must run this script in the top level GCC source directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Necessary to build GCC.
|
||||
MPFR=mpfr-2.4.2
|
||||
GMP=gmp-4.3.2
|
||||
MPC=mpc-0.8.1
|
||||
|
||||
if [ ! -d $MPFR ]; then
|
||||
wget http://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/infrastructure/$MPFR.tar.bz2 || exit 1
|
||||
tar xjf $MPFR.tar.bz2 || exit 1
|
||||
ln -sf $MPFR mpfr || exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d $GMP ]; then
|
||||
wget http://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/infrastructure/$GMP.tar.bz2 || exit 1
|
||||
tar xjf $GMP.tar.bz2 || exit 1
|
||||
ln -sf $GMP gmp || exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d $MPC ]; then
|
||||
wget http://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/infrastructure/$MPC.tar.gz || exit 1
|
||||
tar xzf $MPC.tar.gz || exit 1
|
||||
ln -sf $MPC mpc || exit 1
|
||||
fi
|
||||
|
||||
# Necessary to build GCC with the Graphite loop optimizations.
|
||||
if [ "$GRAPHITE_LOOP_OPT" = "yes" ] ; then
|
||||
ISL=isl-0.12.2
|
||||
CLOOG=cloog-0.18.1
|
||||
|
||||
if [ ! -d $ISL ]; then
|
||||
wget http://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/infrastructure/$ISL.tar.bz2 || exit 1
|
||||
tar xjf $ISL.tar.bz2 || exit 1
|
||||
ln -sf $ISL isl || exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d $CLOOG ]; then
|
||||
wget http://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/infrastructure/$CLOOG.tar.gz || exit 1
|
||||
tar xzf $CLOOG.tar.gz || exit 1
|
||||
ln -sf $CLOOG cloog || exit 1
|
||||
fi
|
||||
fi
|
1
cross/patch/gcc/fixincludes/mkfixinc.sh
Normal file
1
cross/patch/gcc/fixincludes/mkfixinc.sh
Normal file
@ -0,0 +1 @@
|
||||
*-jehanne* | \
|
31
cross/patch/gcc/gcc/config.gcc
Normal file
31
cross/patch/gcc/gcc/config.gcc
Normal file
@ -0,0 +1,31 @@
|
||||
diff --git a/src/gcc/gcc/config.gcc b/src/gcc/gcc/config.gcc
|
||||
index f02ddbd..e5ebfe0 100644
|
||||
--- a/src/gcc/gcc/config.gcc
|
||||
+++ b/src/gcc/gcc/config.gcc
|
||||
@@ -862,6 +862,16 @@ case ${target} in
|
||||
tmake_file="$tmake_file vms/t-vmsnative"
|
||||
fi
|
||||
;;
|
||||
+*-*-jehanne*)
|
||||
+ gas=yes
|
||||
+ gnu_ld=yes
|
||||
+ default_use_cxa_atexit=yes
|
||||
+ case $target in
|
||||
+ x86_64-*)
|
||||
+ native_system_header_dir="/arch/amd64/include"
|
||||
+ ;;
|
||||
+ esac
|
||||
+ ;;
|
||||
*-*-vxworks*)
|
||||
tmake_file=t-vxworks
|
||||
xm_defines=POSIX
|
||||
@@ -1347,6 +1357,9 @@ x86_64-*-darwin*)
|
||||
i[34567]86-*-elf*)
|
||||
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h"
|
||||
;;
|
||||
+x86_64-*-jehanne*)
|
||||
+ tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h glibc-stdint.h i386/i386elf.h i386/x86-64.h jehanne.h"
|
||||
+ ;;
|
||||
x86_64-*-elf*)
|
||||
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h"
|
||||
;;
|
88
cross/patch/gcc/gcc/config/jehanne.h
Normal file
88
cross/patch/gcc/gcc/config/jehanne.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This file is part of Jehanne.
|
||||
*
|
||||
* Copyright (C) 2016 Giacomo Tesio <giacomo@tesio.it>
|
||||
*
|
||||
* Jehanne is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2 of the License.
|
||||
*
|
||||
* Jehanne is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#undef TARGET_JEHANNE
|
||||
#define TARGET_JEHANNE 1
|
||||
|
||||
/* Default arguments you want when running x86_64-jehanne-gcc */
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC "-lc"
|
||||
|
||||
#undef STANDARD_STARTFILE_PREFIX
|
||||
#define STANDARD_STARTFILE_PREFIX "/arch/amd64/lib/"
|
||||
|
||||
#undef MD_STARTFILE_PREFIX
|
||||
#define MD_STARTFILE_PREFIX "/arch/amd64/lib/"
|
||||
|
||||
#undef GPLUSPLUS_INCLUDE_DIR
|
||||
#define GPLUSPLUS_INCLUDE_DIR "/posix/include/g++"
|
||||
|
||||
#undef GCC_INCLUDE_DIR
|
||||
#define GCC_INCLUDE_DIR "/posix/include/gcc"
|
||||
|
||||
/* Architecture specific header (u.h) goes here (from config.gcc) */
|
||||
#define ARCH_INCLUDE_DIR NATIVE_SYSTEM_HEADER_DIR
|
||||
|
||||
/* The default include dir is /sys/include but... */
|
||||
#define PORTABLE_INCLUDE_DIR "/sys/include"
|
||||
|
||||
/* ...we have to wrap libc.h and stdio.h with POSIX headers */
|
||||
#define POSIX_INCLUDE_DIR "/sys/include/apw"
|
||||
|
||||
#undef INCLUDE_DEFAULTS
|
||||
#define INCLUDE_DEFAULTS \
|
||||
{ \
|
||||
{ GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 1, 0 }, \
|
||||
{ GCC_INCLUDE_DIR, 0, 0, 0, 1, 0 }, \
|
||||
{ POSIX_INCLUDE_DIR, 0, 0, 0, 1, 0 }, \
|
||||
{ ARCH_INCLUDE_DIR, 0, 0, 0, 1, 0 }, \
|
||||
{ PORTABLE_INCLUDE_DIR, 0, 0, 0, 1, 0 }, \
|
||||
{ ".", 0, 0, 0, 1, 0 }, \
|
||||
{ 0, 0, 0, 0, 0, 0 } \
|
||||
}
|
||||
|
||||
/* Files that are linked before user code.
|
||||
The %s tells gcc to look for these files in the library directory. */
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
|
||||
|
||||
/* Files that are linked after user code. */
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
|
||||
|
||||
/* Don't automatically add extern "C" { } around header files. */
|
||||
#undef NO_IMPLICIT_EXTERN_C
|
||||
#define NO_IMPLICIT_EXTERN_C 1
|
||||
|
||||
/* Fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67132 */
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "unsigned int"
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 32
|
||||
|
||||
#undef LINK_GCC_C_SEQUENCE_SPEC
|
||||
#define LINK_GCC_C_SEQUENCE_SPEC "%G %L"
|
||||
|
||||
/* Additional predefined macros. */
|
||||
#undef TARGET_OS_CPP_BUILTINS
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do { \
|
||||
builtin_define ("__jehanne__"); \
|
||||
builtin_assert ("system=jehanne"); \
|
||||
} while(0);
|
||||
|
4
cross/patch/gcc/libgcc/config.host
Normal file
4
cross/patch/gcc/libgcc/config.host
Normal file
@ -0,0 +1,4 @@
|
||||
x86_64-*-jehanne*)
|
||||
extra_parts="$extra_parts crtbegin.o crtend.o"
|
||||
tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
|
||||
;;
|
3
cross/patch/gcc/libgcc/config.host.sed
Normal file
3
cross/patch/gcc/libgcc/config.host.sed
Normal file
@ -0,0 +1,3 @@
|
||||
/enable_execute_stack=enable-execute-stack-empty.c;/,/Configuration ${host} not supported/{
|
||||
/^case ${host} in$/r ../patch/gcc/libgcc/config.host
|
||||
}
|
6
cross/patch/gcc/libstdc++-v3/crossconfig.m4
Normal file
6
cross/patch/gcc/libstdc++-v3/crossconfig.m4
Normal file
@ -0,0 +1,6 @@
|
||||
*-jehanne*)
|
||||
GLIBCXX_CHECK_COMPILER_FEATURES
|
||||
GLIBCXX_CHECK_LINKER_FEATURES
|
||||
GLIBCXX_CHECK_MATH_SUPPORT
|
||||
GLIBCXX_CHECK_STDLIB_SUPPORT
|
||||
;;
|
7
cross/src/.gitignore
vendored
Normal file
7
cross/src/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
gcc
|
||||
binutils
|
||||
autoconf
|
||||
automake
|
||||
libtool
|
||||
m4
|
||||
build-*
|
62
cross/src/fetch.json
Normal file
62
cross/src/fetch.json
Normal file
@ -0,0 +1,62 @@
|
||||
{
|
||||
"autoconf" : {
|
||||
"Upstream":"https://ftp.gnu.org/gnu/autoconf/autoconf-2.64.tar.bz2",
|
||||
"Digest": {
|
||||
"sha256":"872f4cadf12e7e7c8a2414e047fdff26b517c7f1a977d72433c124d0d3acaa85"
|
||||
},
|
||||
"Compress":"bzip2",
|
||||
"RemovePrefix": true,
|
||||
"Exclude": [
|
||||
]
|
||||
},
|
||||
"m4": {
|
||||
"Upstream":"https://ftp.gnu.org/gnu/m4/m4-1.4.14.tar.bz2",
|
||||
"Digest": {
|
||||
"sha256":"0885ffa93256353a96b1cf0bcbc4d639ed09953b687e6cc412c4048e656f4dd2"
|
||||
},
|
||||
"Compress":"bzip2",
|
||||
"RemovePrefix": true,
|
||||
"Exclude": [
|
||||
]
|
||||
},
|
||||
"automake": {
|
||||
"Upstream":"https://ftp.gnu.org/gnu/automake/automake-1.11.1.tar.bz2",
|
||||
"Digest": {
|
||||
"sha256":"5b159d3c0e0a1f87de71b68bcb9f1a1c49e9e71749c9b723f17e2e1e0295c7ae"
|
||||
},
|
||||
"Compress":"bzip2",
|
||||
"RemovePrefix": true,
|
||||
"Exclude": [
|
||||
]
|
||||
},
|
||||
"libtool": {
|
||||
"Upstream":"https://ftp.gnu.org/gnu/libtool/libtool-2.4.tar.gz",
|
||||
"Digest": {
|
||||
"sha256":"13df57ab63a94e196c5d6e95d64e53262834fe780d5e82c28f177f9f71ddf62e"
|
||||
},
|
||||
"Compress":"gzip",
|
||||
"RemovePrefix": true,
|
||||
"Exclude": [
|
||||
]
|
||||
},
|
||||
"binutils": {
|
||||
"Upstream":"https://ftp.gnu.org/gnu/binutils/binutils-2.26.tar.bz2",
|
||||
"Digest": {
|
||||
"sha256":"c2ace41809542f5237afc7e3b8f32bb92bc7bc53c6232a84463c423b0714ecd9"
|
||||
},
|
||||
"Compress":"bzip2",
|
||||
"RemovePrefix": true,
|
||||
"Exclude": [
|
||||
]
|
||||
},
|
||||
"gcc": {
|
||||
"Upstream":"https://ftp.gnu.org/gnu/gcc/gcc-4.9.4/gcc-4.9.4.tar.bz2",
|
||||
"Digest": {
|
||||
"sha256":"6c11d292cd01b294f9f84c9a59c230d80e9e4a47e5c6355f046bb36d4f358092"
|
||||
},
|
||||
"Compress":"bzip2",
|
||||
"RemovePrefix": true,
|
||||
"Exclude": [
|
||||
]
|
||||
}
|
||||
}
|
2
cross/tmp/.gitignore
vendored
Normal file
2
cross/tmp/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
3
cross/toolchain/.gitignore
vendored
Normal file
3
cross/toolchain/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*
|
||||
!.gitignore
|
||||
|
@ -1,6 +1,10 @@
|
||||
#!/bin/bash
|
||||
export JEHANNE=`git rev-parse --show-toplevel`
|
||||
export PATH="$JEHANNE/hacking/bin:$PATH"
|
||||
export PATH="$JEHANNE/hacking/third_party/src/github.com/JehanneOS/devtools-kencc/bin:$PATH"
|
||||
export PATH="$JEHANNE/hacking/cross/toolchain/bin:$PATH"
|
||||
export ARCH=amd64
|
||||
|
||||
export TOOLPREFIX=x86_64-jehanne-
|
||||
|
||||
bash --rcfile <(cat ~/.bashrc; echo 'PS1="JehanneDEV $PS1"')
|
||||
|
50
disk-boot-update.sh
Executable file
50
disk-boot-update.sh
Executable file
@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$JEHANNE" = "" ]; then
|
||||
echo $0 requires the shell started by ./hacking/devshell.sh
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$SYSLINUXBIOS" == "" ]; then
|
||||
export SYSLINUXBIOS=/usr/lib/syslinux/modules/bios/ # GNU/Linux Debian way
|
||||
fi
|
||||
if [ ! -d "$SYSLINUXBIOS" ]; then
|
||||
echo 'Missing $SYSLINUXBIOS: install syslinux-utils or set it to the proper path.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d $JEHANNE/hacking/disk-setup/bios/ ]; then
|
||||
rm $JEHANNE/hacking/disk-setup/bios/*
|
||||
else
|
||||
mkdir $JEHANNE/hacking/disk-setup/bios/
|
||||
fi
|
||||
cp $SYSLINUXBIOS/lib* $JEHANNE/hacking/disk-setup/bios/
|
||||
cp $SYSLINUXBIOS/elf.c32 $JEHANNE/hacking/disk-setup/bios/
|
||||
cp $SYSLINUXBIOS/mboot.c32 $JEHANNE/hacking/disk-setup/bios/
|
||||
cp $SYSLINUXBIOS/menu.c32 $JEHANNE/hacking/disk-setup/bios/
|
||||
|
||||
# Locate the disk
|
||||
if [ "$DISK" == "" ]; then
|
||||
export DISK=$JEHANNE/hacking/sample-disk.img
|
||||
fi
|
||||
|
||||
if [ ! -b $DISK ] && [ ! -f $DISK ]; then
|
||||
echo "Cannot find DISK to update ($DISK): set the DISK variable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export KERNEL=$JEHANNE/hacking/bin/workhorse.32bit
|
||||
export KERNDIR=$JEHANNE/hacking/bin/
|
||||
|
||||
# install everything
|
||||
cat << EOF | runqemu
|
||||
disk/fdisk -p /dev/sdE0/data >> /dev/sdE0/ctl
|
||||
disk/prep -p /dev/sdE0/plan9 >> /dev/sdE0/ctl
|
||||
cat /dev/sdE0/ctl
|
||||
|
||||
disk/format -d /dev/sdE0/dos /hacking/disk-setup/syslinux.cfg /hacking/disk-setup/bios/* /arch/amd64/kern/initrd /arch/amd64/kern/jehanne.32bit
|
||||
|
||||
EOF
|
||||
syslinux --offset $((2048*512)) $DISK
|
||||
dd bs=440 count=1 conv=notrunc if=/usr/lib/syslinux/mbr/mbr.bin of=$DISK
|
||||
|
124
disk-create.sh
Executable file
124
disk-create.sh
Executable file
@ -0,0 +1,124 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$JEHANNE" = "" ]; then
|
||||
echo $0 requires the shell started by ./hacking/devshell.sh
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$SYSLINUXBIOS" == "" ]; then
|
||||
export SYSLINUXBIOS=/usr/lib/syslinux/modules/bios/ # GNU/Linux Debian way
|
||||
fi
|
||||
if [ ! -d "$SYSLINUXBIOS" ]; then
|
||||
echo 'Missing $SYSLINUXBIOS: install syslinux-utils or set it to the proper path.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d $JEHANNE/hacking/disk-setup/bios/ ]; then
|
||||
rm $JEHANNE/hacking/disk-setup/bios/*
|
||||
else
|
||||
mkdir $JEHANNE/hacking/disk-setup/bios/
|
||||
fi
|
||||
cp $SYSLINUXBIOS/lib* $JEHANNE/hacking/disk-setup/bios/
|
||||
cp $SYSLINUXBIOS/elf.c32 $JEHANNE/hacking/disk-setup/bios/
|
||||
cp $SYSLINUXBIOS/mboot.c32 $JEHANNE/hacking/disk-setup/bios/
|
||||
cp $SYSLINUXBIOS/menu.c32 $JEHANNE/hacking/disk-setup/bios/
|
||||
|
||||
# Create the data disk
|
||||
if [ "$DISK" == "" ]; then
|
||||
export DISK=$JEHANNE/hacking/sample-disk.img
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -f $DISK ]; then
|
||||
qemu-img create $DISK 4G
|
||||
|
||||
sed -e 's/^\s*\([\+0-9a-zA-Z]*\)[ ].*/\1/' << EOF | /sbin/fdisk $DISK
|
||||
o #clear partition table
|
||||
n #new partition
|
||||
p #primary partition
|
||||
1 #partition 1
|
||||
#start at beginning of disk
|
||||
+40M #reserve 40 megabytes
|
||||
t #change type
|
||||
c #W95 FAT32 (LBA)
|
||||
a #make it bootable
|
||||
n #new partition
|
||||
p #primary partition
|
||||
2 #partition 2
|
||||
#start at first free sector
|
||||
#end at the end of disk
|
||||
t #change type
|
||||
2 #partition 2
|
||||
39 #Plan 9
|
||||
p #print partition table
|
||||
w #write partition table
|
||||
q #quit
|
||||
EOF
|
||||
|
||||
export KERNEL=$JEHANNE/hacking/bin/workhorse.32bit
|
||||
export KERNDIR=$JEHANNE/hacking/bin/
|
||||
|
||||
# install everything
|
||||
cat << EOF | runqemu
|
||||
disk/fdisk -p /dev/sdE0/data >> /dev/sdE0/ctl
|
||||
disk/prep -w -a nvram -a fs /dev/sdE0/plan9
|
||||
disk/prep -p /dev/sdE0/plan9 >> /dev/sdE0/ctl
|
||||
cat /dev/sdE0/ctl
|
||||
|
||||
disk/format -d /dev/sdE0/dos /hacking/disk-setup/syslinux.cfg /hacking/disk-setup/bios/* /arch/amd64/kern/initrd /arch/amd64/kern/jehanne.32bit
|
||||
|
||||
dd -if /hacking/nvram -of /dev/sdE0/nvram
|
||||
|
||||
hjfs -n hjfs -Srf /dev/sdE0/fs
|
||||
/hacking/disk-setup/configure-hjfs >>/srv/hjfs.cmd
|
||||
hjfs -n hjfs -Sf /dev/sdE0/fs
|
||||
mount -c /srv/hjfs /n/newfs
|
||||
cd /n/newfs
|
||||
cd cfg
|
||||
dircp /root/cfg .
|
||||
cd /n/newfs
|
||||
mkdir arch
|
||||
cd arch
|
||||
dircp /root/arch .
|
||||
cd /n/newfs
|
||||
mkdir lib
|
||||
cd lib
|
||||
dircp /root/lib .
|
||||
cd /n/newfs
|
||||
mkdir mnt
|
||||
cd mnt
|
||||
mkdir temp
|
||||
mkdir term
|
||||
mkdir acme
|
||||
mkdir wsys
|
||||
cd /n/newfs
|
||||
mkdir usr
|
||||
cd usr
|
||||
dircp /root/usr .
|
||||
cd /n/newfs
|
||||
mkdir sys
|
||||
cd sys
|
||||
mkdir include
|
||||
mkdir src
|
||||
dircp /root/sys/src src/
|
||||
dircp /root/sys/include include/
|
||||
mkdir log
|
||||
cd /n/newfs
|
||||
mkdir qa
|
||||
cd qa
|
||||
dircp /root/qa .
|
||||
cd /n/newfs
|
||||
lc
|
||||
unmount /n/newfs
|
||||
echo df >> /srv/hjfs.cmd
|
||||
echo sync >> /srv/hjfs.cmd
|
||||
sleep 60
|
||||
echo halt >> /srv/hjfs.cmd
|
||||
sleep 20
|
||||
EOF
|
||||
syslinux --offset $((2048*512)) $DISK
|
||||
dd bs=440 count=1 conv=notrunc if=/usr/lib/syslinux/mbr/mbr.bin of=$DISK
|
||||
else
|
||||
echo Root disk already exists: $DISK
|
||||
fi
|
||||
|
48
disk-get.sh
Executable file
48
disk-get.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$JEHANNE" = "" ]; then
|
||||
echo $0 requires the shell started by ./hacking/devshell.sh
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$DISK" == "" ]; then
|
||||
export DISK=$JEHANNE/hacking/sample-disk.img
|
||||
fi
|
||||
|
||||
if [ ! -f $DISK ] && [ ! -b $DISK ]; then
|
||||
echo "Cannot find DISK to update ($DISK): set the DISK variable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export KERNEL=$JEHANNE/hacking/bin/workhorse.32bit
|
||||
export KERNDIR=$JEHANNE/hacking/bin/
|
||||
|
||||
# install everything
|
||||
cat > $JEHANNE/tmp/files.list << EOF
|
||||
disk/fdisk -p /dev/sdE0/data >> /dev/sdE0/ctl
|
||||
disk/prep -p /dev/sdE0/plan9 >> /dev/sdE0/ctl
|
||||
cat /dev/sdE0/ctl
|
||||
|
||||
hjfs -n hjfs -Sf /dev/sdE0/fs
|
||||
mount -c /srv/hjfs /n/newfs
|
||||
|
||||
EOF
|
||||
|
||||
for var in "$@"
|
||||
do
|
||||
echo "cp /n/newfs/$var /tmp/$var" >> $JEHANNE/tmp/files.list
|
||||
done
|
||||
|
||||
cat >> $JEHANNE/tmp/files.list << EOF
|
||||
|
||||
unmount /n/newfs
|
||||
echo df >> /srv/hjfs.cmd
|
||||
echo sync >> /srv/hjfs.cmd
|
||||
sleep 60
|
||||
echo halt >> /srv/hjfs.cmd
|
||||
sleep 20
|
||||
|
||||
EOF
|
||||
|
||||
cat $JEHANNE/tmp/files.list | runqemu
|
||||
rm $JEHANNE/tmp/files.list
|
15
disk-setup/configure-hjfs
Executable file
15
disk-setup/configure-hjfs
Executable file
@ -0,0 +1,15 @@
|
||||
#!/cmd/rc
|
||||
|
||||
echo echo on
|
||||
echo create /dist sys sys 775 d
|
||||
echo create /tmp sys sys 775 d
|
||||
echo create /usr sys sys 775 d
|
||||
echo newuser glenda
|
||||
echo newuser adm +glenda
|
||||
echo newuser sys +glenda
|
||||
echo newuser upas +glenda
|
||||
echo sync
|
||||
echo echo off
|
||||
echo halt
|
||||
sleep 2
|
||||
|
6
disk-setup/flproto
Normal file
6
disk-setup/flproto
Normal file
@ -0,0 +1,6 @@
|
||||
srv -p fscons
|
||||
srv fossil
|
||||
fsys main config /dev/sdE1/fossil
|
||||
fsys main open -AWP
|
||||
fsys main
|
||||
|
19
disk-setup/syslinux.cfg
Normal file
19
disk-setup/syslinux.cfg
Normal file
@ -0,0 +1,19 @@
|
||||
DEFAULT menu.c32
|
||||
|
||||
# to force boot jump to a rc shell (without executing /lib/namespace, thus no command in /cmd), add
|
||||
# init='/arch/amd64/cmd/rc -i'
|
||||
# to the APPEND line (before ---)
|
||||
# NOTE: double quotes won't work, only singe quotes are accepted
|
||||
|
||||
LABEL FromUSB
|
||||
KERNEL mboot.c32
|
||||
APPEND jehanne.32bit nobootprompt=local!/shr/usb/sdU67d95 maxcores=1024 auth=10.0.0.203 nvram=/shr/usb/sdU67d95/nvram nvrlen=512 nvroff=0 --- initrd
|
||||
|
||||
LABEL FromAHCI
|
||||
KERNEL mboot.c32
|
||||
APPEND jehanne.32bit nobootprompt=local!#S/sdE0 maxcores=1024 auth=10.0.0.1 nvram=#S/sdE0/nvram nvrlen=512 nvroff=0 --- initrd
|
||||
|
||||
LABEL FromIDE
|
||||
KERNEL mboot.c32
|
||||
APPEND jehanne.32bit nobootprompt=local!#S/sdC0 maxcores=1024 auth=10.0.0.1 nvram=#S/sdC0/nvram nvrlen=512 nvroff=0 --- initrd
|
||||
|
4
disk-setup/venti.conf
Normal file
4
disk-setup/venti.conf
Normal file
@ -0,0 +1,4 @@
|
||||
index main
|
||||
isect /dev/sdE1/isect
|
||||
arenas /dev/sdE1/arenas
|
||||
|
48
disk-update.sh
Executable file
48
disk-update.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$JEHANNE" = "" ]; then
|
||||
echo $0 requires the shell started by ./hacking/devshell.sh
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$DISK" == "" ]; then
|
||||
export DISK=$JEHANNE/hacking/sample-disk.img
|
||||
fi
|
||||
|
||||
if [ ! -f $DISK ] && [ ! -b $DISK ]; then
|
||||
echo "Cannot find DISK to update ($DISK): set the DISK variable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export KERNEL=$JEHANNE/hacking/bin/workhorse.32bit
|
||||
export KERNDIR=$JEHANNE/hacking/bin/
|
||||
|
||||
# install everything
|
||||
cat > $JEHANNE/tmp/files.list << EOF
|
||||
disk/fdisk -p /dev/sdE0/data >> /dev/sdE0/ctl
|
||||
disk/prep -p /dev/sdE0/plan9 >> /dev/sdE0/ctl
|
||||
cat /dev/sdE0/ctl
|
||||
|
||||
hjfs -n hjfs -Sf /dev/sdE0/fs
|
||||
mount -c /srv/hjfs /n/newfs
|
||||
|
||||
EOF
|
||||
|
||||
for var in "$@"
|
||||
do
|
||||
echo "cp /$var /n/newfs/$var" >> $JEHANNE/tmp/files.list
|
||||
done
|
||||
|
||||
cat >> $JEHANNE/tmp/files.list << EOF
|
||||
|
||||
unmount /n/newfs
|
||||
echo df >> /srv/hjfs.cmd
|
||||
echo sync >> /srv/hjfs.cmd
|
||||
sleep 60
|
||||
echo halt >> /srv/hjfs.cmd
|
||||
sleep 20
|
||||
|
||||
EOF
|
||||
|
||||
cat $JEHANNE/tmp/files.list | runqemu
|
||||
rm $JEHANNE/tmp/files.list
|
7
drawterm.sh
Executable file
7
drawterm.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$JEHANNE" = "" ]; then
|
||||
echo ./hacking/drawterm.sh requires the shell started by ./hacking/devshell.sh
|
||||
exit 1
|
||||
fi
|
||||
drawterm -a 127.0.0.1 -c 127.0.0.1 -u glenda
|
290
gdbinit
Normal file
290
gdbinit
Normal file
@ -0,0 +1,290 @@
|
||||
set pagination off
|
||||
set logging file ../qemu-gdb.log
|
||||
set logging overwrite on
|
||||
set logging on
|
||||
|
||||
define log_mach_proc
|
||||
if up != 0
|
||||
printf "%s %d ", up->text, up->pid
|
||||
end
|
||||
if m != 0
|
||||
printf "(mach %d) ", m->machno
|
||||
end
|
||||
end
|
||||
|
||||
define log_syscall
|
||||
log_mach_proc
|
||||
printf "\n"
|
||||
c
|
||||
end
|
||||
|
||||
define log_syscalls
|
||||
|
||||
# sysbind
|
||||
b ../port/sysfile.c:1167
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# syschdir
|
||||
b ../port/sysfile.c:1027
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysclose
|
||||
b ../port/sysfile.c:375
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# syscreate
|
||||
b ../port/sysfile.c:1263
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysdup
|
||||
b ../port/sysfile.c:263
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysfd2path
|
||||
b ../port/sysfile.c:191
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysfstat
|
||||
b ../port/sysfile.c:999
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysfwstat
|
||||
b ../port/sysfile.c:1371
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysmount
|
||||
b ../port/sysfile.c:1192
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysopen
|
||||
b ../port/sysfile.c:311
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# syspipe
|
||||
b ../port/sysfile.c:214
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# syspread
|
||||
b ../port/sysfile.c:787
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# syspwrite
|
||||
b ../port/sysfile.c:857
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysremove
|
||||
b ../port/sysfile.c:1293
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysseek
|
||||
b ../port/sysfile.c:929
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysunmount
|
||||
b ../port/sysfile.c:1210
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysfversion
|
||||
b ../port/sysauth.c:50
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysfauth
|
||||
b ../port/sysauth.c:83
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysrfork
|
||||
b ../port/sysproc.c:36
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysalarm
|
||||
b ../port/sysproc.c:656
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysawake
|
||||
b ../port/sysproc.c:682
|
||||
commands
|
||||
printf "sys->ticks %lld ms %lld \n", sys->ticks, ms
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysawait
|
||||
b ../port/sysproc.c:729
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# syserrstr
|
||||
b ../port/sysproc.c:791
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysnotify
|
||||
b ../port/sysproc.c:809
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysexec
|
||||
b ../port/sysproc.c:284
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysexits
|
||||
b ../port/sysproc.c:702
|
||||
commands
|
||||
if status != 0
|
||||
printf "status: %s", status
|
||||
else
|
||||
printf "status: (nil)"
|
||||
end
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysnoted
|
||||
b ../port/sysproc.c:840
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysrendezvous
|
||||
b ../port/sysproc.c:861
|
||||
commands
|
||||
printf "tag %llu rendval %llu\n", tag, rendval
|
||||
printf "sys->ticks %lld lastWakeup %lld pendingWakeup %lld \n", sys->ticks, up->lastWakeup, up->pendingWakeup
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysnotify
|
||||
b ../port/sysproc.c:820
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysnsec
|
||||
b ../port/sysproc.c:1233
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# syssemacquire
|
||||
b ../port/sysproc.c:1167
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# syssemrelease
|
||||
b ../port/sysproc.c:1222
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# syssleep
|
||||
b ../port/sysproc.c:640
|
||||
commands
|
||||
printf "ms %lld\n", ms
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# systsemacquire
|
||||
b ../port/sysproc.c:1193
|
||||
commands
|
||||
log_syscall
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
define debug_awake
|
||||
# awakekproc
|
||||
b ../port/awake.c:139
|
||||
commands
|
||||
printf "%s %d ", p->text, p->pid
|
||||
printf "p->state %d p->lastWakeup %lld toAwake->time %d \n", p->state, p->lastWakeup, toAwake->time
|
||||
c
|
||||
end
|
||||
|
||||
# sysawake
|
||||
b ../port/sysproc.c:682
|
||||
commands
|
||||
printf "sys->ticks %lld ms %lld \n", sys->ticks, ms
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysrendezvous
|
||||
b ../port/sysproc.c:861
|
||||
commands
|
||||
printf "ENTER: \n tag %llu rendval %llu\n", tag, rendval
|
||||
printf "sys->ticks %lld lastWakeup %lld pendingWakeup %lld \n", sys->ticks, up->lastWakeup, up->pendingWakeup
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysrendezvous
|
||||
b ../port/sysproc.c:879
|
||||
commands
|
||||
printf "EXIT on match: \n tag %llu rendval %llu\n", tag, rendval
|
||||
printf "sys->ticks %lld lastWakeup %lld pendingWakeup %lld \n", sys->ticks, up->lastWakeup, up->pendingWakeup
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysrendezvous
|
||||
b ../port/sysproc.c:886
|
||||
commands
|
||||
printf "EXIT on awaken: \n tag %llu rendval %llu\n", tag, rendval
|
||||
printf "sys->ticks %lld lastWakeup %lld pendingWakeup %lld \n", sys->ticks, up->lastWakeup, up->pendingWakeup
|
||||
log_syscall
|
||||
end
|
||||
|
||||
# sysrendezvous
|
||||
b ../port/sysproc.c:902
|
||||
commands
|
||||
printf "EXIT after wait: \n tag %llu rendval %llu\n", tag, rendval
|
||||
printf "sys->ticks %lld lastWakeup %lld pendingWakeup %lld \n", sys->ticks, up->lastWakeup, up->pendingWakeup
|
||||
log_syscall
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#log_syscalls
|
||||
|
||||
|
74
runDisk.sh
Executable file
74
runDisk.sh
Executable file
@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
|
||||
export SDL_VIDEO_X11_DGAMOUSE=0 # see https://wiki.archlinux.org/index.php/QEMU#Mouse_cursor_is_jittery_or_erratic
|
||||
|
||||
if [ "$JEHANNE" = "" ]; then
|
||||
echo $0 requires the shell started by ./hacking/devshell.sh
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trap : 2
|
||||
|
||||
export machineflag=pc
|
||||
if [ "$(uname)" = "Linux" ] && [ -e /dev/kvm ]; then
|
||||
export kvmflag='-enable-kvm'
|
||||
export machineflag='pc,accel=kvm'
|
||||
if [ ! -w /dev/kvm ]; then
|
||||
# we don't have access as a regular user
|
||||
export kvmdo=sudo
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "" ]; then
|
||||
if [ "$DISK" = "" ]; then
|
||||
if [ -f $JEHANNE/hacking/sample-disk.img ]; then
|
||||
export DISK=$JEHANNE/hacking/sample-disk.img
|
||||
else
|
||||
echo No disk image provided: usage: $0 path/to/disk
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo No disk image provided: usage: $0 path/to/disk
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
export DISK="$1"
|
||||
fi
|
||||
|
||||
case "$DISK" in
|
||||
*:*)
|
||||
bootDisk="-usb -usbdevice host:$DISK"
|
||||
;;
|
||||
*)
|
||||
bootDisk="-drive if=none,id=usbstick,file=$DISK -usb -readconfig /usr/share/doc/qemu-system-x86/common/ich9-ehci-uhci.cfg -device usb-host,bus=usb-bus.0,hostbus=3,hostport=1 -device usb-host,bus=usb-bus.0,hostbus=3,hostport=1 -device usb-storage,bus=ehci.0,drive=usbstick "
|
||||
;;
|
||||
esac
|
||||
#bootDisk="-device ahci,id=ahci -drive id=boot,file=$DISK,index=0,cache=writeback,if=none -device ide-drive,drive=boot,bus=ahci.0"
|
||||
bootDisk="-global ide-drive.physical_block_size=4096 -drive file=$DISK,if=ide,index=0,media=disk"
|
||||
|
||||
cd $JEHANNE/arch/$ARCH/kern/
|
||||
read -r cmd <<EOF
|
||||
$kvmdo qemu-system-x86_64 -s -cpu Haswell -smp 2 -m 2048 $kvmflag \
|
||||
-serial stdio \
|
||||
--machine $machineflag \
|
||||
$bootDisk \
|
||||
-net nic,model=rtl8139 \
|
||||
-net user,hostfwd=tcp::5555-:1522 \
|
||||
-net dump,file=/tmp/vm0.pcap \
|
||||
-redir tcp:9999::9 \
|
||||
-redir tcp:17010::17010 \
|
||||
-redir tcp:17013::17013
|
||||
EOF
|
||||
|
||||
# To enable qemu log:
|
||||
#-no-reboot -D $JEHANNE/../qemu.log -d int,cpu_reset,in_asm \
|
||||
|
||||
# To wait for a gdb connection prepend to -append "waitgdb"
|
||||
# then from gdb:
|
||||
# (gdb) target remote :1234
|
||||
# (gdb) p at=1
|
||||
# now you can set your breakpoints and continue
|
||||
|
||||
echo $cmd
|
||||
eval $cmd
|
||||
|
42
runOver9P.sh
42
runOver9P.sh
@ -1,5 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
export SDL_VIDEO_X11_DGAMOUSE=0 # see https://wiki.archlinux.org/index.php/QEMU#Mouse_cursor_is_jittery_or_erratic
|
||||
|
||||
if [ "$JEHANNE" = "" ]; then
|
||||
echo $0 requires the shell started by ./hacking/devshell.sh
|
||||
exit 1
|
||||
fi
|
||||
if [ "$KERNEL" = "" ]; then
|
||||
KERNEL="jehanne.32bit"
|
||||
fi
|
||||
|
||||
trap : 2
|
||||
|
||||
$JEHANNE/hacking/bin/ufs -root=$JEHANNE &
|
||||
@ -15,21 +25,45 @@ if [ "$(uname)" = "Linux" ] && [ -e /dev/kvm ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
export NVRAM=/boot/nvram
|
||||
export FS="nobootprompt=tcp fs=10.0.2.2 auth=10.0.2.2"
|
||||
|
||||
if [ "$DISK" = "" ]; then
|
||||
export DISK=$JEHANNE/hacking/sample-disk.img
|
||||
fi
|
||||
|
||||
if [ -f $DISK ]; then
|
||||
usbDev="-drive if=none,id=usbstick,file=$DISK -usb -device nec-usb-xhci,id=xhci -device usb-storage,bus=xhci.0,drive=usbstick"
|
||||
usbDev="-drive if=none,id=usbstick,file=$DISK -usb -readconfig /usr/share/doc/qemu-system-x86/common/ich9-ehci-uhci.cfg -device usb-host,bus=usb-bus.0,hostbus=3,hostport=1 -device usb-host,bus=usb-bus.0,hostbus=3,hostport=1 -device usb-storage,bus=ehci.0,drive=usbstick "
|
||||
fi
|
||||
|
||||
cd $JEHANNE/arch/$ARCH/kern/
|
||||
read -r cmd <<EOF
|
||||
$kvmdo qemu-system-x86_64 -s -cpu Opteron_G1 -smp 1 -m 2048 $kvmflag \
|
||||
-serial stdio \
|
||||
$kvmdo qemu-system-x86_64 -s -cpu Haswell -smp 4 -m 2048 $kvmflag \
|
||||
-no-reboot -serial mon:stdio \
|
||||
--machine $machineflag \
|
||||
$bootDisk \
|
||||
-net nic,model=rtl8139 \
|
||||
-net user,hostfwd=tcp::5555-:1522 \
|
||||
-net dump,file=/tmp/vm0.pcap \
|
||||
-redir tcp:9999::9 \
|
||||
-redir tcp:17010::17010 \
|
||||
-redir tcp:17013::17013 \
|
||||
-append "nobootprompt=tcp maxcores=1024 fs=10.0.2.2 auth=10.0.2.2 nvram=/boot/nvram nvrlen=512 nvroff=0" \
|
||||
-kernel jehanne.32bit $*
|
||||
$usbDev \
|
||||
-append "maxcores=1024 nvram=$NVRAM nvrlen=512 nvroff=0 $FS $KAPPEND" \
|
||||
-initrd ./initrd \
|
||||
-kernel $KERNEL $*
|
||||
EOF
|
||||
|
||||
# To enable qemu log:
|
||||
#-D $JEHANNE/../qemu.log -d int,cpu_reset,in_asm \
|
||||
|
||||
# To wait for a gdb connection prepend to -append "waitgdb"
|
||||
# then from gdb:
|
||||
# (gdb) target remote :1234
|
||||
# (gdb) p at=1
|
||||
# now you can set your breakpoints and continue
|
||||
|
||||
echo $cmd
|
||||
eval $cmd
|
||||
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -43,6 +44,7 @@ type kernconfig struct {
|
||||
}
|
||||
|
||||
type kernel struct {
|
||||
CodeFile string
|
||||
Systab string
|
||||
Config kernconfig
|
||||
Ramfiles map[string]string
|
||||
@ -89,9 +91,9 @@ func (bf *buildfile) UnmarshalJSON(s []byte) error {
|
||||
b.Projects = adjust(b.Projects)
|
||||
b.Libs = adjust(b.Libs)
|
||||
b.Cflags = adjust(b.Cflags)
|
||||
b.SourceFiles = adjust(b.SourceFiles)
|
||||
b.SourceFilesCmd = adjust(b.SourceFilesCmd)
|
||||
b.ObjectFiles = adjust(b.ObjectFiles)
|
||||
b.SourceFiles = b.SourceFiles
|
||||
b.SourceFilesCmd = b.SourceFilesCmd
|
||||
b.ObjectFiles = b.ObjectFiles
|
||||
b.Include = adjust(b.Include)
|
||||
b.Install = fromRoot(b.Install)
|
||||
for i, e := range b.Env {
|
||||
@ -138,6 +140,15 @@ func failOn(err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func isValueInList(value string, list []string) bool {
|
||||
for _, v := range list {
|
||||
if v == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func adjust(s []string) []string {
|
||||
for i, v := range s {
|
||||
s[i] = fromRoot(v)
|
||||
@ -145,6 +156,18 @@ func adjust(s []string) []string {
|
||||
return s
|
||||
}
|
||||
|
||||
func buildEnv(b *build) func(string) string{
|
||||
return func(v string) string {
|
||||
search := v + "="
|
||||
for _, s := range b.Env {
|
||||
if strings.Index(s, search) == 0 {
|
||||
return strings.Replace(s, search, "", 1)
|
||||
}
|
||||
}
|
||||
return os.Getenv(v)
|
||||
}
|
||||
}
|
||||
|
||||
// return the given absolute path as an absolute path rooted at the jehanne tree.
|
||||
func fromRoot(p string) string {
|
||||
p = os.ExpandEnv(p)
|
||||
@ -179,6 +202,40 @@ func sh(cmd *exec.Cmd) {
|
||||
failOn(shell.Run())
|
||||
}
|
||||
|
||||
func mergeKernel(k *kernel, defaults *kernel) *kernel {
|
||||
if k == nil {
|
||||
return defaults
|
||||
}
|
||||
if defaults == nil {
|
||||
return k
|
||||
}
|
||||
|
||||
// The custom kernel Code will be added after the default from includes
|
||||
// so that it has a chance to change de default behaviour.
|
||||
k.Config.Code = append(defaults.Config.Code, k.Config.Code...)
|
||||
|
||||
k.Config.Dev = append(k.Config.Dev, defaults.Config.Dev...)
|
||||
k.Config.Ip = append(k.Config.Ip, defaults.Config.Ip...)
|
||||
k.Config.Link = append(k.Config.Link, defaults.Config.Link...)
|
||||
k.Config.Sd = append(k.Config.Sd, defaults.Config.Sd...)
|
||||
k.Config.Uart = append(k.Config.Uart, defaults.Config.Uart...)
|
||||
k.Config.VGA = append(k.Config.VGA, defaults.Config.VGA...)
|
||||
|
||||
if k.CodeFile == "" {
|
||||
k.CodeFile = defaults.CodeFile
|
||||
}
|
||||
if k.Systab == "" {
|
||||
k.Systab = defaults.Systab
|
||||
}
|
||||
for name, path := range defaults.Ramfiles {
|
||||
if _, ok := k.Ramfiles[name]; ok == false {
|
||||
k.Ramfiles[name] = path
|
||||
}
|
||||
}
|
||||
|
||||
return k
|
||||
}
|
||||
|
||||
func include(f string, b *build) {
|
||||
if b.jsons[f] {
|
||||
return
|
||||
@ -203,6 +260,7 @@ func include(f string, b *build) {
|
||||
b.SourceFilesCmd = append(b.SourceFilesCmd, build.SourceFilesCmd...)
|
||||
b.Program += build.Program
|
||||
b.Library += build.Library
|
||||
b.Kernel = mergeKernel(b.Kernel, build.Kernel)
|
||||
if build.Install != "" {
|
||||
if b.Install != "" {
|
||||
log.Fatalf("In file %s (target %s) included by %s (target %s): redefined Install.", f, n, build.path, build.name)
|
||||
@ -244,7 +302,16 @@ func process(f string, r []*regexp.Regexp) []build {
|
||||
d, err := ioutil.ReadFile(f)
|
||||
failOn(err)
|
||||
failOn(json.Unmarshal(d, &builds))
|
||||
for n, build := range builds {
|
||||
|
||||
// Sort keys alphabetically (GoLang does not preserve the JSON order)
|
||||
var keys []string
|
||||
for n := range builds {
|
||||
keys = append(keys, n)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, n := range keys {
|
||||
build := builds[n]
|
||||
build.name = n
|
||||
build.jsons = make(map[string]bool)
|
||||
skip := true
|
||||
@ -281,8 +348,15 @@ func buildkernel(b *build) {
|
||||
if b.Kernel == nil {
|
||||
return
|
||||
}
|
||||
envFunc := buildEnv(b)
|
||||
for name, path := range b.Kernel.Ramfiles {
|
||||
b.Kernel.Ramfiles[name] = os.Expand(path, envFunc);
|
||||
}
|
||||
codebuf := confcode(b.path, b.Kernel)
|
||||
failOn(ioutil.WriteFile(b.name+".c", codebuf, 0666))
|
||||
if b.Kernel.CodeFile == "" {
|
||||
log.Fatalf("Missing Kernel.CodeFile in %v\n", b.path)
|
||||
}
|
||||
failOn(ioutil.WriteFile(b.Kernel.CodeFile, codebuf, 0666))
|
||||
}
|
||||
|
||||
func wrapInQuote(args []string) []string {
|
||||
@ -297,24 +371,57 @@ func wrapInQuote(args []string) []string {
|
||||
return res
|
||||
}
|
||||
|
||||
func convertLibPathsToArgs(b *build) []string {
|
||||
libLocations := make([]string, 0)
|
||||
args := make([]string, 0)
|
||||
defaultLibLocation := fromRoot("/arch/$ARCH/lib")
|
||||
for _, lib := range b.Libs {
|
||||
ldir := filepath.Dir(lib)
|
||||
if ldir != defaultLibLocation {
|
||||
if !isValueInList(ldir, libLocations) {
|
||||
libLocations = append(libLocations, ldir)
|
||||
args = append(args, "-L", ldir)
|
||||
}
|
||||
}
|
||||
lib = strings.Replace(lib, ldir + "/lib", "-l", 1)
|
||||
lib = strings.Replace(lib, ".a", "", 1)
|
||||
args = append(args, lib)
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
func compile(b *build) {
|
||||
log.Printf("Building %s\n", b.name)
|
||||
// N.B. Plan 9 has a very well defined include structure, just three things:
|
||||
// /amd64/include, /sys/include, .
|
||||
args := b.Cflags
|
||||
args := b.SourceFiles
|
||||
args = append(args, b.Cflags...)
|
||||
if !isValueInList("-c", b.Cflags) {
|
||||
args = append(args, convertLibPathsToArgs(b)...)
|
||||
args = append(args, b.Oflags...)
|
||||
}
|
||||
if len(b.SourceFilesCmd) > 0 {
|
||||
for _, i := range b.SourceFilesCmd {
|
||||
cmd := exec.Command(tools["cc"], append(args, i)...)
|
||||
largs := make([]string, 3)
|
||||
largs[0] = i
|
||||
largs[1] = "-o"
|
||||
largs[2] = strings.Replace(filepath.Base(i), filepath.Ext(i), "", 1)
|
||||
cmd := exec.Command(tools["cc"], append(largs, args...)...)
|
||||
run(b, *shellhack, cmd)
|
||||
}
|
||||
return
|
||||
}
|
||||
args = append(args, b.SourceFiles...)
|
||||
if !isValueInList("-c", b.Cflags) {
|
||||
args = append(args, "-o", b.Program)
|
||||
}
|
||||
cmd := exec.Command(tools["cc"], args...)
|
||||
run(b, *shellhack, cmd)
|
||||
}
|
||||
|
||||
func link(b *build) {
|
||||
if !isValueInList("-c", b.Cflags) {
|
||||
return
|
||||
}
|
||||
log.Printf("Linking %s\n", b.name)
|
||||
if len(b.SourceFilesCmd) > 0 {
|
||||
for _, n := range b.SourceFilesCmd {
|
||||
@ -329,7 +436,6 @@ func link(b *build) {
|
||||
o := f[:len(f)] + ".o"
|
||||
args := []string{"-o", n, o}
|
||||
args = append(args, b.Oflags...)
|
||||
args = append(args, "-L", fromRoot("/arch/$ARCH/lib"))
|
||||
args = append(args, b.Libs...)
|
||||
run(b, *shellhack, exec.Command(tools["ld"], args...))
|
||||
}
|
||||
@ -338,7 +444,6 @@ func link(b *build) {
|
||||
args := []string{"-o", b.Program}
|
||||
args = append(args, b.ObjectFiles...)
|
||||
args = append(args, b.Oflags...)
|
||||
args = append(args, "-L", fromRoot("/arch/$ARCH/lib"))
|
||||
args = append(args, b.Libs...)
|
||||
run(b, *shellhack, exec.Command(tools["ld"], args...))
|
||||
}
|
||||
@ -412,12 +517,12 @@ func projects(b *build, r []*regexp.Regexp) {
|
||||
for _, v := range b.Projects {
|
||||
f, _ := findBuildfile(v)
|
||||
log.Printf("Doing %s\n", f)
|
||||
project(f, r)
|
||||
project(f, r, b)
|
||||
}
|
||||
}
|
||||
|
||||
// assumes we are in the wd of the project.
|
||||
func project(bf string, which []*regexp.Regexp) {
|
||||
func project(bf string, which []*regexp.Regexp, container *build) {
|
||||
cwd, err := os.Getwd()
|
||||
failOn(err)
|
||||
debug("Start new project cwd is %v", cwd)
|
||||
@ -430,11 +535,25 @@ func project(bf string, which []*regexp.Regexp) {
|
||||
debug("Processing %v: %d target", root, len(builds))
|
||||
for _, b := range builds {
|
||||
debug("Processing %v: %v", b.name, b)
|
||||
if container != nil {
|
||||
b.Env = append(container.Env, b.Env...)
|
||||
}
|
||||
projects(&b, regexpAll)
|
||||
for _, c := range b.Pre {
|
||||
// this is a hack: we just pass the command through as an exec.Cmd
|
||||
run(&b, true, exec.Command(c))
|
||||
}
|
||||
envFunc := buildEnv(&b);
|
||||
b.Program = os.Expand(b.Program, envFunc)
|
||||
for i, s := range b.SourceFiles {
|
||||
b.SourceFiles[i] = fromRoot(os.Expand(s, envFunc));
|
||||
}
|
||||
for i, s := range b.SourceFilesCmd {
|
||||
b.SourceFilesCmd[i] = fromRoot(os.Expand(s, envFunc));
|
||||
}
|
||||
for i, s := range b.ObjectFiles {
|
||||
b.ObjectFiles[i] = fromRoot(os.Expand(s, envFunc));
|
||||
}
|
||||
buildkernel(&b)
|
||||
if len(b.SourceFiles) > 0 || len(b.SourceFilesCmd) > 0 {
|
||||
compile(&b)
|
||||
@ -511,7 +630,7 @@ func main() {
|
||||
re = append(re, rx)
|
||||
}
|
||||
}
|
||||
project(bf, re)
|
||||
project(bf, re, nil)
|
||||
}
|
||||
|
||||
func findTools(toolprefix string) {
|
||||
@ -520,7 +639,10 @@ func findTools(toolprefix string) {
|
||||
if x := os.Getenv(strings.ToUpper(k)); x != "" {
|
||||
v = x
|
||||
}
|
||||
v, err = exec.LookPath(toolprefix + v)
|
||||
if v != "sh" {
|
||||
v = toolprefix + v;
|
||||
}
|
||||
v, err = exec.LookPath(v)
|
||||
failOn(err)
|
||||
tools[k] = v
|
||||
}
|
||||
|
@ -98,20 +98,6 @@ VGAcur* vgacur[] = {
|
||||
nil,
|
||||
};
|
||||
|
||||
Physseg physseg[8] = {
|
||||
{
|
||||
.attr = SG_SHARED,
|
||||
.name = "shared",
|
||||
.size = SEGMAXPG,
|
||||
},
|
||||
{
|
||||
.attr = SG_BSS,
|
||||
.name = "memory",
|
||||
.size = SEGMAXPG,
|
||||
},
|
||||
};
|
||||
int nphysseg = 8;
|
||||
|
||||
{{ range .Config.Code }}{{ . }}
|
||||
{{ end }}
|
||||
|
||||
|
197
src/jehanne/cmd/fetch/fetch.go
Normal file
197
src/jehanne/cmd/fetch/fetch.go
Normal file
@ -0,0 +1,197 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/bzip2"
|
||||
"compress/gzip"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"hash"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
dirPermissions = 0755
|
||||
)
|
||||
|
||||
type Fetch struct {
|
||||
Upstream string
|
||||
Digest map[string]string
|
||||
Compress string
|
||||
RemovePrefix bool
|
||||
Exclude []string
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
j, err := ioutil.ReadFile("fetch.json")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fetches := make(map[string]Fetch)
|
||||
if err := json.Unmarshal(j, &fetches); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for name, f := range(fetches) {
|
||||
if _, err := os.Stat(name); err == nil {
|
||||
log.Printf("Fetch: skip %v (already present)", name)
|
||||
} else {
|
||||
log.Printf("Fetch: %v from %v", name, f.Upstream)
|
||||
if err := do(&f, name); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func do(f *Fetch, name string) error {
|
||||
fname := fetch(f)
|
||||
s, err := os.Open(fname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(fname)
|
||||
|
||||
os.MkdirAll(name, dirPermissions)
|
||||
|
||||
var unZ io.Reader
|
||||
switch f.Compress {
|
||||
case "gzip":
|
||||
unZ, err = gzip.NewReader(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "bzip2":
|
||||
unZ = bzip2.NewReader(s)
|
||||
default:
|
||||
unZ = s
|
||||
}
|
||||
|
||||
ar := tar.NewReader(unZ)
|
||||
h, err := ar.Next()
|
||||
untar:
|
||||
for ; err == nil; h, err = ar.Next() {
|
||||
n := h.Name
|
||||
if f.RemovePrefix {
|
||||
n = strings.SplitN(n, "/", 2)[1]
|
||||
}
|
||||
for _, ex := range f.Exclude {
|
||||
if strings.HasPrefix(n, ex) {
|
||||
continue untar
|
||||
}
|
||||
}
|
||||
n = path.Join(name, n)
|
||||
if h.FileInfo().IsDir() {
|
||||
os.MkdirAll(n, dirPermissions)
|
||||
continue
|
||||
}
|
||||
os.MkdirAll(path.Dir(n), dirPermissions)
|
||||
out, err := os.Create(n)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if n, err := io.Copy(out, ar); n != h.Size || err != nil {
|
||||
return err
|
||||
}
|
||||
out.Close()
|
||||
if err := os.Chmod(n, h.FileInfo().Mode()); err != nil {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
if err != io.EOF {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type match struct {
|
||||
hash.Hash
|
||||
Good []byte
|
||||
Name string
|
||||
}
|
||||
|
||||
func (m match) OK() bool {
|
||||
return bytes.Equal(m.Good, m.Hash.Sum(nil))
|
||||
}
|
||||
|
||||
func fetch(v *Fetch) string {
|
||||
if len(v.Digest) == 0 {
|
||||
log.Fatal("no checksums specifed")
|
||||
}
|
||||
|
||||
f, err := ioutil.TempFile("", "cmdVendor")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
req, err := http.NewRequest("GET", v.Upstream, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
client := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DisableCompression: true,
|
||||
},
|
||||
}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
var digests []match
|
||||
for k, v := range v.Digest {
|
||||
g, err := hex.DecodeString(v)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
switch k {
|
||||
case "sha224":
|
||||
digests = append(digests, match{sha256.New224(), g, k})
|
||||
case "sha256":
|
||||
digests = append(digests, match{sha256.New(), g, k})
|
||||
case "sha384":
|
||||
digests = append(digests, match{sha512.New384(), g, k})
|
||||
case "sha512":
|
||||
digests = append(digests, match{sha512.New(), g, k})
|
||||
}
|
||||
}
|
||||
ws := make([]io.Writer, len(digests))
|
||||
for i := range digests {
|
||||
ws[i] = digests[i]
|
||||
}
|
||||
w := io.MultiWriter(ws...)
|
||||
|
||||
if _, err := io.Copy(f, io.TeeReader(res.Body, w)); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for _, h := range digests {
|
||||
if !h.OK() {
|
||||
log.Fatalf("mismatched %q hash\n\tWanted %x\n\tGot %x\n", h.Name, h.Good, h.Hash.Sum(nil))
|
||||
}
|
||||
}
|
||||
return f.Name()
|
||||
}
|
||||
|
||||
func run(exe string, arg ...string) error {
|
||||
cmd := exec.Command(exe, arg...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
374
src/jehanne/cmd/ksyscalls/ksyscalls.go
Normal file
374
src/jehanne/cmd/ksyscalls/ksyscalls.go
Normal file
@ -0,0 +1,374 @@
|
||||
/*
|
||||
* This file is part of Jehanne.
|
||||
*
|
||||
* Copyright (C) 2016 Giacomo Tesio <giacomo@tesio.it>
|
||||
*
|
||||
* Jehanne is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Jehanne is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type SyscallConf struct {
|
||||
Ret []string
|
||||
Args []string
|
||||
Name string
|
||||
Id uint32
|
||||
}
|
||||
|
||||
type Sysconf struct {
|
||||
Syscalls []SyscallConf
|
||||
}
|
||||
|
||||
func usage(msg string) {
|
||||
fmt.Fprint(os.Stderr, msg)
|
||||
fmt.Fprint(os.Stderr, "Usage: ksyscalls path/to/sysconf.json\n")
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
type SyscallWrapper struct {
|
||||
Id uint32
|
||||
Name string
|
||||
Vars []string
|
||||
CommonCode string
|
||||
ExecCode string
|
||||
EntryPrint string
|
||||
ExitPrint string
|
||||
SysRetField string
|
||||
DefaultRet string
|
||||
}
|
||||
|
||||
type KernelCode struct {
|
||||
Externs []string
|
||||
Wrappers []SyscallWrapper
|
||||
}
|
||||
|
||||
func uregArg(index int) string{
|
||||
switch(index){
|
||||
case 0:
|
||||
return "di";
|
||||
case 1:
|
||||
return "si";
|
||||
case 2:
|
||||
return "dx";
|
||||
case 3:
|
||||
return "r10";
|
||||
case 4:
|
||||
return "r8";
|
||||
case 5:
|
||||
return "r9";
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func sysret(t string) string {
|
||||
switch(t){
|
||||
case "int", "int32_t":
|
||||
return "i"
|
||||
case "long", "int64_t":
|
||||
return "vl"
|
||||
case "uintptr_t", "void":
|
||||
return "p"
|
||||
case "void*", "char*", "char**", "uint8_t*", "int32_t*", "uint64_t*", "int64_t*":
|
||||
return "v"
|
||||
}
|
||||
return " [?? " + t + "]"
|
||||
}
|
||||
|
||||
func formatArg(i int, t string) string{
|
||||
switch(t){
|
||||
case "int", "int32_t":
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%d\", a%d);\n", i)
|
||||
case "unsigned int", "uint32_t":
|
||||
/* unsigned int is reserved for flags */
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%#ux\", a%d);\n", i)
|
||||
case "long", "int64_t":
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%lld\", a%d);\n", i)
|
||||
case "unsigned long", "uint64_t":
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%#lud\", a%d);\n", i)
|
||||
case "void*", "uint8_t*", "const void*", "const uint8_t*":
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%#p\", a%d);\n", i)
|
||||
case "int32_t*", "int*", "const int32_t*", "const int*":
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%#p(%%d)\", a%d, a%d);\n", i, i)
|
||||
case "const char*", "char*":
|
||||
return fmt.Sprintf("\tfmtuserstring(fmt, a%d);\n", i)
|
||||
case "const char**", "char**":
|
||||
return fmt.Sprintf("\tfmtuserstringlist(fmt, a%d);\n", i);
|
||||
}
|
||||
return " [?? " + t + "]"
|
||||
}
|
||||
|
||||
func formatRet(t string) string{
|
||||
switch(t){
|
||||
case "int", "int32_t":
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%d\", ret->%s);\n", sysret(t))
|
||||
case "unsigned int", "uint32_t":
|
||||
/* unsigned int is reserved for flags */
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%#ux\", ret->%s);\n", sysret(t))
|
||||
case "long", "int64_t":
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%lld\", ret->%s);\n", sysret(t))
|
||||
case "unsigned long", "uint64_t", "void":
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%#llud\", ret->%s);\n", sysret(t))
|
||||
case "void*", "uintptr_t", "const void*", "const uintptr_t":
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%#p\", ret->%s);\n", sysret(t))
|
||||
case "int32_t*", "int*", "const int32_t*", "const int*":
|
||||
return fmt.Sprintf("\tfmtprint(fmt, \" %%#p(%%d)\", ret->%s, *ret->%s);\n", sysret(t), sysret(t))
|
||||
}
|
||||
return " [?? " + t + "]"
|
||||
}
|
||||
|
||||
func generateKernelCode(calls []SyscallConf){
|
||||
code := new(KernelCode)
|
||||
|
||||
for _, call := range(calls) {
|
||||
/* extern definitions */
|
||||
ext := "extern " + call.Ret[0] + " sys" + call.Name + "("
|
||||
if len(call.Args) == 0 {
|
||||
ext += "void";
|
||||
} else {
|
||||
for i, a := range(call.Args){
|
||||
if i > 0 {
|
||||
ext += ", "
|
||||
}
|
||||
ext += fmt.Sprintf("%s", a)
|
||||
}
|
||||
}
|
||||
ext += ");\n"
|
||||
|
||||
wcall := new(SyscallWrapper)
|
||||
wcall.Id = call.Id
|
||||
wcall.Name = call.Name
|
||||
wcall.SysRetField = sysret(call.Ret[0])
|
||||
wcall.DefaultRet = fmt.Sprintf("ret.%s = (%s)-1;", wcall.SysRetField, call.Ret[0])
|
||||
|
||||
for i, a := range(call.Args){
|
||||
wcall.Vars = append(wcall.Vars, fmt.Sprintf("%s a%v;", a, i))
|
||||
wcall.CommonCode += fmt.Sprintf("\ta%v = (%s)ureg->%s;\n", i, a, uregArg(i))
|
||||
}
|
||||
wcall.ExecCode += "\tret->" + wcall.SysRetField + " = sys" + call.Name + "("
|
||||
for i, _ := range(call.Args){
|
||||
if i > 0 {
|
||||
wcall.ExecCode += ", "
|
||||
}
|
||||
wcall.ExecCode += fmt.Sprintf("a%v", i)
|
||||
}
|
||||
wcall.ExecCode += ");"
|
||||
|
||||
if call.Name == "pwrite"{
|
||||
wcall.EntryPrint += formatArg(0, call.Args[0])
|
||||
wcall.EntryPrint += "\tfmtrwdata(fmt, (char*)a1, MIN(a2, 64));\n"
|
||||
wcall.EntryPrint += formatArg(2, call.Args[2])
|
||||
wcall.EntryPrint += formatArg(3, call.Args[3])
|
||||
} else {
|
||||
for i, a := range(call.Args){
|
||||
wcall.EntryPrint += formatArg(i, a)
|
||||
}
|
||||
}
|
||||
|
||||
wcall.ExitPrint += formatRet(call.Ret[0])
|
||||
if call.Name == "pread"{
|
||||
wcall.ExitPrint += fmt.Sprintf("\tfmtrwdata(fmt, (char*)ureg->%s, MIN(ureg->%s, 64));\n", uregArg(1), uregArg(2))
|
||||
}
|
||||
|
||||
code.Wrappers = append(code.Wrappers, *wcall)
|
||||
code.Externs = append(code.Externs, ext)
|
||||
}
|
||||
|
||||
tmpl, err := template.New("systab.c").Parse(`/*
|
||||
* This file is part of Jehanne.
|
||||
*
|
||||
* Copyright (C) 2016 Giacomo Tesio <giacomo@tesio.it>
|
||||
*
|
||||
* Jehanne is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Jehanne is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* automatically generated by ksyscalls */
|
||||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
#include "ureg.h"
|
||||
|
||||
extern void fmtrwdata(Fmt* f, char* a, int n);
|
||||
extern void fmtuserstring(Fmt* f, const char* a);
|
||||
extern void fmtuserstringlist(Fmt* f, const char** argv);
|
||||
|
||||
{{ range .Externs }}{{.}}{{ end }}
|
||||
{{ range .Wrappers }}
|
||||
static void
|
||||
wrap_{{ .Name }}(ScRet* ret, Ureg* ureg)
|
||||
{
|
||||
{{ range .Vars }}{{.}}
|
||||
{{ end }}
|
||||
{{ .CommonCode }}
|
||||
{{ .ExecCode }}
|
||||
}
|
||||
{{ end }}
|
||||
int nsyscall = {{len .Wrappers}};
|
||||
|
||||
ScRet
|
||||
default_syscall_ret(int syscall)
|
||||
{
|
||||
static ScRet zero;
|
||||
ScRet ret = zero;
|
||||
switch(syscall){
|
||||
{{ range .Wrappers }}case {{ .Id }}:
|
||||
{{ .DefaultRet }}
|
||||
break;
|
||||
{{ end }}
|
||||
default:
|
||||
ret.vl = -1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char*
|
||||
syscall_name(int syscall)
|
||||
{
|
||||
switch(syscall){
|
||||
{{ range .Wrappers }}case {{ .Id }}:
|
||||
return "{{ .Name }}";
|
||||
{{ end }}
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dispatch_syscall(int syscall, Ureg* ureg, ScRet* ret)
|
||||
{
|
||||
switch(syscall){
|
||||
{{ range .Wrappers }}case {{ .Id }}:
|
||||
wrap_{{ .Name }}(ret, ureg);
|
||||
break;
|
||||
{{ end }}
|
||||
default:
|
||||
panic("dispatch_syscall: bad sys call number %d pc %#p\n", syscall, ureg->ip);
|
||||
}
|
||||
}
|
||||
|
||||
{{ range .Wrappers }}
|
||||
static void
|
||||
enter_{{ .Name }}(Fmt* fmt, Ureg* ureg)
|
||||
{
|
||||
{{ range .Vars }}{{.}}
|
||||
{{ end }}
|
||||
{{ .CommonCode }}
|
||||
fmtprint(fmt, "{{ .Name }} %#p > ", ureg->ip);
|
||||
{{ .EntryPrint }}
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
char*
|
||||
syscallfmt(int syscall, Ureg* ureg)
|
||||
{
|
||||
Fmt fmt;
|
||||
fmtstrinit(&fmt);
|
||||
fmtprint(&fmt, "%d %s ", up->pid, up->text);
|
||||
|
||||
switch(syscall){
|
||||
{{ range .Wrappers }}case {{ .Id }}:
|
||||
enter_{{ .Name }}(&fmt, ureg);
|
||||
break;
|
||||
{{ end }}
|
||||
default:
|
||||
panic("syscallfmt: bad sys call number %d pc %#p\n", syscall, ureg->ip);
|
||||
}
|
||||
|
||||
return fmtstrflush(&fmt);
|
||||
}
|
||||
|
||||
{{ range .Wrappers }}
|
||||
static void
|
||||
exit_{{ .Name }}(Fmt* fmt, Ureg* ureg, ScRet* ret)
|
||||
{
|
||||
fmtprint(fmt, "{{ .Name }} %#p < ", ureg->ip);
|
||||
{{ .ExitPrint }}
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
char*
|
||||
sysretfmt(int syscall, Ureg* ureg, ScRet* ret, uint64_t start, uint64_t stop)
|
||||
{
|
||||
Fmt fmt;
|
||||
fmtstrinit(&fmt);
|
||||
fmtprint(&fmt, "%d %s ", up->pid, up->text);
|
||||
|
||||
switch(syscall){
|
||||
{{ range .Wrappers }}case {{ .Id }}:
|
||||
exit_{{ .Name }}(&fmt, ureg, ret);
|
||||
break;
|
||||
{{ end }}
|
||||
default:
|
||||
panic("sysretfmt: bad sys call number %d pc %#p\n", syscall, ureg->ip);
|
||||
}
|
||||
|
||||
if(0 > ret->vl){
|
||||
fmtprint(&fmt, " %s %#llud %#llud\n", up->syserrstr, start, stop-start);
|
||||
} else {
|
||||
fmtprint(&fmt, " \"\" %#llud %#llud\n", start, stop-start);
|
||||
}
|
||||
|
||||
return fmtstrflush(&fmt);
|
||||
}
|
||||
|
||||
`)
|
||||
err = tmpl.Execute(os.Stdout, code)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if flag.NArg() != 1 {
|
||||
usage("no path to sysconf.json")
|
||||
}
|
||||
|
||||
buf, err := ioutil.ReadFile(flag.Arg(0))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var sysconf Sysconf
|
||||
err = json.Unmarshal(buf, &sysconf)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
generateKernelCode(sysconf.Syscalls)
|
||||
|
||||
}
|
@ -258,9 +258,9 @@ const(
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "../../libc/9syscall/sys.h"
|
||||
#include <9syscall/sys.h>
|
||||
|
||||
{{ range . }}extern void {{ .Sysname }}(Ar0*, ...);
|
||||
{{ range . }}extern void {{ .Sysname }}(ScRet*, ScArg, ScArg, ScArg, ScArg, ScArg, ScArg);
|
||||
{{ end }}
|
||||
Systab systab[] = {
|
||||
{{ range . }}[{{ .Define }}] { "{{ .Name }}", {{ .Sysname }}, {{ .Fudge }} },
|
||||
|
291
src/jehanne/cmd/usyscalls/usyscalls.go
Normal file
291
src/jehanne/cmd/usyscalls/usyscalls.go
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* This file is part of Jehanne.
|
||||
*
|
||||
* Copyright (C) 2016 Giacomo Tesio <giacomo@tesio.it>
|
||||
*
|
||||
* Jehanne is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Jehanne is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
const gplHeader string = `/*
|
||||
* This file is part of Jehanne.
|
||||
*
|
||||
* Copyright (C) 2016 Giacomo Tesio <giacomo@tesio.it>
|
||||
*
|
||||
* Jehanne is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Jehanne is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* automatically generated by usyscalls */
|
||||
`
|
||||
|
||||
type SyscallConf struct {
|
||||
Ret []string
|
||||
Args []string
|
||||
Name string
|
||||
Id uint32
|
||||
}
|
||||
|
||||
type Sysconf struct {
|
||||
Syscalls []SyscallConf
|
||||
}
|
||||
|
||||
type SyscallWrapper struct {
|
||||
Id uint32
|
||||
Name string
|
||||
FuncArgs string
|
||||
MacroArgs string
|
||||
VarValues []string
|
||||
Vars []string
|
||||
AsmArgs string
|
||||
AsmClobbers string
|
||||
RetType string
|
||||
}
|
||||
|
||||
type HeaderCode struct {
|
||||
Wrappers []SyscallWrapper
|
||||
}
|
||||
|
||||
|
||||
func usage(msg string) {
|
||||
fmt.Fprint(os.Stderr, msg)
|
||||
fmt.Fprint(os.Stderr, "Usage: usyscalls header|code path/to/sysconf.json\n")
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func argTypeName(t string) string{
|
||||
switch(t){
|
||||
case "int", "int32_t":
|
||||
return "i"
|
||||
case "unsigned int", "uint32_t":
|
||||
/* unsigned int is reserved for flags */
|
||||
return "ui"
|
||||
case "long", "int64_t":
|
||||
return "l"
|
||||
case "unsigned long", "uint64_t":
|
||||
return "ul"
|
||||
case "void*", "uint8_t*", "const void*", "const uint8_t*":
|
||||
return "p"
|
||||
case "int32_t*", "int*", "const int32_t*", "const int*":
|
||||
return "p"
|
||||
case "const char*", "char*":
|
||||
return "p"
|
||||
case "const char**", "char**":
|
||||
return "p"
|
||||
}
|
||||
return " [?? " + t + "]"
|
||||
|
||||
}
|
||||
|
||||
func argRegister(index int, t string) string{
|
||||
prefix := ""
|
||||
switch(t){
|
||||
case "int", "unsigned int", "uint32_t", "int32_t":
|
||||
prefix = "e"
|
||||
default:
|
||||
prefix = "r"
|
||||
}
|
||||
switch(index){
|
||||
case 0:
|
||||
return prefix + "di";
|
||||
case 1:
|
||||
return prefix + "si";
|
||||
case 2:
|
||||
return prefix + "dx";
|
||||
case 3:
|
||||
return "r10";
|
||||
case 4:
|
||||
return "r8";
|
||||
case 5:
|
||||
return "r9";
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getHeaderData(calls []SyscallConf) *HeaderCode {
|
||||
code := new(HeaderCode)
|
||||
for _, call := range(calls) {
|
||||
wcall := new(SyscallWrapper)
|
||||
wcall.Id = call.Id
|
||||
wcall.Name = call.Name
|
||||
wcall.RetType = call.Ret[0]
|
||||
|
||||
clobberMemory := false
|
||||
wcall.AsmClobbers = "\"cc\", \"rcx\", \"r11\""
|
||||
wcall.AsmArgs = fmt.Sprintf("\"0\"(%d)", wcall.Id)
|
||||
for i, a := range(call.Args){
|
||||
if i > 0 {
|
||||
wcall.FuncArgs += ", "
|
||||
wcall.MacroArgs += ", "
|
||||
}
|
||||
if strings.HasSuffix(a, "*") && !strings.HasPrefix(a, "const"){
|
||||
clobberMemory = true
|
||||
}
|
||||
wcall.FuncArgs += fmt.Sprintf("%s a%d", a, i)
|
||||
wcall.MacroArgs += fmt.Sprintf("/* %s */ a%d", a, i)
|
||||
wcall.VarValues = append(wcall.VarValues, fmt.Sprintf("_sysargs[%d].%s = (a%d); \\\n\t", i, argTypeName(a), i))
|
||||
wcall.Vars = append(wcall.Vars, fmt.Sprintf("register %s __r%d asm(\"%s\") = _sysargs[%d].%s; \\\n\t", a, i, argRegister(i, a), i, argTypeName(a)))
|
||||
wcall.AsmArgs += fmt.Sprintf(", \"r\"(__r%d)", i)
|
||||
}
|
||||
if clobberMemory {
|
||||
wcall.AsmClobbers += ", \"memory\""
|
||||
}
|
||||
code.Wrappers = append(code.Wrappers, *wcall)
|
||||
}
|
||||
|
||||
return code
|
||||
}
|
||||
|
||||
func generateSyscallTable(calls []SyscallConf){
|
||||
code := getHeaderData(calls)
|
||||
tmpl, err := template.New("tab.c").Parse(`
|
||||
{{ range .Wrappers }}"{{ .Name }}", (int(*)()) {{ .Name }},
|
||||
{{ end }}
|
||||
`)
|
||||
err = tmpl.Execute(os.Stdout, code)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func generateLibcCode(calls []SyscallConf){
|
||||
code := getHeaderData(calls)
|
||||
tmpl, err := template.New("syscalls.c").Parse(gplHeader + `
|
||||
#define PORTABLE_SYSCALLS
|
||||
#include <u.h>
|
||||
|
||||
{{ range .Wrappers }}
|
||||
{{ .RetType }}
|
||||
{{ .Name }}({{ .FuncArgs }})
|
||||
{
|
||||
register {{ .RetType }} __ret asm ("rax");
|
||||
__asm__ __volatile__ (
|
||||
"movq %%rcx, %%r10" "\n\t"
|
||||
"movq ${{ .Id }}, %%rax" "\n\t"
|
||||
"syscall"
|
||||
: "=r" (__ret)
|
||||
: /* args are ready */
|
||||
: {{ .AsmClobbers }}
|
||||
);
|
||||
return __ret;
|
||||
}
|
||||
{{ end }}
|
||||
`)
|
||||
err = tmpl.Execute(os.Stdout, code)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func generateSyscallHeader(calls []SyscallConf){
|
||||
funcMap := template.FuncMap{
|
||||
"title": strings.Title,
|
||||
}
|
||||
code := getHeaderData(calls)
|
||||
tmpl, err := template.New("syscall.h").Funcs(funcMap).Parse(gplHeader + `
|
||||
typedef enum Syscalls
|
||||
{
|
||||
{{ range .Wrappers }} Sys{{ .Name|title }} = {{ .Id }},
|
||||
{{ end }}} Syscalls;
|
||||
|
||||
#ifndef KERNEL
|
||||
{{ range .Wrappers }}
|
||||
#define sys_{{ .Name }}({{ .MacroArgs }}) ({ \
|
||||
{{ range .VarValues }}{{.}}{{end}}{{ range .Vars }}{{.}}{{end}}register {{ .RetType }} __ret asm ("rax"); \
|
||||
__asm__ __volatile__ ( \
|
||||
"syscall" \
|
||||
: "=&r" (__ret) \
|
||||
: {{ .AsmArgs }} \
|
||||
: {{ .AsmClobbers }} \
|
||||
); \
|
||||
__ret; })
|
||||
{{ end }}
|
||||
|
||||
#ifdef PORTABLE_SYSCALLS
|
||||
|
||||
{{ range .Wrappers }}extern {{ .RetType }} {{ .Name }}({{ .FuncArgs }});
|
||||
{{ end }}
|
||||
extern int32_t read(int, void*, int32_t);
|
||||
extern int32_t write(int, const void*, int32_t);
|
||||
|
||||
#else
|
||||
|
||||
{{ range .Wrappers }}# define {{ .Name }}(...) sys_{{ .Name }}(__VA_ARGS__)
|
||||
{{ end }}
|
||||
#define read(fd, buf, size) pread(fd, buf, size, -1)
|
||||
#define write(fd, buf, size) pwrite(fd, buf, size, -1)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
`)
|
||||
err = tmpl.Execute(os.Stdout, code)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if flag.NArg() != 2 {
|
||||
usage("no path to sysconf.json")
|
||||
}
|
||||
|
||||
buf, err := ioutil.ReadFile(flag.Arg(1))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var sysconf Sysconf
|
||||
err = json.Unmarshal(buf, &sysconf)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
mode := flag.Arg(0)
|
||||
switch(mode){
|
||||
case "header":
|
||||
generateSyscallHeader(sysconf.Syscalls)
|
||||
break
|
||||
case "code":
|
||||
generateLibcCode(sysconf.Syscalls)
|
||||
break
|
||||
case "tab":
|
||||
generateSyscallTable(sysconf.Syscalls)
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user