menios icon indicating copy to clipboard operation
menios copied to clipboard

Migrate /bin utilities from FAT32 to ext2 partition

Open pbalduino opened this issue 3 months ago • 0 comments

Goal

Migrate all /bin utilities and executables from the FAT32 boot partition to the ext2 root partition, establishing a proper UNIX filesystem layout with full permission and ownership support.

Context

Currently, /bin utilities live on the FAT32 partition, which has limitations:

  • No POSIX permissions (all files executable by everyone)
  • No ownership (UID/GID) support
  • No symbolic link support
  • Limited metadata

With ext2 as the root filesystem (#228), we can migrate /bin to enjoy:

  • Proper file permissions (755 for executables, 644 for scripts)
  • File ownership (root-owned system binaries)
  • Symbolic links for alternative names
  • Better security and organization

Definition of Done

  • Build system: Compile binaries and install to ext2 partition
  • Migration script: Move existing /bin from FAT32 to ext2
  • Permissions: Set proper permissions on all binaries (755)
  • Ownership: Set proper ownership (root:root typically)
  • Symbolic links: Create common aliases (sh → mosh, etc.)
  • PATH: Update default PATH to use ext2 /bin
  • Verification: All utilities work from new location

Current /bin Contents

Shell and Core Utilities

/bin/mosh          # Default shell
/bin/init          # Init process
/bin/sh → mosh     # Shell symlink (future)

File Utilities

/bin/cat           # Concatenate files
/bin/echo          # Print text
/bin/ls            # List directory
/bin/env           # Environment variables

Process Management

/bin/ps            # Process list
/bin/kill          # Send signals
/bin/true          # Return success
/bin/false         # Return failure

Future Utilities

/bin/cp            # Copy files
/bin/mv            # Move files
/bin/rm            # Remove files
/bin/mkdir         # Make directory
/bin/rmdir         # Remove directory
/bin/ln            # Create links
/bin/chmod         # Change permissions
/bin/chown         # Change ownership

Implementation Details

Build System Changes

# Makefile changes for ext2 installation

# Build binaries
USERLAND_BINS = mosh init cat echo ls env ps kill true false
USERLAND_DIR = src/usermode
BIN_INSTALL_DIR = /tmp/menios_root/bin

# Compile each binary
$(USERLAND_BINS): %: $(USERLAND_DIR)/%.c
	$(CC) $(CFLAGS) -o build/bin/$@ $< $(LDFLAGS)

# Install to ext2 partition
install-binaries: $(USERLAND_BINS)
	@mkdir -p $(BIN_INSTALL_DIR)
	@for bin in $(USERLAND_BINS); do \
		cp build/bin/$$bin $(BIN_INSTALL_DIR)/$$bin; \
		chmod 755 $(BIN_INSTALL_DIR)/$$bin; \
	done
	@echo "Installed $(words $(USERLAND_BINS)) binaries to ext2"

# Create symbolic links
install-symlinks:
	@ln -sf mosh $(BIN_INSTALL_DIR)/sh
	@ln -sf env $(BIN_INSTALL_DIR)/printenv
	@echo "Created symbolic links"

# Full installation
install: install-binaries install-symlinks

Disk Image Build Process

#!/bin/bash
# build_system.sh - Updated for ext2 /bin

set -e

# 1. Build all binaries
make -C src/usermode all

# 2. Create disk image with partitions
./scripts/create_boot_disk.sh

# 3. Mount ext2 partition
LOOP=$(sudo losetup -fP --show menios.img)
mkdir -p /tmp/menios_root
sudo mount ${LOOP}p2 /tmp/menios_root

# 4. Create directory structure
sudo mkdir -p /tmp/menios_root/{bin,dev,tmp,proc,etc,home,usr,var,root,boot}

# 5. Install binaries with correct permissions
for binary in build/bin/*; do
    sudo cp "$binary" /tmp/menios_root/bin/
    sudo chmod 755 "/tmp/menios_root/bin/$(basename $binary)"
    sudo chown root:root "/tmp/menios_root/bin/$(basename $binary)"
done

# 6. Create symbolic links
sudo ln -sf mosh /tmp/menios_root/bin/sh

# 7. Create initial /etc structure
sudo mkdir -p /tmp/menios_root/etc
echo "PATH=/bin:/usr/bin" | sudo tee /tmp/menios_root/etc/environment
echo "root:x:0:0:root:/root:/bin/sh" | sudo tee /tmp/menios_root/etc/passwd

# 8. Unmount and cleanup
sudo umount /tmp/menios_root
sudo losetup -d $LOOP
rm -rf /tmp/menios_root

echo "ext2 root partition populated successfully"

Runtime Migration (First Boot)

// Run once on first boot to migrate from FAT32 to ext2
int migrate_bin_to_ext2(void) {
    struct stat st;
    
    // Check if /bin already exists on ext2
    if (stat("/bin/mosh", &st) == 0) {
        kprintf("Migration: /bin already exists on ext2, skipping\n");
        return 0;
    }
    
    kprintf("Migration: Copying /bin from FAT32 to ext2...\n");
    
    // Create /bin directory on ext2
    if (mkdir("/bin", 0755) < 0) {
        kprintf("Migration: Failed to create /bin\n");
        return -1;
    }
    
    // Mount FAT32 temporarily to /boot (if not already mounted)
    // Copy each binary from /boot/bin/* to /bin/*
    const char *binaries[] = {
        "mosh", "init", "cat", "echo", "ls", 
        "env", "ps", "kill", "true", "false", NULL
    };
    
    for (int i = 0; binaries[i]; i++) {
        char src[256], dst[256];
        snprintf(src, sizeof(src), "/boot/bin/%s", binaries[i]);
        snprintf(dst, sizeof(dst), "/bin/%s", binaries[i]);
        
        if (copy_file(src, dst) < 0) {
            kprintf("Migration: Warning - failed to copy %s\n", binaries[i]);
            continue;
        }
        
        chmod(dst, 0755);
        kprintf("Migration: Copied %s\n", binaries[i]);
    }
    
    // Create symbolic links
    symlink("mosh", "/bin/sh");
    
    kprintf("Migration: Completed successfully\n");
    return 0;
}

Permission Setup

// Set proper permissions on binaries
struct binary_perms {
    const char *path;
    mode_t mode;
    uid_t uid;
    gid_t gid;
};

struct binary_perms bin_permissions[] = {
    // Regular executables (owner rwx, group rx, other rx)
    { "/bin/mosh",  0755, 0, 0 },
    { "/bin/cat",   0755, 0, 0 },
    { "/bin/echo",  0755, 0, 0 },
    { "/bin/ls",    0755, 0, 0 },
    { "/bin/env",   0755, 0, 0 },
    
    // System utilities (may want restricted)
    { "/bin/ps",    0755, 0, 0 },
    { "/bin/kill",  0755, 0, 0 },
    
    // Init (critical system binary)
    { "/bin/init",  0750, 0, 0 },  // root only
    
    { NULL, 0, 0, 0 }
};

int setup_bin_permissions(void) {
    for (int i = 0; bin_permissions[i].path; i++) {
        struct binary_perms *bp = &bin_permissions[i];
        
        if (chmod(bp->path, bp->mode) < 0) {
            kprintf("Failed to set permissions on %s\n", bp->path);
            return -1;
        }
        
        if (chown(bp->path, bp->uid, bp->gid) < 0) {
            kprintf("Failed to set ownership on %s\n", bp->path);
            return -1;
        }
    }
    
    return 0;
}

Symbolic Link Creation

# Common shell aliases
ln -s /bin/mosh /bin/sh

# Alternative utility names
ln -s /bin/env /bin/printenv

# Future compatibility
ln -s /bin/true /bin/:
ln -s /bin/false /bin/false

Directory Structure After Migration

/ (ext2 root)
├── bin/
│   ├── cat          (755, root:root)
│   ├── echo         (755, root:root)
│   ├── env          (755, root:root)
│   ├── false        (755, root:root)
│   ├── init         (750, root:root)
│   ├── kill         (755, root:root)
│   ├── ls           (755, root:root)
│   ├── mosh         (755, root:root)
│   ├── ps           (755, root:root)
│   ├── sh → mosh    (symbolic link)
│   └── true         (755, root:root)
│
├── boot/           (mount point for FAT32 sda1)
│   ├── kernel.elf
│   └── limine.cfg
│
├── etc/
│   ├── passwd
│   ├── group
│   └── environment
│
└── [other directories...]

Testing Strategy

  • Build system test: Verify binaries installed to ext2
  • Permission test: Verify all permissions set correctly
  • Execution test: Run each binary from ext2 location
  • Symbolic link test: Verify symlinks work
  • PATH test: Ensure shell finds binaries
  • Migration test: Test first-boot migration
  • Fallback test: Verify FAT32 fallback still works

Environment Variables

# /etc/environment - Default environment
PATH=/bin:/usr/bin:/sbin:/usr/sbin
HOME=/root
SHELL=/bin/sh
TERM=linux

Init Process Updates

// init process should set proper PATH
void init_environment(void) {
    // Read /etc/environment if exists
    FILE *fp = fopen("/etc/environment", "r");
    if (fp) {
        char line[256];
        while (fgets(line, sizeof(line), fp)) {
            // Parse VAR=value and set environment
            char *eq = strchr(line, '=');
            if (eq) {
                *eq = '\0';
                setenv(line, eq + 1, 1);
            }
        }
        fclose(fp);
    } else {
        // Fallback defaults
        setenv("PATH", "/bin:/usr/bin", 1);
        setenv("HOME", "/root", 1);
        setenv("SHELL", "/bin/sh", 1);
    }
}

Migration Checklist

  • [ ] Update Makefile to install to ext2
  • [ ] Create disk build script with ext2 /bin
  • [ ] Implement permission setting
  • [ ] Create symbolic links
  • [ ] Update PATH in default environment
  • [ ] Test all binaries from new location
  • [ ] Document new directory layout
  • [ ] Remove old FAT32 /bin references

Dependencies

  • ext2 support: #227 (ext2 filesystem)
  • Dual partition mount: #228 (FAT32 /boot + ext2 /)
  • chmod/chown syscalls: Permission management syscalls
  • symlink syscall: Symbolic link creation

Benefits

  • Proper UNIX permissions on system binaries
  • File ownership and security
  • Symbolic link support for aliases
  • Cleaner separation of boot and system files
  • Foundation for multi-user system
  • Better organized filesystem

Rollback Plan

  • Keep FAT32 /bin as backup during transition
  • Fallback PATH includes /boot/bin
  • Can boot with old FAT32-only layout if needed

Files to Create/Modify

  • Makefile - Binary installation updates
  • scripts/build_system.sh - Disk creation script
  • src/usermode/init.c - Environment setup
  • etc/environment - Default environment file
  • docs/FILESYSTEM_LAYOUT.md - Documentation

Deliverables

  • Binaries installed to ext2 /bin
  • Proper permissions (755) on all executables
  • Symbolic links for common aliases
  • Updated PATH to use ext2
  • Migration script for first boot
  • Documentation

Related Issues

  • #228 - Dual partition mount (FAT32 /boot + ext2 /)
  • #227 - ext2 filesystem support
  • chmod/chown syscalls implementation (future)

Dependencies

Required (Blocking)

  • #227 - Full ext2 implementation (need write support to create /bin on ext2)
  • #228 - Dual partition mount (need ext2 mounted as /)
  • chmod/chown syscalls - Need permission management (new issue needed)
  • symlink syscall - Need symbolic link creation (new issue needed)

Part Of

  • #227 - ext2 implementation (this is the migration/deployment phase)

Priority

Low - Nice organizational improvement, not blocking functionality

Justification

  • Cosmetic/organizational improvement
  • Binaries work fine from FAT32
  • POSIX permissions nice but not critical yet
  • Should wait until ext2 write support is stable
  • No urgency until multi-user support needed

Implementation Phases

Phase 1: Build System (2-3 days)

  • Update Makefile to install binaries to ext2
  • Create disk image build script
  • Partition formatting and file copying

Phase 2: Permission Setup (1-2 days)

  • Implement chmod/chown in build scripts
  • Set proper permissions (755 for executables)
  • Set ownership (root:root)

Phase 3: Symbolic Links (1 day)

  • Create /bin/sh → mosh symlink
  • Create other common aliases
  • Test link resolution

Phase 4: Environment (1-2 days)

  • Create /etc/environment
  • Update init to set PATH
  • Default shell configuration

Phase 5: Testing (2-3 days)

  • Verify all binaries work from ext2
  • Test permissions
  • Test symbolic links
  • Migration script testing

Total Estimated: 1.5-2 weeks

Current Status

Blocked - Waiting for:

  1. #227 (ext2 write support) - Not started
  2. #228 (dual partition mount) - Blocked
  3. chmod/chown syscalls - Not created
  4. symlink syscall - Partially exists, needs testing

Recommend deferring this until #227 and #228 are complete and stable.

Testing Strategy

  • Build system test: Verify binaries installed to ext2
  • Permission test: Verify all permissions set correctly
  • Execution test: Run each binary from ext2 location
  • Symbolic link test: Verify symlinks work
  • PATH test: Ensure shell finds binaries
  • Migration test: Test first-boot migration
  • Fallback test: Verify FAT32 fallback still works

pbalduino avatar Oct 09 '25 03:10 pbalduino