|
| 1 | +param( |
| 2 | + [ValidateSet("all", "clean")] |
| 3 | + [string]$Target = "all", |
| 4 | + [string]$ModelBlob |
| 5 | +) |
| 6 | + |
| 7 | +$ErrorActionPreference = "Stop" |
| 8 | + |
| 9 | +function Require-Command([string]$Name) { |
| 10 | + if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) { |
| 11 | + throw "$Name not found in PATH" |
| 12 | + } |
| 13 | +} |
| 14 | + |
| 15 | +function Invoke-Checked([string]$Exe, [string[]]$Args) { |
| 16 | + & $Exe @Args |
| 17 | + if ($LASTEXITCODE -ne 0) { |
| 18 | + throw "$Exe failed with exit code $LASTEXITCODE" |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +function Get-ObjPath([string]$SrcPath, [string]$SrcRoot, [string]$BuildRoot) { |
| 23 | + $rel = $SrcPath.Substring($SrcRoot.Length) |
| 24 | + $rel = $rel.TrimStart([System.IO.Path]::DirectorySeparatorChar, [System.IO.Path]::AltDirectorySeparatorChar) |
| 25 | + $dir = Split-Path $rel -Parent |
| 26 | + $base = [System.IO.Path]::GetFileNameWithoutExtension($rel) |
| 27 | + if ([string]::IsNullOrEmpty($dir)) { |
| 28 | + return (Join-Path $BuildRoot ($base + ".o")) |
| 29 | + } |
| 30 | + return (Join-Path $BuildRoot (Join-Path $dir ($base + ".o"))) |
| 31 | +} |
| 32 | + |
| 33 | +$root = $PSScriptRoot |
| 34 | +if ([string]::IsNullOrEmpty($root)) { |
| 35 | + $root = (Get-Location).Path |
| 36 | +} |
| 37 | + |
| 38 | +$srcDir = Join-Path $root "src" |
| 39 | +$buildDir = Join-Path $root "build" |
| 40 | +$kernelBin = Join-Path $root "kernel.bin" |
| 41 | +$ldScript = Join-Path $root "linker.ld" |
| 42 | +$assetsDir = Join-Path $root "assets" |
| 43 | + |
| 44 | +if ($Target -eq "clean") { |
| 45 | + if (Test-Path $buildDir) { |
| 46 | + Remove-Item -Recurse -Force $buildDir |
| 47 | + } |
| 48 | + if (Test-Path $kernelBin) { |
| 49 | + Remove-Item -Force $kernelBin |
| 50 | + } |
| 51 | + exit 0 |
| 52 | +} |
| 53 | + |
| 54 | +Require-Command "i686-elf-gcc" |
| 55 | +Require-Command "nasm" |
| 56 | +Require-Command "i686-elf-objcopy" |
| 57 | + |
| 58 | +if (-not (Test-Path $ldScript)) { |
| 59 | + throw "linker.ld not found" |
| 60 | +} |
| 61 | + |
| 62 | +if (-not (Test-Path $buildDir)) { |
| 63 | + New-Item -ItemType Directory -Force -Path $buildDir | Out-Null |
| 64 | +} |
| 65 | + |
| 66 | +$asmSrcs = Get-ChildItem -Path $srcDir -Recurse -Filter "*.asm" |
| 67 | +$cSrcs = Get-ChildItem -Path $srcDir -Recurse -Filter "*.c" |
| 68 | + |
| 69 | +$objPaths = @() |
| 70 | + |
| 71 | +$asFlags = @("-f", "elf32") |
| 72 | +$cFlags = @("-ffreestanding", "-O2", "-Wall", "-Wextra", "-m32", "-fno-pie", "-fno-stack-protector", "-nostdlib", "-nostdinc", "-Iinclude") |
| 73 | + |
| 74 | +foreach ($src in $asmSrcs) { |
| 75 | + $obj = Get-ObjPath $src.FullName $srcDir $buildDir |
| 76 | + $objDir = Split-Path $obj -Parent |
| 77 | + if (-not (Test-Path $objDir)) { |
| 78 | + New-Item -ItemType Directory -Force -Path $objDir | Out-Null |
| 79 | + } |
| 80 | + Invoke-Checked "nasm" ($asFlags + @($src.FullName, "-o", $obj)) |
| 81 | + $objPaths += $obj |
| 82 | +} |
| 83 | + |
| 84 | +foreach ($src in $cSrcs) { |
| 85 | + $obj = Get-ObjPath $src.FullName $srcDir $buildDir |
| 86 | + $objDir = Split-Path $obj -Parent |
| 87 | + if (-not (Test-Path $objDir)) { |
| 88 | + New-Item -ItemType Directory -Force -Path $objDir | Out-Null |
| 89 | + } |
| 90 | + Invoke-Checked "i686-elf-gcc" ($cFlags + @("-c", $src.FullName, "-o", $obj)) |
| 91 | + $objPaths += $obj |
| 92 | +} |
| 93 | + |
| 94 | +$modelBlobPath = $ModelBlob |
| 95 | +if ([string]::IsNullOrEmpty($modelBlobPath)) { |
| 96 | + $candidateA = Join-Path $assetsDir "smollm-135m.gguf" |
| 97 | + $candidateB = Join-Path $assetsDir "SmolLM2-135M-Instruct-Q4_K_M.gguf" |
| 98 | + if (Test-Path $candidateA) { |
| 99 | + $modelBlobPath = $candidateA |
| 100 | + } elseif (Test-Path $candidateB) { |
| 101 | + $modelBlobPath = $candidateB |
| 102 | + } |
| 103 | +} |
| 104 | + |
| 105 | +if (-not [string]::IsNullOrEmpty($modelBlobPath)) { |
| 106 | + if (-not (Test-Path $modelBlobPath)) { |
| 107 | + throw "Model blob not found: $modelBlobPath" |
| 108 | + } |
| 109 | + $modelObj = Join-Path $buildDir "model.o" |
| 110 | + Invoke-Checked "i686-elf-objcopy" @( |
| 111 | + "-I", "binary", |
| 112 | + "-O", "elf32-i386", |
| 113 | + "-B", "i386", |
| 114 | + "--rename-section", ".data=.ai_model,alloc,load,readonly,data,contents", |
| 115 | + $modelBlobPath, |
| 116 | + $modelObj |
| 117 | + ) |
| 118 | + $objPaths += $modelObj |
| 119 | +} |
| 120 | + |
| 121 | +$ldFlags = @("-T", $ldScript, "-ffreestanding", "-O2", "-nostdlib", "-Wl,--build-id=none") |
| 122 | +Invoke-Checked "i686-elf-gcc" ($ldFlags + @("-o", $kernelBin) + $objPaths) |
0 commit comments