Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
1618c10
feat: 支持源码编译第三方库
Jun 10, 2026
1b47179
support online comiler
Ga1axy0 Jun 10, 2026
5f2ee9b
merge auto-run change
Ga1axy0 Jun 10, 2026
3b0d7ae
fix: grep return enosy
Ga1axy0 Jun 10, 2026
ab1bed2
chore: 修改submodule路径,从CosmOS-rootfs/改为rootfs/
Justin-Nickel-Wu Jun 10, 2026
7db5649
chore: 修改rust版本到2025-01-18
Justin-Nickel-Wu Jun 10, 2026
4a76240
chore: 将两个来自于github的依赖打包放入本地vendor目录下,实现离线构建。
Justin-Nickel-Wu Jun 10, 2026
a6a26ab
chore: 删除不必要rust依赖
Justin-Nickel-Wu Jun 10, 2026
1de36ab
chore: 修改qemu启动参数为smp=1,m=1g,并对应修改os中内存地址范围(共1g内存)
Justin-Nickel-Wu Jun 10, 2026
28ea521
chore: 修改.carge为别名,编译时恢复
Justin-Nickel-Wu Jun 10, 2026
61a9e5d
chore: 修改makefile。现在make run会吧sd-card.img复制一份,并挂载复制结果,避免写坏测试盘。
Justin-Nickel-Wu Jun 11, 2026
d000805
fix: 修复 iozone 下 ext4 写回与 unlink 卡住问题
Justin-Nickel-Wu Jun 11, 2026
83f141f
feat: 修改github workflow
Justin-Nickel-Wu Jun 11, 2026
8df44a7
refactor: 优化workflow输出内容
Justin-Nickel-Wu Jun 11, 2026
bd02509
refactor: 更新评测流程。
Justin-Nickel-Wu Jun 11, 2026
a812779
refactor: 优化workflow,现在提交到gitlab的只有快照。
Justin-Nickel-Wu Jun 11, 2026
e2c191d
refactor: workflow会展开所有submodule,然后推送到gitlab main分支
Justin-Nickel-Wu Jun 11, 2026
fd21f77
refactor: 为了避免单次提交过大,workflow将rootfs中的内容分两次提交。
Justin-Nickel-Wu Jun 11, 2026
be73a47
test: support ltp auto run
Ga1axy0 Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 98 additions & 33 deletions .github/workflows/mirror-main-to-gitlab.yml
Original file line number Diff line number Diff line change
@@ -1,65 +1,130 @@
name: Mirror Main to GitLab
name: Mirror Branch to GitLab

on:
push:
branches:
- main

permissions:
contents: write
contents: read

jobs:
mirror-main:
mirror-branch:
runs-on: ubuntu-latest
if: github.ref_type == 'branch'

steps:
- name: Checkout main
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive

- name: Build evaluation snapshot commit
id: snapshot
- name: Flatten submodules and push temporary commit
id: mirror
env:
GITLAB_MIRROR_URL: ${{ secrets.GITLAB_MIRROR_URL }}
run: |
set -euo pipefail

git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# 推送指定 ref,最多重试 5 次以规避临时网络波动。
retry_git_push() {
local source_ref="$1"
local target_branch="$2"
local attempt
for attempt in 1 2 3 4 5; do
echo "[mirror] step: push ${source_ref} to GitLab ${target_branch} (attempt ${attempt}/5)"
if git push --force gitlab "${source_ref}:refs/heads/${target_branch}"; then
echo "[mirror] done: push ${source_ref} to GitLab ${target_branch}"
return 0
fi
if [ "$attempt" -eq 5 ]; then
echo "::error::Failed to push to GitLab after 5 attempts"
return 1
fi
sleep "$((attempt * 5))"
done
}

