Skip to content

Commit

Permalink
Merge pull request #1 from davidar/i386
Browse files Browse the repository at this point in the history
Support i386
  • Loading branch information
davidar authored May 23, 2024
2 parents 128fac5 + 176f690 commit 87011a0
Show file tree
Hide file tree
Showing 265 changed files with 3,717 additions and 1,215 deletions.
9 changes: 3 additions & 6 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,17 @@ jobs:
with:
load: true
tags: davidar/bootsh:latest
platforms: linux/amd64,linux/i386
-
name: Checkout
uses: actions/checkout@v4
-
name: Test
run: |
docker run --rm \
-v $PWD/test-cc:/tmp/test-cc \
-v $PWD/lib/toybox:/tmp/lib/toybox \
-v $PWD/tarballs:/src/tarballs \
davidar/bootsh:latest test-host
run: make test-latest -o docker-latest
-
name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: davidar/bootsh:latest
platforms: linux/amd64,linux/i386
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@
/test/cc/tests2/fred.txt

/tarballs/
/logs/
15 changes: 11 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
ARG TAG=latest

FROM alpine AS build-latest
FROM alpine AS alpine-amd64

FROM alpine AS alpine-386
RUN apk add setarch
SHELL [ "setarch", "i386", "/bin/sh", "-c" ]

ARG TARGETARCH
FROM alpine-$TARGETARCH AS build-latest
RUN apk add build-base bash

FROM davidar/bootsh:latest AS build-stage0
Expand All @@ -20,8 +27,8 @@ COPY lib bootsh/lib
RUN cd bootsh && CFLAGS=-Werror ./configure && make clean && make -j$(nproc)

FROM scratch AS bootsh
COPY --from=build /tmp/bootsh/bootsh /bin/sh
COPY boot.sh /bin/boot.sh
COPY Makefile.packages /tmp/Makefile
COPY wak.c /bin/awk
COPY Makefile.packages /tmp/Makefile
COPY boot.sh /bin/boot.sh
COPY --from=build /tmp/bootsh/bootsh /bin/sh
ENTRYPOINT ["/bin/boot.sh"]
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ clean:
$(MAKE) -C lib/tcc clean
$(MAKE) -C lib/toybox clean
$(MAKE) -C src clean
if [ -d test-cc ]; then $(MAKE) -C test-cc clean; fi

tarballs/musl-%.tar.gz:
mkdir -p tarballs
Expand Down
31 changes: 18 additions & 13 deletions Makefile.docker
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
IMAGE_NAME = davidar/bootsh
GET_DOCKER_IMAGE_ID = docker images --format "{{.ID}}" --no-trunc --filter=reference=$(IMAGE_NAME)
DOCKER_MOUNTS = \
-v $(CURDIR)/test-cc:/tmp/test-cc \
-v $(CURDIR)/lib/toybox:/tmp/lib/toybox \
-v $(CURDIR)/tarballs:/src/tarballs

test: test-latest test-bootstrap
test: test-latest test-stage2 bootstrap-amd64 bootstrap-i386

docker-%:
docker build . -t $(IMAGE_NAME):$* --build-arg TAG=$*
docker build . -t $(IMAGE_NAME):$* --build-arg TAG=$* --platform linux/amd64,linux/i386

docker-stage0: docker-latest
docker-stage1: docker-stage0
docker-stage2: docker-stage1

docker-bootstrap: docker-stage2
[ `$(GET_DOCKER_IMAGE_ID):stage1` = `$(GET_DOCKER_IMAGE_ID):stage2` ]
docker tag $(IMAGE_NAME):stage2 $(IMAGE_NAME):bootstrap

test-%: docker-%
docker run --rm \
-v $(CURDIR)/test-cc:/tmp/test-cc \
-v $(CURDIR)/lib/toybox:/tmp/lib/toybox \
-v $(CURDIR)/tarballs:/src/tarballs \
$(IMAGE_NAME):$* test-host
docker run --rm --platform linux/amd64 $(DOCKER_MOUNTS) $(IMAGE_NAME):$* test-host
docker run --rm --platform linux/i386 $(DOCKER_MOUNTS) $(IMAGE_NAME):$* test-host

