Files
WSL/tools/create-initrd.ps1
Ben Hillis e5cb458e67 Ship initrd.img in MSI using build-time generation via powershell script (#14424)
* Ship initrd.img in MSI using build-time generation via tar.exe

Replace the install-time CreateInitrd/RemoveInitrd custom actions with a
build-time step that generates initrd.img using the Windows built-in
tar.exe (libarchive/bsdtar) and ships it directly in the MSI.

The install-time approach had a race condition: wsl.exe could launch
before the CreateInitrd custom action completed, causing
ERROR_FILE_NOT_FOUND for initrd.img.

Changes:
- Add CMake custom command to generate initrd.img via tar.exe --format=newc
- Add initrd.img as a regular file in the MSI tools component
- Remove CreateInitrd/RemoveInitrd custom actions from WiX, DllMain,
  and wslinstall.def
- Remove CreateCpioInitrd helper and its tests (no longer needed)
- Update pipeline build targets to build initramfs instead of init

* pr feedback

* more pr feedback

* switch to using a powershell script instead of tar.exe

* powershell script feedback

* hopefully final pr feedback

---------

Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
2026-03-12 20:42:24 -07:00

68 lines
2.3 KiB
PowerShell

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# Creates a CPIO newc format initramfs archive containing a single file named "init"
# with mode 0100755 (rwxr-xr-x), uid 0, gid 0.
[CmdletBinding()]
param (
[Parameter(Mandatory)][string]$InputFile,
[Parameter(Mandatory)][string]$OutputFile
)
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
function Write-Pad([System.IO.Stream]$Stream)
{
$remainder = $Stream.Position % 4
if ($remainder -ne 0)
{
$pad = [byte[]]::new(4 - $remainder)
$Stream.Write($pad, 0, $pad.Length)
}
}
function Write-CpioEntry([System.IO.Stream]$Stream, [byte[]]$NameBytes, [byte[]]$FileData, [int]$Mode, [uint32]$Mtime)
{
$header = "070701" + # header magic
"00000001" + # inode
("{0:X8}" -f $Mode) + # mode
"00000000" + # uid
"00000000" + # gid
"00000001" + # nlink
("{0:X8}" -f $Mtime) + # mtime
("{0:X8}" -f $FileData.Length) + # filesize
"00000000" + # devmajor
"00000000" + # devminor
"00000000" + # rdevmajor
"00000000" + # rdevminor
("{0:X8}" -f $NameBytes.Length) + # namesize
"00000000" # check
$headerBytes = [System.Text.Encoding]::ASCII.GetBytes($header)
$Stream.Write($headerBytes, 0, $headerBytes.Length)
$Stream.Write($NameBytes, 0, $NameBytes.Length)
Write-Pad $Stream
if ($FileData.Length -gt 0)
{
$Stream.Write($FileData, 0, $FileData.Length)
Write-Pad $Stream
}
}
$data = [System.IO.File]::ReadAllBytes($InputFile)
$name = [System.Text.Encoding]::ASCII.GetBytes("init`0")
$mtime = [uint32][System.DateTimeOffset]::UtcNow.ToUnixTimeSeconds()
$out = [System.IO.File]::Create($OutputFile)
try
{
Write-CpioEntry $out $name $data 0x81ED $mtime # S_IFREG | 0755
$trailer = [System.Text.Encoding]::ASCII.GetBytes("TRAILER!!!`0")
Write-CpioEntry $out $trailer ([byte[]]::new(0)) 0 0
}
finally
{
$out.Close()
}