source_commit_message_file="$(mktemp)"
git log -1 --pretty=%B > "$source_commit_message_file"
# 先用临时分支上传最大 blob,降低最终 main 推送的单包大小。
seed_large_blob() {
local seed_file="CosmOS-rootfs/third-party/binutils-2.41.tar.xz"
local seed_branch="mirror-seed-large-blob"
local seed_index
local seed_tree_sha
local seed_commit_sha
local parent_args=()

bash scripts/export-eval-tree.sh
if [ ! -f "$seed_file" ]; then
echo "[mirror] skip: seed file not found: ${seed_file}"
return
fi

tree_sha="$(git write-tree)"
if git show-ref --verify --quiet refs/remotes/gitlab/main; then
parent_args=(-p refs/remotes/gitlab/main)
fi

if git ls-remote --exit-code --heads origin gitlab-output >/dev/null 2>&1; then
git fetch --depth=1 origin gitlab-output:refs/remotes/origin/gitlab-output
commit_sha="$(git commit-tree "$tree_sha" -F "$source_commit_message_file" -p refs/remotes/origin/gitlab-output)"
else
commit_sha="$(git commit-tree "$tree_sha" -F "$source_commit_message_file")"
fi
echo "[mirror] step: create seed commit for ${seed_file}"
seed_index="$(mktemp)"
rm -f "$seed_index"
GIT_INDEX_FILE="$seed_index" git add -- "$seed_file"
seed_tree_sha="$(GIT_INDEX_FILE="$seed_index" git write-tree)"
seed_commit_sha="$(git commit-tree "$seed_tree_sha" "${parent_args[@]}" -m "Seed large mirror blob ${seed_file}")"
rm -f "$seed_index"
echo "[mirror] done: create seed commit ${seed_commit_sha}"

git update-ref refs/heads/gitlab-output "$commit_sha"
echo "commit_sha=$commit_sha" >> "$GITHUB_OUTPUT"
MIRROR_SEED_BRANCH="$seed_branch"
MIRROR_SEED_COMMIT_SHA="$seed_commit_sha"
retry_git_push "$seed_commit_sha" "$seed_branch"
}

- name: Push snapshot branch to GitHub
run: |
set -euo pipefail
git push --force origin refs/heads/gitlab-output:refs/heads/gitlab-output
# 创建完整展开提交,父提交接 seed,确保最终推送不再携带最大 blob。
create_mirror_commit() {
local full_tree_sha
local mirror_commit_sha
local parent_args=()

# 将 gitlab-output 快照分支同步到 GitLab 的 main 分支。
- name: Push snapshot to GitLab main
env:
GITLAB_MIRROR_URL: ${{ secrets.GITLAB_MIRROR_URL }}
run: |
set -euo pipefail
if [ -n "$MIRROR_SEED_COMMIT_SHA" ]; then
parent_args=(-p "$MIRROR_SEED_COMMIT_SHA")
elif git show-ref --verify --quiet refs/remotes/gitlab/main; then
parent_args=(-p refs/remotes/gitlab/main)
fi

full_tree_sha="$(git write-tree)"
mirror_commit_sha="$(git commit-tree "$full_tree_sha" "${parent_args[@]}" -m "Mirror ${GITHUB_REF_NAME}@${GITHUB_SHA} with flattened submodules")"
echo "$mirror_commit_sha"
}

MIRROR_SEED_BRANCH=""
MIRROR_SEED_COMMIT_SHA=""

git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

if [ -z "$GITLAB_MIRROR_URL" ]; then
echo "::error::Missing GITLAB_MIRROR_URL secret"
exit 1
fi

# 在当前 GitHub 分支上创建临时提交,避免生成无父快照提交。
echo "[mirror] step: prepare source branch ${GITHUB_REF_NAME}"
git checkout -B "$GITHUB_REF_NAME" "$GITHUB_SHA"
echo "[mirror] done: prepare source branch ${GITHUB_REF_NAME}"

echo "[mirror] step: flatten submodules"
bash scripts/export-eval-tree.sh
echo "[mirror] done: flatten submodules"