run: docker-latest
docker run --rm -it -v $(CURDIR)/tarballs:/src/tarballs $(IMAGE_NAME):latest
docker run --rm -it -v $(CURDIR):/src $(IMAGE_NAME):latest

bootsh.amd64.%: docker-%
ID=`docker create --platform linux/amd64 $(IMAGE_NAME):$*` && docker cp $$ID:/bin/sh $@ && docker rm $$ID

bootsh.i386.%: docker-%
ID=`docker create --platform linux/i386 $(IMAGE_NAME):$*` && docker cp $$ID:/bin/sh $@ && docker rm $$ID

bootstrap-%: bootsh.%.stage1 bootsh.%.stage2
diff -q $^
6 changes: 3 additions & 3 deletions Makefile.packages
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARCH = $(shell uname -m)
ARCH = $(shell uname -m | sed 's/i.86/i386/')
NPROC = $(shell nproc)
MAKEFLAGS += -j$(NPROC)

Expand Down Expand Up @@ -60,7 +60,7 @@ linux-headers-4.19.88: /src/tarballs/linux-headers-4.19.88.tar.xz

/usr/local/include/linux: linux-headers-4.19.88
@echo "Bootstrapping linux-headers -> /src/logs/boot_linux-headers.log"
(cd $< && $(MAKE) install ARCH=$(shell uname -m)) > /src/logs/boot_linux-headers.log 2>&1
(cd $< && $(MAKE) install ARCH=$(ARCH)) > /src/logs/boot_linux-headers.log 2>&1

linux-headers: /usr/local/include/linux

Expand Down Expand Up @@ -123,6 +123,6 @@ curl-8.0.1: /src/tarballs/curl-8.0.1.tar.xz
curl: /usr/local/bin/curl

test-host: bash
cd test-cc && $(MAKE) && $(MAKE) clean
cd test-cc && $(MAKE) -j1 ARCH=$(ARCH) && $(MAKE) clean
cd lib/toybox && TEST_HOST=1 USER=root scripts/test.sh && rm -rf generated/testdir
@echo "All tests passed!"
195 changes: 65 additions & 130 deletions boot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ if which make >/dev/null && tty -s; then
exec /bin/sh
fi

# Setup root filesystem

[ ! -L /usr ] && ln -s / /usr
mkdir -p /etc /local/bin /tmp
chmod 1777 /tmp
Expand Down Expand Up @@ -54,118 +56,51 @@ fi
tar -xf /src/tarballs/musl-1.2.5.tar.gz
cd musl-1.2.5

echo "Bootstrapping musl -> /src/logs/boot_musl.log"
echo "Bootstrapping musl"

CFLAGS="$CFLAGS -std=c99 -nostdinc -D_XOPEN_SOURCE=700"
CFLAGS="$CFLAGS -Iarch/x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude"
ARCH=$(uname -m | sed 's/i.86/i386/')

# Patch musl to be compatible with tcc

rm -rf src/complex src/math/$ARCH crt/$ARCH

