fix: Cross-compilation & build tools script, IoPort fix
This commit is contained in:
@@ -4,3 +4,6 @@
|
|||||||
*.iso
|
*.iso
|
||||||
*.hdd
|
*.hdd
|
||||||
qemu.log
|
qemu.log
|
||||||
|
toolchain/local/
|
||||||
|
toolchain/build/
|
||||||
|
toolchain/src/
|
||||||
|
|||||||
@@ -139,6 +139,10 @@ run-hdd-bios: $(IMAGE_NAME).hdd
|
|||||||
-hda $(IMAGE_NAME).hdd \
|
-hda $(IMAGE_NAME).hdd \
|
||||||
$(QEMUFLAGS)
|
$(QEMUFLAGS)
|
||||||
|
|
||||||
|
.PHONY: toolchain
|
||||||
|
toolchain:
|
||||||
|
./toolchain/build-toolchain.sh
|
||||||
|
|
||||||
limine/limine:
|
limine/limine:
|
||||||
rm -rf limine
|
rm -rf limine
|
||||||
git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1
|
git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1
|
||||||
|
|||||||
+13
-3
@@ -17,17 +17,27 @@ ifeq ($(filter $(ARCH),aarch64 loongarch64 riscv64 x86_64),)
|
|||||||
$(error Architecture $(ARCH) not supported)
|
$(error Architecture $(ARCH) not supported)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Auto-detect x86_64-elf cross compiler from toolchain/local/.
|
||||||
|
ifeq ($(ARCH),x86_64)
|
||||||
|
TOOLCHAIN_PREFIX := $(shell cd .. && pwd)/toolchain/local/bin/x86_64-elf-
|
||||||
|
ifneq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),)
|
||||||
|
CC := $(TOOLCHAIN_PREFIX)gcc
|
||||||
|
CXX := $(TOOLCHAIN_PREFIX)g++
|
||||||
|
AR := $(TOOLCHAIN_PREFIX)ar
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
# User controllable C compiler command.
|
# User controllable C compiler command.
|
||||||
CC := cc
|
CC ?= cc
|
||||||
|
|
||||||
# User controllable C++ compiler command.
|
# User controllable C++ compiler command.
|
||||||
CXX := c++
|
CXX ?= c++
|
||||||
|
|
||||||
# User controllable Objective C compiler command.
|
# User controllable Objective C compiler command.
|
||||||
OBJC := g++
|
OBJC := g++
|
||||||
|
|
||||||
# User controllable archiver command.
|
# User controllable archiver command.
|
||||||
AR := ar
|
AR ?= ar
|
||||||
|
|
||||||
# User controllable C flags.
|
# User controllable C flags.
|
||||||
CFLAGS := -g -O2 -pipe
|
CFLAGS := -g -O2 -pipe
|
||||||
|
|||||||
+16
-11
@@ -23,20 +23,25 @@ namespace Io {
|
|||||||
asm ("outl %0, %1" : : "a"(value), "Nd"(port) : "memory");
|
asm ("outl %0, %1" : : "a"(value), "Nd"(port) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO fix */
|
inline uint8_t In8(uint16_t port) {
|
||||||
// inline uint8_t In8(uint16_t port) {
|
uint8_t result;
|
||||||
// asm ("inb %0" : : "Nd"(port) : "memory");
|
asm volatile("inb %1, %0" : "=a"(result) : "Nd"(port) : "memory");
|
||||||
// }
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// inline uint16_t In16(uint16_t port) {
|
inline uint16_t In16(uint16_t port) {
|
||||||
// asm ("inw %0" : : "Nd"(port) : "memory");
|
uint16_t result;
|
||||||
// }
|
asm volatile("inw %1, %0" : "=a"(result) : "Nd"(port) : "memory");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// inline uint32_t In32(uint16_t port) {
|
inline uint32_t In32(uint16_t port) {
|
||||||
// asm ("inl %0" : : "Nd"(port) : "memory");
|
uint32_t result;
|
||||||
// }
|
asm volatile("inl %1, %0" : "=a"(result) : "Nd"(port) : "memory");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
inline void IoPortWait() {
|
inline void IoPortWait() {
|
||||||
Out8(0x80, 0);
|
Out8(0, 0x80);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Executable
+163
@@ -0,0 +1,163 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# build-toolchain.sh — Build an x86_64-elf cross compiler (Binutils + GCC)
|
||||||
|
# for bare-metal kernel development.
|
||||||
|
#
|
||||||
|
# Usage: ./toolchain/build-toolchain.sh
|
||||||
|
#
|
||||||
|
# The toolchain is installed to toolchain/local/ and provides:
|
||||||
|
# x86_64-elf-gcc, x86_64-elf-g++, x86_64-elf-ld, x86_64-elf-ar, etc.
|
||||||
|
#
|
||||||
|
# This script is idempotent — it skips steps whose output already exists.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ── Versions ──────────────────────────────────────────────────────────────────
|
||||||
|
BINUTILS_VERSION="2.43.1"
|
||||||
|
GCC_VERSION="14.2.0"
|
||||||
|
TARGET="x86_64-elf"
|
||||||
|
|
||||||
|
# ── Directories ───────────────────────────────────────────────────────────────
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PREFIX="${SCRIPT_DIR}/local"
|
||||||
|
SRC_DIR="${SCRIPT_DIR}/src"
|
||||||
|
BUILD_DIR="${SCRIPT_DIR}/build"
|
||||||
|
|
||||||
|
BINUTILS_TARBALL="binutils-${BINUTILS_VERSION}.tar.xz"
|
||||||
|
GCC_TARBALL="gcc-${GCC_VERSION}.tar.xz"
|
||||||
|
BINUTILS_URL="https://ftp.gnu.org/gnu/binutils/${BINUTILS_TARBALL}"
|
||||||
|
GCC_URL="https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/${GCC_TARBALL}"
|
||||||
|
|
||||||
|
# Number of parallel jobs for make.
|
||||||
|
JOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)"
|
||||||
|
|
||||||
|
# ── Color helpers ─────────────────────────────────────────────────────────────
|
||||||
|
bold() { printf '\033[1m%s\033[0m\n' "$*"; }
|
||||||
|
green() { printf '\033[1;32m%s\033[0m\n' "$*"; }
|
||||||
|
red() { printf '\033[1;31m%s\033[0m\n' "$*"; }
|
||||||
|
|
||||||
|
# ── Prerequisite check ────────────────────────────────────────────────────────
|
||||||
|
check_prereqs() {
|
||||||
|
local missing=()
|
||||||
|
for cmd in gcc g++ make bison flex texinfo makeinfo tar wget; do
|
||||||
|
# 'texinfo' is a package name; the actual binary is 'makeinfo'.
|
||||||
|
[[ "$cmd" == "texinfo" ]] && continue
|
||||||
|
if ! command -v "$cmd" &>/dev/null; then
|
||||||
|
missing+=("$cmd")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( ${#missing[@]} )); then
|
||||||
|
red "Missing required tools: ${missing[*]}"
|
||||||
|
echo "On Debian/Ubuntu: sudo apt install build-essential bison flex libgmp-dev libmpc-dev libmpfr-dev texinfo wget"
|
||||||
|
echo "On Fedora: sudo dnf install gcc gcc-c++ make bison flex gmp-devel mpfr-devel libmpc-devel texinfo wget"
|
||||||
|
echo "On Arch: sudo pacman -S base-devel gmp mpfr libmpc texinfo wget"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Early exit if already built ───────────────────────────────────────────────
|
||||||
|
if [[ -x "${PREFIX}/bin/${TARGET}-gcc" ]]; then
|
||||||
|
green "Cross compiler already built: ${PREFIX}/bin/${TARGET}-gcc"
|
||||||
|
"${PREFIX}/bin/${TARGET}-gcc" --version | head -1
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
bold "=== Building ${TARGET} cross compiler ==="
|
||||||
|
bold " Binutils ${BINUTILS_VERSION} | GCC ${GCC_VERSION}"
|
||||||
|
bold " Install prefix: ${PREFIX}"
|
||||||
|
bold " Parallel jobs: ${JOBS}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
check_prereqs
|
||||||
|
|
||||||
|
export PATH="${PREFIX}/bin:${PATH}"
|
||||||
|
|
||||||
|
mkdir -p "${SRC_DIR}" "${BUILD_DIR}" "${PREFIX}"
|
||||||
|
|
||||||
|
# ── Download sources ──────────────────────────────────────────────────────────
|
||||||
|
download() {
|
||||||
|
local url="$1" dest="$2"
|
||||||
|
if [[ -f "${dest}" ]]; then
|
||||||
|
bold "Already downloaded: $(basename "${dest}")"
|
||||||
|
else
|
||||||
|
bold "Downloading $(basename "${dest}")..."
|
||||||
|
wget -q --show-progress -O "${dest}" "${url}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
download "${BINUTILS_URL}" "${SRC_DIR}/${BINUTILS_TARBALL}"
|
||||||
|
download "${GCC_URL}" "${SRC_DIR}/${GCC_TARBALL}"
|
||||||
|
|
||||||
|
# ── Extract sources ───────────────────────────────────────────────────────────
|
||||||
|
extract() {
|
||||||
|
local tarball="$1" name="$2"
|
||||||
|
if [[ -d "${SRC_DIR}/${name}" ]]; then
|
||||||
|
bold "Already extracted: ${name}"
|
||||||
|
else
|
||||||
|
bold "Extracting ${name}..."
|
||||||
|
tar xf "${tarball}" -C "${SRC_DIR}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
extract "${SRC_DIR}/${BINUTILS_TARBALL}" "binutils-${BINUTILS_VERSION}"
|
||||||
|
extract "${SRC_DIR}/${GCC_TARBALL}" "gcc-${GCC_VERSION}"
|
||||||
|
|
||||||
|
# ── Download GCC prerequisites (GMP, MPFR, MPC, ISL) ─────────────────────────
|
||||||
|
if [[ ! -d "${SRC_DIR}/gcc-${GCC_VERSION}/gmp" ]]; then
|
||||||
|
bold "Downloading GCC prerequisites..."
|
||||||
|
(cd "${SRC_DIR}/gcc-${GCC_VERSION}" && ./contrib/download_prerequisites)
|
||||||
|
else
|
||||||
|
bold "GCC prerequisites already present."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Build Binutils ────────────────────────────────────────────────────────────
|
||||||
|
if [[ -x "${PREFIX}/bin/${TARGET}-ld" ]]; then
|
||||||
|
bold "Binutils already installed — skipping."
|
||||||
|
else
|
||||||
|
bold "Building Binutils ${BINUTILS_VERSION}..."
|
||||||
|
rm -rf "${BUILD_DIR}/binutils"
|
||||||
|
mkdir -p "${BUILD_DIR}/binutils"
|
||||||
|
(
|
||||||
|
cd "${BUILD_DIR}/binutils"
|
||||||
|
"${SRC_DIR}/binutils-${BINUTILS_VERSION}/configure" \
|
||||||
|
--target="${TARGET}" \
|
||||||
|
--prefix="${PREFIX}" \
|
||||||
|
--with-sysroot \
|
||||||
|
--disable-nls \
|
||||||
|
--disable-werror
|
||||||
|
make -j"${JOBS}"
|
||||||
|
make install
|
||||||
|
)
|
||||||
|
green "Binutils installed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Build GCC ─────────────────────────────────────────────────────────────────
|
||||||
|
if [[ -x "${PREFIX}/bin/${TARGET}-gcc" ]]; then
|
||||||
|
bold "GCC already installed — skipping."
|
||||||
|
else
|
||||||
|
bold "Building GCC ${GCC_VERSION}..."
|
||||||
|
rm -rf "${BUILD_DIR}/gcc"
|
||||||
|
mkdir -p "${BUILD_DIR}/gcc"
|
||||||
|
(
|
||||||
|
cd "${BUILD_DIR}/gcc"
|
||||||
|
"${SRC_DIR}/gcc-${GCC_VERSION}/configure" \
|
||||||
|
--target="${TARGET}" \
|
||||||
|
--prefix="${PREFIX}" \
|
||||||
|
--disable-nls \
|
||||||
|
--enable-languages=c,c++ \
|
||||||
|
--without-headers \
|
||||||
|
--disable-hosted-libstdcxx
|
||||||
|
make -j"${JOBS}" all-gcc
|
||||||
|
make -j"${JOBS}" all-target-libgcc
|
||||||
|
make install-gcc
|
||||||
|
make install-target-libgcc
|
||||||
|
)
|
||||||
|
green "GCC installed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Done ──────────────────────────────────────────────────────────────────────
|
||||||
|
echo
|
||||||
|
green "=== Cross compiler ready ==="
|
||||||
|
"${PREFIX}/bin/${TARGET}-gcc" --version | head -1
|
||||||
|
"${PREFIX}/bin/${TARGET}-ld" --version | head -1
|
||||||
Reference in New Issue
Block a user