echo "[mirror] step: add GitLab remote"
git remote add gitlab "$GITLAB_MIRROR_URL"
git push --force gitlab refs/heads/gitlab-output:refs/heads/main
echo "[mirror] done: add GitLab remote"

echo "[mirror] step: fetch GitLab main"
git fetch --depth=1 gitlab main:refs/remotes/gitlab/main || true
echo "[mirror] done: fetch GitLab main"

seed_large_blob

echo "[mirror] step: create temporary mirror commit"
mirror_commit_sha="$(create_mirror_commit)"
echo "[mirror] done: create temporary mirror commit ${mirror_commit_sha}"

retry_git_push "$mirror_commit_sha" main
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
!.vscode/settings.json
.idea/*
os/target/*
os/.cargo/
os/.idea/*
os/src/link_app.S
os/last-*
Expand All @@ -13,6 +14,7 @@ os/.gdb_history
os/qemu-net.pcap
user/build/*
user/target/*
user/.cargo/
user/.idea/*
user/Cargo.lock
fs/Cargo.lock
Expand All @@ -34,4 +36,4 @@ sdcard-rv.img
second-easyfs.img
second-fat32.img
bootloader/loongarch64-direct/target/*
sdcard-la.img
sdcard-la.img
2 changes: 1 addition & 1 deletion CosmOS-rootfs
Submodule CosmOS-rootfs updated 505 files
71 changes: 57 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,32 @@ USER_MODE ?= release
USER_BIN_DIR := user/target/$(TARGET)/$(USER_MODE)
KERNEL_RV_ELF := os/target/$(TARGET)/release/os
QEMU ?= qemu-system-riscv64
MEM ?= 2G
SMP ?= 8
MEM ?= 1G
SMP ?= 1
TEST_FS ?= sdcard-rv.img
# make run 使用写时复制副本,避免 QEMU 写坏原始测试镜像。
RUN_TEST_FS ?= .make/sdcard-rv-run.img
QEMU_NETDEV ?= user,id=net
QEMU_TRACE_ARGS ?=
QEMU_COMP_BLK_ARGS = -drive file=$(TEST_FS),if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
QEMU_COMP_BLK_ARGS = -drive file=$(RUN_TEST_FS),if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
QEMU_COMP_EXTRA_BLK_ARGS = -drive file=disk.img,if=none,format=raw,id=x1 -device virtio-blk-device,drive=x1,bus=virtio-mmio-bus.1

STAMP_DIR := .make
USER_BUILD_STAMP := $(STAMP_DIR)/user-build.stamp
KERNEL_BUILD_STAMP := $(STAMP_DIR)/kernel-build.stamp
USER_BUILD_DEPS := user/Makefile user/Cargo.toml $(shell find user/src -type f | sort)
KERNEL_BUILD_DEPS := os/Makefile os/Cargo.toml os/build.rs $(shell find os/src fs/src -type f | sort)
ROOTFS_FILES := $(shell find rootfs -type f | sort)
ROOTFS_REPO := CosmOS-rootfs
ROOTFS_DIR := $(ROOTFS_REPO)/rootfs
ROOTFS_FILES := $(shell if [ -d $(ROOTFS_DIR) ]; then find $(ROOTFS_DIR) -type f | sort; fi)
OPTIONAL_RUNTIME_FILES := $(wildcard lib/musl/ar lib/glibc/ar)

.PHONY: all submodules docker build_docker fmt user-apps clean run run-trace run-comp-rv debug gdbserver gdbclient
.PHONY: all submodules cargo-config docker build_docker fmt user-apps rootfs clean run run-trace run-comp-rv debug gdbserver gdbclient check-kernel check-user-apps check-rootfs prepare-run-test-fs

all:
$(MAKE) submodules
$(MAKE) kernel-rv kernel-la disk.img
$(MAKE) cargo-config
$(MAKE) user-apps kernel-rv kernel-la disk.img

# 拉取所有子模块,确保后续构建依赖完整。
submodules:
Expand All @@ -35,16 +40,22 @@ submodules:
echo "No .gitmodules found; assuming dependencies are already vendored."; \
fi

# 评测会过滤隐藏目录,构建前从非隐藏目录恢复 Cargo 配置。
cargo-config:
@mkdir -p os/.cargo user/.cargo
@cp os/cargo-config/config.toml os/.cargo/config.toml
@cp user/cargo-config/config.toml user/.cargo/config.toml

$(STAMP_DIR):
mkdir -p $@

$(USER_BUILD_STAMP): $(USER_BUILD_DEPS) | $(STAMP_DIR)
$(USER_BUILD_STAMP): $(USER_BUILD_DEPS) | $(STAMP_DIR) cargo-config
$(MAKE) -C user build
touch $@

user-apps: $(USER_BUILD_STAMP)

$(KERNEL_BUILD_STAMP): $(KERNEL_BUILD_DEPS) | $(STAMP_DIR)
$(KERNEL_BUILD_STAMP): $(KERNEL_BUILD_DEPS) | $(STAMP_DIR) cargo-config
$(MAKE) -C os kernel
touch $@

Expand All @@ -55,21 +66,53 @@ kernel-la: kernel-rv
@echo "warning: LoongArch kernel is not implemented in this repository yet; using kernel-rv as a temporary placeholder." >&2
cp kernel-rv $@

disk.img: $(USER_BUILD_STAMP) $(ROOTFS_FILES) $(OPTIONAL_RUNTIME_FILES) scripts/pack-disk-img.sh
./scripts/pack-disk-img.sh rootfs $(USER_BIN_DIR) $@
rootfs:
$(MAKE) -C $(ROOTFS_REPO) rootfs-init

check-kernel:
@test -x kernel-rv || { \
echo "missing kernel-rv; run 'make all' first" >&2; \
exit 1; \
}

check-user-apps:
@test -d "$(USER_BIN_DIR)" || { \
echo "missing user binaries in $(USER_BIN_DIR); run 'make all' first" >&2; \
exit 1; \
}

check-rootfs: rootfs
@test -d "$(ROOTFS_DIR)" || { \
echo "missing rootfs directory $(ROOTFS_DIR); run 'make all' first" >&2; \
exit 1; \
}
@test -d "$(ROOTFS_DIR)/root" || { \
echo "rootfs is incomplete under $(ROOTFS_DIR); run 'make all' first" >&2; \
exit 1; \
}

disk.img: check-user-apps check-rootfs $(OPTIONAL_RUNTIME_FILES) $(ROOTFS_FILES) scripts/pack-disk-img.sh
./scripts/pack-disk-img.sh $(ROOTFS_DIR) $(USER_BIN_DIR) $@

prepare-run-test-fs: | $(STAMP_DIR)
@if [ ! -f "$(TEST_FS)" ]; then \
echo "Test image not found: $(TEST_FS)"; \
exit 2; \
fi
cp -c "$(TEST_FS)" "$(RUN_TEST_FS)" 2>/dev/null || cp --reflink=auto "$(TEST_FS)" "$(RUN_TEST_FS)" 2>/dev/null || cp "$(TEST_FS)" "$(RUN_TEST_FS)"

run: kernel-rv disk.img
run: check-kernel disk.img prepare-run-test-fs
$(QEMU) -machine virt -kernel kernel-rv -m $(MEM) -nographic -smp $(SMP) -bios default $(QEMU_COMP_BLK_ARGS) -device virtio-net-device,netdev=net -netdev $(QEMU_NETDEV) -no-reboot -rtc base=utc $(QEMU_COMP_EXTRA_BLK_ARGS) $(QEMU_TRACE_ARGS)

run-trace: QEMU_TRACE_ARGS = -d int,in_asm -D qemu.log
run-trace: run

run-comp-rv: run

debug: kernel-rv disk.img
debug: check-kernel disk.img
$(MAKE) -C os debug

gdbserver: kernel-rv disk.img
gdbserver: check-kernel disk.img
$(MAKE) -C os gdbserver

gdbclient:
Expand All @@ -85,6 +128,6 @@ fmt:
cd fs; cargo fmt; cd ../fs-fuse; cargo fmt; cd ../os; cargo fmt; cd ../user; cargo fmt; cd ..

clean:
rm -rf $(STAMP_DIR) disk.img kernel-rv kernel-la
rm -rf $(STAMP_DIR) $(RUN_TEST_FS) disk.img kernel-rv kernel-la os/.cargo user/.cargo
$(MAKE) -C os clean
$(MAKE) -C user clean
1 change: 1 addition & 0 deletions fs/src/errno.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use ext4_rs::{Ext4, Ext4Error};

#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(missing_docs)]
pub enum FS_ERRNO {
EPERM = 1, // Operation not permitted
Expand Down
6 changes: 6 additions & 0 deletions fs/src/ext4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,12 @@ impl VfsNode for Ext4Inode {
ext4.write_at(self.inode_num, offset, buf).unwrap_or(0)
}

/// ext4 写入需要保留 ENOSPC/ENOTSUP,供 page cache 回写路径处理失败页。
fn write_at_result(&self, offset: usize, buf: &[u8]) -> Result<usize, FS_ERRNO> {
let ext4 = self.fs.ext4.lock();
ext4.write_at(self.inode_num, offset, buf).map_err(FS_ERRNO::from)
}

fn ino(&self) -> u64 {
self.inode_num as u64
}
Expand Down
22 changes: 22 additions & 0 deletions fs/src/vfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ pub trait VfsNode: Send + Sync + Any + Debug {
}
fn read_at(&self, offset: usize, buf: &mut [u8]) -> usize;
fn write_at(&self, offset: usize, buf: &[u8]) -> usize;
/// 向固定偏移写入数据,并保留底层文件系统返回的真实错误。
fn write_at_result(&self, offset: usize, buf: &[u8]) -> Result<usize, FS_ERRNO> {
Ok(self.write_at(offset, buf))
}
/// Stable inode number for stat-like metadata.
fn ino(&self) -> u64 {
0
Expand Down Expand Up @@ -454,6 +458,24 @@ impl Inode {
written
}

/// 向固定偏移写入数据,并把底层错误传给调用方。
pub fn write_at_result(&self, offset: usize, buf: &[u8]) -> Result<usize, FS_ERRNO> {
let written = self.inner.write_at_result(offset, buf).map_err(|err| {
log::error!(
"[vfs] write_at_result failed: ino={} offset={} len={} errno={}",
self.ino(),
offset,
buf.len(),
err as i32
);
err
})?;
if written != 0 {
self.invalidate_stat_cache();
}
Ok(written)
}

pub fn ino(&self) -> u64 {
self.inner.ino()
}
Expand Down
Binary file removed lib/glibc/ar
Binary file not shown.
Binary file removed lib/musl/ar
Binary file not shown.
4 changes: 2 additions & 2 deletions os/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
riscv = { path = "../vendor/riscv", features = ["inline-asm"] }
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
log = "0.4"
buddy_system_allocator = "0.6"
Expand All @@ -16,7 +16,7 @@ xmas-elf = "0.7.0"
virtio-drivers = "0.12.0"
fs = { path = "../fs" }
hashbrown = "0.12.3"
smoltcp = { git = "https://github.com/KyleMao2023/smoltcp", branch = "os", default-features = false, features = [
smoltcp = { path = "../vendor/smoltcp", default-features = false, features = [
"alloc",
"medium-ethernet",
"proto-ipv4",
Expand Down
Loading
Loading