rm -rf src/complex src/math/x86_64 crt/x86_64
sed -i s/@PLT//g src/signal/x86_64/sigsetjmp.s
cat > arch/x86_64/syscall_arch.h <<EOF
#define __SYSCALL_LL_E(x) (x)
#define __SYSCALL_LL_O(x) (x)
static __inline long __syscall0(long n);
asm (
".type __syscall0, @function;"
"__syscall0:;"
"movq %rdi, %rax;"
"syscall;"
"ret"
);
static __inline long __syscall1(long n, long a1);
asm (
".type __syscall1, @function;"
"__syscall1:;"
"movq %rdi, %rax;"
"movq %rsi, %rdi;"
"syscall;"
"ret"
);
static __inline long __syscall2(long n, long a1, long a2);
asm (
".type __syscall2, @function;"
"__syscall2:;"
"movq %rdi, %rax;"
"movq %rsi, %rdi;"
"movq %rdx, %rsi;"
"syscall;"
"ret"
);
static __inline long __syscall3(long n, long a1, long a2, long a3);
asm (
".type __syscall3, @function;"
"__syscall3:;"
"movq %rdi, %rax;"
"movq %rsi, %rdi;"
"movq %rdx, %rsi;"
"movq %rcx, %rdx;"
"syscall;"
"ret"
);
static __inline long __syscall4(long n, long a1, long a2, long a3, long a4);
asm (
".type __syscall4, @function;"
"__syscall4:;"
"movq %rdi, %rax;"
"movq %rsi, %rdi;"
"movq %rdx, %rsi;"
"movq %rcx, %rdx;"
"movq %r8, %r10;"
"syscall;"
"ret"
);
static __inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5);
asm (
".type __syscall5, @function;"
"__syscall5:;"
"movq %rdi, %rax;"
"movq %rsi, %rdi;"
"movq %rdx, %rsi;"
"movq %rcx, %rdx;"
"movq %r8, %r10;"
"movq %r9, %r8;"
"syscall;"
"ret"
);
static __inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6);
asm (
".type __syscall6, @function;"
"__syscall6:;"
"movq %rdi, %rax;"
"movq %rsi, %rdi;"
"movq %rdx, %rsi;"
"movq %rcx, %rdx;"
"movq %r8, %r10;"
"movq %r9, %r8;"
"movq 8(%rsp), %r9;"
"syscall;"
"ret"
);
#define VDSO_USEFUL
#define VDSO_CGT_SYM "__vdso_clock_gettime"
#define VDSO_CGT_VER "LINUX_2.6"
#define VDSO_GETCPU_SYM "__vdso_getcpu"
#define VDSO_GETCPU_VER "LINUX_2.6"
#define IPC_64 0
sed -i 's/jecxz/test %ecx,%ecx; jz/' src/signal/i386/sigsetjmp.s

sed /_REDIR_TIME64/d -i arch/$ARCH/bits/alltypes.h.in

head -n3 arch/x86_64/syscall_arch.h > arch/x86_64/syscall_arch.h.new
tail -n8 arch/x86_64/syscall_arch.h >> arch/x86_64/syscall_arch.h.new
mv -f arch/x86_64/syscall_arch.h.new arch/x86_64/syscall_arch.h

head -n5 arch/i386/syscall_arch.h > arch/i386/syscall_arch.h.new
tail -n6 arch/i386/syscall_arch.h >> arch/i386/syscall_arch.h.new
mv -f arch/i386/syscall_arch.h.new arch/i386/syscall_arch.h

# These functions are provided by libtcc1.a
cat >> arch/$ARCH/syscall_arch.h <<EOF
long __syscall0(long);
long __syscall1(long, long);
long __syscall2(long, long, long);
long __syscall3(long, long, long, long);
long __syscall4(long, long, long, long, long);
long __syscall5(long, long, long, long, long, long);
long __syscall6(long, long, long, long, long, long, long);
EOF

# Build musl

CFLAGS="$CFLAGS -std=c99 -nostdinc -D_XOPEN_SOURCE=700"
CFLAGS="$CFLAGS -Iarch/$ARCH -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude"

mkdir -p obj/include/bits
sed -f ./tools/mkalltypes.sed ./arch/x86_64/bits/alltypes.h.in ./include/alltypes.h.in > obj/include/bits/alltypes.h
cp arch/x86_64/bits/syscall.h.in obj/include/bits/syscall.h
sed -n -e s/__NR_/SYS_/p < arch/x86_64/bits/syscall.h.in >> obj/include/bits/syscall.h
sed -f ./tools/mkalltypes.sed ./arch/$ARCH/bits/alltypes.h.in ./include/alltypes.h.in > obj/include/bits/alltypes.h
cp arch/$ARCH/bits/syscall.h.in obj/include/bits/syscall.h
sed -n -e s/__NR_/SYS_/p < arch/$ARCH/bits/syscall.h.in >> obj/include/bits/syscall.h

cp -r include $PREFIX/
cp -r arch/generic/bits $PREFIX/include/
cp -r arch/x86_64/bits $PREFIX/include/
cp -r arch/$ARCH/bits $PREFIX/include/
cp -r obj/include/bits $PREFIX/include/

