Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,4 @@ mnt/
**/bin/
**/build/
.venv/
external/

pushTags.sh
external/
130 changes: 61 additions & 69 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@


# Object files grouped by functionality
FILES = \
./build/kernel.asm.o \
./build/kernel.o \
Expand Down Expand Up @@ -72,7 +69,7 @@ prepare_dirs:

all: build install

build: prepare_dirs fonts ./bin/boot_with_size.bin user_programs ./bin/os.bin
build: prepare_dirs fonts ./bin/boot_with_size.bin ./bin/kernel.bin user_programs ./bin/os.bin
@echo "Build complete! User programs built but not installed to disk image."
@echo "To install user programs to disk image, run: make install"

Expand All @@ -82,82 +79,75 @@ fonts:
install: ./bin/os.bin
ifeq ($(UNAME_S),Linux)
@echo "Installing user programs and assets to disk image (Linux)..."
@# Create mount point if it doesn't exist
@sudo mkdir -p /mnt/d
@# Unmount if already mounted
@sudo umount /mnt/d 2>/dev/null || true
@# Mount the disk image
@sudo mount -t vfat ./bin/os.bin /mnt/d
@# Copy all assets recursively
@sudo cp -r ./assets/* /mnt/d/ 2>/dev/null || true
@# Find and copy all .elf files from programs directory
@find ./assets/etc/default/user/programs -name '*.elf' -exec sudo cp {} /mnt/d/ \;
@# Unmount the disk image
@sudo mount -t vfat ./bin/os.bin /mnt/d || { echo "Failed to mount disk image"; exit 1; }
@if [ -d "./assets" ]; then sudo cp -r ./assets/* /mnt/d/ || { echo "Failed to copy assets"; sudo umount /mnt/d; exit 1; }; fi
@if [ -d "./assets/etc/default/user/programs" ]; then find ./assets/etc/default/user/programs -name '*.elf' -exec sudo cp {} /mnt/d/ \; || { echo "Failed to copy .elf files"; sudo umount /mnt/d; exit 1; }; fi
@sudo umount /mnt/d
@echo "User programs and assets installed to disk image!"
else ifeq ($(UNAME_S),Darwin)
@echo "Attaching disk image (macOS)..."
@bash -c '\
DISK_ID=$$(hdiutil attach -imagekey diskimage-class=CRawDiskImage -nomount ./bin/os.bin | awk "/\\/dev\\// {print \$$1}"); \
echo "diskutil list output for $$DISK_ID:"; \
diskutil list $$DISK_ID; \
PART_DEV=$$(ls /dev/$$(basename $$DISK_ID)s1); \
echo "Partition device: $$PART_DEV"; \
sudo mkdir -p /Volumes/viosmnt; \
sudo mount -t msdos $$PART_DEV /Volumes/viosmnt || { echo "Failed to mount $$PART_DEV"; hdiutil detach $$DISK_ID; exit 1; }; \
echo "Copying files..."; \
sudo cp -r ./assets/* /Volumes/viosmnt/ 2>/dev/null || true; \
find ./assets/etc/default/user/programs -name "*.elf" -exec sudo cp {} /Volumes/viosmnt/ \; ; \
@echo "Preparing disk image for macOS..."
@bash -c "\
set -e; \
echo 'Attaching disk image...'; \
ATTACH_OUTPUT=\$$(hdiutil attach -imagekey diskimage-class=CRawDiskImage -nomount ./bin/os.bin 2>/dev/null); \
DISK_ID=\$$(echo \"\$$ATTACH_OUTPUT\" | grep -o '/dev/disk[0-9]*' | head -1); \
PARTITION_ID=\"\$${DISK_ID}s1\"; \
if [ -z \"\$$DISK_ID\" ]; then echo 'Failed to attach disk image'; exit 1; fi; \
echo \"Attached as \$$DISK_ID, partition \$$PARTITION_ID\"; \
echo 'Formatting partition as FAT32...'; \
diskutil eraseVolume MS-DOS VIOSFAT32 \"\$$PARTITION_ID\" >/dev/null 2>&1 || { echo 'Failed to format partition'; hdiutil detach \"\$$DISK_ID\" 2>/dev/null; exit 1; }; \
echo 'Copying files...'; \
if [ -d './assets' ]; then \
echo 'Copying assets...'; \
cp -r ./assets/* /Volumes/VIOSFAT32/ || { echo 'Failed to copy assets'; diskutil unmount \"\$$PARTITION_ID\"; hdiutil detach \"\$$DISK_ID\" 2>/dev/null; exit 1; }; \
else \
echo 'No assets directory found, skipping...'; \
fi; \
if [ -d './assets/etc/default/user/programs' ]; then \
echo 'Copying .elf files...'; \
find ./assets/etc/default/user/programs -name '*.elf' -exec cp {} /Volumes/VIOSFAT32/ \; || { echo 'Failed to copy .elf files'; diskutil unmount \"\$$PARTITION_ID\"; hdiutil detach \"\$$DISK_ID\" 2>/dev/null; exit 1; }; \
else \
echo 'No programs directory found, skipping...'; \
fi; \
sync; \
echo "Unmounting..."; \
sudo umount /Volumes/viosmnt; \
hdiutil detach $$DISK_ID; \
echo "User programs and assets installed to disk image!"; \
'
echo 'Unmounting for boot sector update...'; \
diskutil unmount \"\$$PARTITION_ID\" >/dev/null 2>&1 || echo 'Unmount failed, continuing...'; \
echo 'Installing custom boot sector...'; \
dd if=./bin/vbr.bin of=\"\$$PARTITION_ID\" bs=512 count=1 conv=notrunc 2>/dev/null || echo 'Warning: Failed to install custom boot sector'; \
hdiutil detach \"\$$DISK_ID\" >/dev/null 2>&1 || echo 'Detach failed, continuing...'; \
echo 'User programs and assets installed to disk image!'; \
"
endif


./bin/kernel.bin: prepare_dirs $(FILES)
i686-elf-gcc $(FLAGS) -T ./src/linker.ld -o ./bin/kernel.bin -ffreestanding -O0 -nostdlib $(FILES)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Document cross-compiler requirement and ensure CI has it installed.

The build requires i686-elf-gcc cross-compiler which is missing in the CI environment, causing pipeline failures.

Consider:

  1. Adding a prerequisites check target to the Makefile
  2. Documenting the cross-compiler requirement in README
  3. Ensuring the CI workflow installs the cross-compiler

Also applies to: 194-194


🏁 Script executed:

#!/bin/bash
# Check if CI workflow installs cross-compiler
echo "Checking for GitHub Actions workflow files..."
fd -t f -e yml -e yaml . .github/workflows | xargs cat | rg -A 5 -B 5 "i686-elf|cross-compiler|gcc"

echo -e "\nChecking for build documentation..."
fd README -t f | xargs rg -i "build|compiler|prerequisite|dependency" -A 3

Length of output: 3605


Add CI installation for i686-elf-gcc and a prereqs check

  • The README already documents the i686-elf-gcc requirement under Build Requirements.
  • Update your GitHub Actions workflow (e.g. .github/workflows/build.yml) to install the cross-compiler before running make. For example:
    - name: Install build dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y \
          build-essential \
          nasm \
          qemu \
          gcc-multilib \
          binutils-i686-elf \
          grub-pc-bin \
          xorriso
  • Add a check-prereqs target in the Makefile to fail early if i686-elf-gcc is missing:
    .PHONY: check-prereqs
    check-prereqs:
      @command -v i686-elf-gcc >/dev/null 2>&1 \
        || { echo >&2 "Error: i686-elf-gcc not found. See README.md #build-requirements."; exit 1; }
    
    # Then invoke this at the top of your default target:
    all: check-prereqs kernel.bin

These changes will ensure the CI environment installs the cross-compiler and that local builds fail fast with a clear error.

🤖 Prompt for AI Agents
In the Makefile at line 124, add a new target named check-prereqs that checks if
i686-elf-gcc is installed by using the command -v i686-elf-gcc and exits with an
error message if not found. Then modify the default all target to depend on
check-prereqs so it runs this check before building kernel.bin. Additionally,
update the GitHub Actions workflow file (e.g., .github/workflows/build.yml) to
include a step that installs i686-elf-gcc and other required dependencies using
apt-get before running make, ensuring the CI environment has the necessary
cross-compiler installed.


./bin/mbr.bin: prepare_dirs ./src/boot/mbr.asm
./bin/boot.bin: prepare_dirs ./src/boot/mbr.asm ./src/boot/vbrEntry.asm ./src/boot/vbrMain.asm ./src/boot/fsinfo.asm
nasm -f bin ./src/boot/mbr.asm -o ./bin/mbr.bin

./bin/vbr.bin: prepare_dirs ./src/boot/vbr.asm
nasm -f bin ./src/boot/vbr.asm -o ./bin/vbr.bin
nasm -f bin ./src/boot/vbrEntry.asm -o ./bin/vbrEntry.bin
nasm -f bin ./src/boot/vbrMain.asm -o ./bin/vbrMain.bin
nasm -f bin ./src/boot/fsinfo.asm -o ./bin/fsinfo.bin
dd if=./bin/vbrEntry.bin of=./bin/vbr.bin bs=512 count=1 conv=notrunc status=none
dd if=./bin/vbrMain.bin of=./bin/vbr.bin bs=512 seek=1 count=2 conv=notrunc status=none
dd if=./bin/mbr.bin of=$@ bs=512 count=1 conv=notrunc status=none
dd if=./bin/vbr.bin of=$@ bs=512 seek=2050 count=3 conv=notrunc status=none
dd if=./bin/fsinfo.bin of=$@ bs=512 seek=2060 count=1 conv=notrunc status=none

# Calculate kernel size and update boot sector
./bin/boot_with_size.bin: ./bin/mbr.bin ./bin/vbr.bin ./bin/kernel.bin
@echo "Calculating kernel size and updating VBR..."
# ./updateBoot.sh ./bin/vbr.bin ./bin/kernel.bin
@echo "Combining MBR + VBR into boot image..."
dd if=./bin/mbr.bin of=./bin/boot_with_size.bin bs=512 count=1 conv=notrunc
dd if=./bin/vbr.bin of=./bin/boot_with_size.bin bs=512 seek=2048 conv=notrunc

./bin/os.bin:
python3 utilities/make_mbr_partition.py ./bin/os.bin --size 128 --start 2048 --type 0x0C
@bash -c " \
set -e; \
ATTACH_OUTPUT=$$(hdiutil attach -imagekey diskimage-class=CRawDiskImage -nomount ./bin/os.bin); \
echo 'hdiutil attach output:'; \
echo "$$ATTACH_OUTPUT"; \
DISK_ID=$$(echo "$$ATTACH_OUTPUT" | awk '/\/dev\// {print $$1; exit}'); \
if [ -z "$$DISK_ID" ]; then \
echo 'ERROR: No device found. hdiutil did not recognize the image as a disk.'; \
exit 1; \
fi; \
echo "DISK_ID is $$DISK_ID"; \
PART_DEV=$$(ls /dev/$$(basename $$DISK_ID)s1 2>/dev/null || true); \
if [ -z "$$PART_DEV" ]; then \
echo 'ERROR: Partition device not found. Check the image partition table.'; \
hdiutil detach $$DISK_ID; \
exit 1; \
fi; \
echo "Formatting partition $$PART_DEV as FAT32..."; \
sudo newfs_msdos -F 32 -v VIOS_BOOT $$PART_DEV; \
hdiutil detach $$DISK_ID; \
"
@sudo dd if=./bin/vbr.bin of=./bin/os.bin bs=512 seek=2048 conv=notrunc

./bin/boot_with_size.bin: ./bin/boot.bin ./bin/kernel.bin
@echo "Calculating kernel size and updating boot sector..."
cp ./bin/boot.bin ./bin/boot_with_size.bin


./bin/os.bin: ./bin/boot_with_size.bin
rm -rf ./bin/os.bin
dd if=./bin/boot_with_size.bin of=./bin/os.bin bs=512 conv=notrunc
dd if=./bin/kernel.bin of=./bin/os.bin bs=512 seek=2070 conv=notrunc
dd if=/dev/zero bs=1048576 count=128 >> ./bin/os.bin

# Generic C and ASM file rules
./build/%.o: ./src/%.c
mkdir -p $(dir $@)
Expand All @@ -168,12 +158,14 @@ endif
nasm -f elf -g $< -o $@

user_programs:
@{ \
for dir in $(shell find ./assets/etc/default/user/programs -mindepth 1 -maxdepth 1 -type d); do \
@if [ -d "./assets/etc/default/user/programs" ]; then \
for dir in $$(find ./assets/etc/default/user/programs -mindepth 1 -maxdepth 1 -type d 2>/dev/null); do \
echo "Building user program $$dir..."; \
$(MAKE) -C $$dir all || exit 1; \
done; \
}
else \
echo "No user programs directory found (./assets/etc/default/user/programs), skipping..."; \
fi

user_programs_clean:
@for dir in ./assets/etc/default/user/programs/*/ ; do \
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ ___________
│   └── .keep
├── build.sh
├── buildExternal.sh
├── debug.log
├── docs
│   └── api
│   ├── copy_string_from_task.md
Expand Down Expand Up @@ -200,8 +201,11 @@ ___________
│   │   ├── sb16.c
│   │   └── sb16.h
│   ├── boot
│   │   ├── fsinfo.asm
│   │   ├── mbr.asm
│   │   └── vbr.asm
│   │   ├── vbrEntry.asm
│   │   ├── vbrMain.asm
│   │   └── vbrOld.asm
│   ├── config.h
│   ├── debug
│   │   ├── simple_serial.c
Expand Down Expand Up @@ -316,7 +320,6 @@ ___________
│   └── utils
│   ├── utils.c
│   └── utils.h
├── updateBoot.sh
├── updateREADME.sh
├── utilities
│   ├── fonts
Expand All @@ -325,11 +328,10 @@ ___________
│   │   ├── Brightly.otf
│   │   ├── Cheri.ttf
│   │   └── RobotoThin.ttf
│   ├── generateFonts.py
│   └── make_mbr_partition.py
│   └── generateFonts.py
└── ViOS_LOGO_PNG.png