mkdir -p obj/src/internal
Expand Down Expand Up @@ -204,38 +139,38 @@ EOF
for src in $SOURCES; do
obj=obj/${src%.c}.o
mkdir -p $(dirname $obj)
cc $CFLAGS -c -o $obj $src >> /src/logs/boot_musl.log 2>&1
cc $CFLAGS -c -o $obj $src
done

mkdir -p obj/src/env
mkdir -p obj/src/fenv/x86_64
mkdir -p obj/src/ldso/x86_64
mkdir -p obj/src/process/x86_64
mkdir -p obj/src/setjmp/x86_64
mkdir -p obj/src/signal/x86_64
mkdir -p obj/src/string/x86_64
mkdir -p obj/src/thread/x86_64

cc $CFLAGS -c -o obj/src/fenv/x86_64/fenv.o src/fenv/x86_64/fenv.s
cc $CFLAGS -c -o obj/src/ldso/x86_64/dlsym.o src/ldso/x86_64/dlsym.s
cc $CFLAGS -c -o obj/src/ldso/x86_64/tlsdesc.o src/ldso/x86_64/tlsdesc.s
cc $CFLAGS -c -o obj/src/process/x86_64/vfork.o src/process/x86_64/vfork.s
cc $CFLAGS -c -o obj/src/setjmp/x86_64/longjmp.o src/setjmp/x86_64/longjmp.s
cc $CFLAGS -c -o obj/src/setjmp/x86_64/setjmp.o src/setjmp/x86_64/setjmp.s
cc $CFLAGS -c -o obj/src/signal/x86_64/restore.o src/signal/x86_64/restore.s
cc $CFLAGS -c -o obj/src/signal/x86_64/sigsetjmp.o src/signal/x86_64/sigsetjmp.s
cc $CFLAGS -c -o obj/src/thread/x86_64/__unmapself.o src/thread/x86_64/__unmapself.s
cc $CFLAGS -c -o obj/src/thread/x86_64/clone.o src/thread/x86_64/clone.s
cc $CFLAGS -c -o obj/src/thread/x86_64/syscall_cp.o src/thread/x86_64/syscall_cp.s
mkdir -p obj/src/fenv/$ARCH
mkdir -p obj/src/ldso/$ARCH
mkdir -p obj/src/process/$ARCH
mkdir -p obj/src/setjmp/$ARCH
mkdir -p obj/src/signal/$ARCH
mkdir -p obj/src/string/$ARCH
mkdir -p obj/src/thread/$ARCH

cc $CFLAGS -c -o obj/src/fenv/$ARCH/fenv.o src/fenv/$ARCH/fenv.s
cc $CFLAGS -c -o obj/src/ldso/$ARCH/dlsym.o src/ldso/$ARCH/dlsym.s
cc $CFLAGS -c -o obj/src/ldso/$ARCH/tlsdesc.o src/ldso/$ARCH/tlsdesc.s
cc $CFLAGS -c -o obj/src/process/$ARCH/vfork.o src/process/$ARCH/vfork.s
cc $CFLAGS -c -o obj/src/setjmp/$ARCH/longjmp.o src/setjmp/$ARCH/longjmp.s
cc $CFLAGS -c -o obj/src/setjmp/$ARCH/setjmp.o src/setjmp/$ARCH/setjmp.s
cc $CFLAGS -c -o obj/src/signal/$ARCH/restore.o src/signal/$ARCH/restore.s
cc $CFLAGS -c -o obj/src/signal/$ARCH/sigsetjmp.o src/signal/$ARCH/sigsetjmp.s
cc $CFLAGS -c -o obj/src/thread/$ARCH/__unmapself.o src/thread/$ARCH/__unmapself.s
cc $CFLAGS -c -o obj/src/thread/$ARCH/clone.o src/thread/$ARCH/clone.s
cc $CFLAGS -c -o obj/src/thread/$ARCH/syscall_cp.o src/thread/$ARCH/syscall_cp.s

cc $CFLAGS -fno-stack-protector -c -o obj/src/env/__init_tls.o src/env/__init_tls.c
cc $CFLAGS -fno-stack-protector -c -o obj/src/env/__libc_start_main.o src/env/__libc_start_main.c
cc $CFLAGS -fno-stack-protector -c -o obj/src/env/__stack_chk_fail.o src/env/__stack_chk_fail.c
cc $CFLAGS -fno-stack-protector -c -o obj/src/thread/x86_64/__set_thread_area.o src/thread/x86_64/__set_thread_area.s
cc $CFLAGS -fno-stack-protector -c -o obj/src/thread/$ARCH/__set_thread_area.o src/thread/$ARCH/__set_thread_area.s
cc $CFLAGS -fno-tree-loop-distribute-patterns -c -o obj/src/string/memcmp.o src/string/memcmp.c
cc $CFLAGS -fno-tree-loop-distribute-patterns -c -o obj/src/string/x86_64/memmove.o src/string/x86_64/memmove.s
cc $CFLAGS -fno-tree-loop-distribute-patterns -fno-stack-protector -c -o obj/src/string/x86_64/memcpy.o src/string/x86_64/memcpy.s
cc $CFLAGS -fno-tree-loop-distribute-patterns -fno-stack-protector -c -o obj/src/string/x86_64/memset.o src/string/x86_64/memset.s
cc $CFLAGS -fno-tree-loop-distribute-patterns -c -o obj/src/string/$ARCH/memmove.o src/string/$ARCH/memmove.s
cc $CFLAGS -fno-tree-loop-distribute-patterns -fno-stack-protector -c -o obj/src/string/$ARCH/memcpy.o src/string/$ARCH/memcpy.s
cc $CFLAGS -fno-tree-loop-distribute-patterns -fno-stack-protector -c -o obj/src/string/$ARCH/memset.o src/string/$ARCH/memset.s

ar rcs $PREFIX/lib/libc.a `find obj/src -name '*.o'`
cd ..
Expand All @@ -258,8 +193,8 @@ if [ $# -gt 0 ]; then
fi

if tty -s; then
export USER=$(whoami)
export HOSTNAME=$(hostname)
export PS1='$USER@$HOSTNAME:$PWD\$ '
export USER=$(whoami)
export HOSTNAME=$(hostname)
export PS1='$USER@$HOSTNAME:$PWD\$ '
exec /bin/sh
fi
8 changes: 4 additions & 4 deletions lib/tcc/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ XCC = $(XTCC)
XAR = $(AR)
XFLAGS-unx = -B$(TOPSRC)
XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include
XFLAGS = $(XFLAGS$(XCFG)) -I$(TOP)
XFLAGS = $(XFLAGS$(XCFG)) -I$(TOP) -D__SOFT_FP__
BFLAGS = -bt
XCFG = $(or $(findstring -win,$T),-unx)
S = $(if $(findstring yes,$(SILENT)),@$(info * $@))
Expand All @@ -24,7 +24,7 @@ arm-libtcc1-usegcc ?= no

# This makes bounds checking 40%..60% faster.
x86_64-libtcc1-usegcc=yes
i386-libtcc1-usegcc=yes
# i386-libtcc1-usegcc=yes

ifeq "$($(T)-libtcc1-usegcc)" "yes"
XCC = $(CC)
Expand All @@ -48,8 +48,8 @@ DSO_O = dsohandle.o
RT_C := $(wildcard rt/*.c)
RT_O := $(patsubst rt/%.c,rt/%.o,$(RT_C))

I386_O = $(RT_O) alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O)
X86_64_O = $(RT_O) lib-x86_64.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O)
I386_O = $(RT_O) syscall-i386.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O)
X86_64_O = $(RT_O) syscall-x86_64.o lib-x86_64.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O)
ARM_O = $(RT_O) armeabi.o alloca.o armflush.o stdatomic.o atomic.o builtin.o $(BT_O)
ARM64_O = lib-arm64.o stdatomic.o atomic.o builtin.o $(BT_O)
RISCV64_O = lib-arm64.o stdatomic.o atomic.o builtin.o $(BT_O)
Expand Down
Loading

0 comments on commit 87011a0

Please sign in to comment.