53 directories, 165 files
53 directories, 167 files
```

___________
Expand Down
Binary file added debug.log
Binary file not shown.
17 changes: 17 additions & 0 deletions src/boot/fsinfo.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; FAT32 FSInfo Sector
; This sector provides information about the filesystem state

ORG 0x0000
BITS 16

; FSInfo sector structure
FSInfo_LeadSig dd 0x41615252 ; Lead signature "RRaA"
FSInfo_Reserved1 times 480 db 0 ; Reserved bytes
FSInfo_StrucSig dd 0x61417272 ; Structure signature "rrAa"
FSInfo_Free_Count dd 0xFFFFFFFF ; Free cluster count (unknown)
FSInfo_Nxt_Free dd 0xFFFFFFFF ; Next free cluster (unknown)
FSInfo_Reserved2 times 12 db 0 ; Reserved bytes
FSInfo_TrailSig dd 0xAA550000 ; Trail signature

; Pad to 512 bytes
times 512-($-$$) db 0
92 changes: 45 additions & 47 deletions src/boot/mbr.asm
Original file line number Diff line number Diff line change
@@ -1,63 +1,61 @@
; MBR FAT32 Bootloader - loads first cluster of BOOT file
BITS 16
ORG 0x7C00
BITS 16

start:
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
sti

; Save boot drive
mov [boot_drive], dl

; Set text mode
mov ax, 0x03
int 0x10

; Load first sector of partition at LBA 2048
mov eax, 2048 ; Sector number to load
mov [dap_lba], eax
mov [dap_mem], word 0x8000 ; Destination segment:offset
mov [dap_mem + 2], word 0x0000
mov si, load_msg
call print

; INT 13h Extended Read (0x42)
mov si, disk_address_packet
mov dl, [boot_drive]
; Setup Disk Address Packet (DAP) for partition start (LBA 2048)
mov si, dap
mov ah, 0x42
mov dl, 0x80 ; First hard disk
int 0x13
jc disk_error

; Jump to loaded VBR/Stage2
jmp 0:0x8000
; Far jump to loaded VBR at 0x0000:0x7E00
jmp 0x0000:0x7E00

disk_error:
mov si, err_msg
.print_err:
lodsb
or al, al
jz $
mov si, error_msg
call print
jmp $

print:
mov ah, 0x0E
.next_char:
lodsb
cmp al, 0
je .done
int 0x10
jmp .print_err

; --- Disk Address Packet ---
disk_address_packet:
db 0x10 ; Size
db 0x00 ; Reserved
dw 1 ; Sectors to read
dap_mem:
dw 0x8000 ; Offset
dw 0x0000 ; Segment
dap_lba:
dd 0x00000800 ; LBA = 2048
dd 0x00000000 ; LBA high dword

boot_drive: db 0
err_msg db "Disk Error", 0

times 510 - ($ - $$) db 0
dw 0xAA55
jmp .next_char
.done:
ret

load_msg db "MBR: Loading VBR...", 0
error_msg db "MBR: Disk read error!", 0

; --- Disk Address Packet (DAP) ---
dap:
db 0x10 ; size of DAP
db 0x00 ; reserved
dw 0x0003 ; number of sectors to read
dw 0x7E00 ; offset
dw 0x0000 ; segment
dq 2050 ; LBA - VBR location

times 446 - ($ - $$) db 0 ; Pad to partition table

; === Partition Table ===
db 0x80 ; Bootable
db 0x01, 0x01, 0x00 ; CHS start — dummy
db 0x0C ; FAT32 (LBA)
db 0xFE, 0xFF, 0xFF ; CHS end — dummy
dd 3000 ; LBA of first sector of partition
dd 260096 ; Number of sectors in partition (262144 - 2048)

times 3*16 db 0 ; Empty partitions
dw 0xAA55 ; Boot signature
Loading
Loading