Skip to content

Commit d98a259

Browse files
authored
Merge pull request #400 from Microsoft/linux_kernel_direct
Adding LinuxKernelDirect boot support
2 parents 7f79371 + b111b24 commit d98a259

File tree

4 files changed

+88
-22
lines changed

4 files changed

+88
-22
lines changed

functional/lcow_test.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,24 +66,46 @@ func testLCOWUVMNoSCSISingleVPMem(t *testing.T, opts *uvm.UVMOptions, expected s
6666
// TestLCOWTimeUVMStartVHD starts/terminates a utility VM booting from VPMem-
6767
// attached root filesystem a number of times.
6868
func TestLCOWTimeUVMStartVHD(t *testing.T) {
69-
testLCOWTimeUVMStart(t, uvm.PreferredRootFSTypeVHD)
69+
testutilities.RequiresBuild(t, osversion.RS5)
70+
71+
testLCOWTimeUVMStart(t, false, uvm.PreferredRootFSTypeVHD)
72+
}
73+
74+
// TestLCOWUVMStart_KernelDirect_VHD starts/terminates a utility VM booting from
75+
// VPMem- attached root filesystem a number of times starting from the Linux
76+
// Kernel directly and skipping EFI.
77+
func TestLCOWUVMStart_KernelDirect_VHD(t *testing.T) {
78+
testutilities.RequiresBuild(t, 18286)
79+
80+
testLCOWTimeUVMStart(t, true, uvm.PreferredRootFSTypeVHD)
7081
}
7182

7283
// TestLCOWTimeUVMStartInitRD starts/terminates a utility VM booting from initrd-
7384
// attached root file system a number of times.
7485
func TestLCOWTimeUVMStartInitRD(t *testing.T) {
75-
testLCOWTimeUVMStart(t, uvm.PreferredRootFSTypeInitRd)
86+
testutilities.RequiresBuild(t, osversion.RS5)
87+
88+
testLCOWTimeUVMStart(t, false, uvm.PreferredRootFSTypeInitRd)
7689
}
7790

78-
func testLCOWTimeUVMStart(t *testing.T, rfsType uvm.PreferredRootFSType) {
79-
testutilities.RequiresBuild(t, osversion.RS5)
91+
// TestLCOWUVMStart_KernelDirect_InitRd starts/terminates a utility VM booting
92+
// from initrd- attached root file system a number of times starting from the
93+
// Linux Kernel directly and skipping EFI.
94+
func TestLCOWUVMStart_KernelDirect_InitRd(t *testing.T) {
95+
testutilities.RequiresBuild(t, 18286)
96+
97+
testLCOWTimeUVMStart(t, true, uvm.PreferredRootFSTypeInitRd)
98+
}
99+
100+
func testLCOWTimeUVMStart(t *testing.T, kernelDirect bool, rfsType uvm.PreferredRootFSType) {
80101
var vpmemCount uint32 = 32
81102
for i := 0; i < 3; i++ {
82103
opts := &uvm.UVMOptions{
83104
OperatingSystem: "linux",
84105
ID: "uvm",
85106
VPMemDeviceCount: &vpmemCount,
86107
PreferredRootFSType: &rfsType,
108+
KernelDirect: kernelDirect,
87109
}
88110
lcowUVM := testutilities.CreateLCOWUVMFromOpts(t, opts)
89111
lcowUVM.Close()

internal/schema2/chipset.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
package hcsschema
1111

1212
type Chipset struct {
13-
1413
Uefi *Uefi `json:"Uefi,omitempty"`
1514

1615
IsNumLockDisabled bool `json:"IsNumLockDisabled,omitempty"`
@@ -22,4 +21,7 @@ type Chipset struct {
2221
ChassisAssetTag string `json:"ChassisAssetTag,omitempty"`
2322

2423
UseUtc bool `json:"UseUtc,omitempty"`
24+
25+
// LinuxKernelDirect - Added in v2.2 Builds >=181117
26+
LinuxKernelDirect *LinuxKernelDirect `json:"LinuxKernelDirect,omitempty"`
2527
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* HCS API
3+
*
4+
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
5+
*
6+
* API version: 2.2
7+
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
8+
*/
9+
10+
package hcsschema
11+
12+
type LinuxKernelDirect struct {
13+
KernelFilePath string `json:"KernelFilePath,omitempty"`
14+
15+
InitRdPath string `json:"InitRdPath,omitempty"`
16+
17+
KernelCmdLine string `json:"KernelCmdLine,omitempty"`
18+
}

internal/uvm/create.go

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/Microsoft/hcsshim/internal/uvmfolder"
1818
"github.com/Microsoft/hcsshim/internal/wclayer"
1919
"github.com/Microsoft/hcsshim/internal/wcow"
20+
"github.com/Microsoft/hcsshim/osversion"
2021
"github.com/linuxkit/virtsock/pkg/hvsock"
2122
specs "github.com/opencontainers/runtime-spec/specs-go"
2223
"github.com/sirupsen/logrus"
@@ -46,6 +47,7 @@ type UVMOptions struct {
4647
// LCOW specific parameters
4748
BootFilesPath string // Folder in which kernel and root file system reside. Defaults to \Program Files\Linux Containers
4849
KernelFile string // Filename under BootFilesPath for the kernel. Defaults to `kernel`
50+
KernelDirect bool // Skip UEFI and boot directly to `kernel`
4951
RootFSFile string // Filename under BootFilesPath for the UVMs root file system. Defaults are `initrd.img` or `rootfs.vhd`.
5052
KernelBootOptions string // Additional boot options for the kernel
5153
EnableGraphicsConsole bool // If true, enable a graphics console for the utility VM
@@ -179,6 +181,9 @@ func Create(opts *UVMOptions) (_ *UtilityVM, err error) {
179181
uvm.vpmemMaxSizeBytes = *opts.VPMemSizeBytes
180182
}
181183
}
184+
if opts.KernelDirect && osversion.Get().Build < 18286 {
185+
return nil, fmt.Errorf("KernelDirectBoot is not support on builds older than 18286")
186+
}
182187

183188
scsi["0"] = hcsschema.Scsi{Attachments: attachments}
184189
uvm.scsiControllerCount = 1
@@ -333,19 +338,21 @@ func Create(opts *UVMOptions) (_ *UtilityVM, err error) {
333338
vmDebugging := false
334339
vm.GuestConnection.UseVsock = true
335340
vm.GuestConnection.UseConnectedSuspend = true
336-
vm.Devices.VirtualSmb = &hcsschema.VirtualSmb{
337-
Shares: []hcsschema.VirtualSmbShare{
338-
{
339-
Name: "os",
340-
Path: opts.BootFilesPath,
341-
Options: &hcsschema.VirtualSmbShareOptions{
342-
ReadOnly: true,
343-
TakeBackupPrivilege: true,
344-
CacheIo: true,
345-
ShareRead: true,
341+
if !opts.KernelDirect {
342+
vm.Devices.VirtualSmb = &hcsschema.VirtualSmb{
343+
Shares: []hcsschema.VirtualSmbShare{
344+
{
345+
Name: "os",
346+
Path: opts.BootFilesPath,
347+
Options: &hcsschema.VirtualSmbShareOptions{
348+
ReadOnly: true,
349+
TakeBackupPrivilege: true,
350+
CacheIo: true,
351+
ShareRead: true,
352+
},
346353
},
347354
},
348-
},
355+
}
349356
}
350357

351358
if uvm.vpmemMaxCount > 0 {
@@ -355,8 +362,13 @@ func Create(opts *UVMOptions) (_ *UtilityVM, err error) {
355362
}
356363
}
357364

358-
kernelArgs := "initrd=/" + opts.RootFSFile
359-
if actualRootFSType == PreferredRootFSTypeVHD {
365+
var kernelArgs string
366+
switch actualRootFSType {
367+
case PreferredRootFSTypeInitRd:
368+
if !opts.KernelDirect {
369+
kernelArgs = "initrd=/" + opts.RootFSFile
370+
}
371+
case PreferredRootFSTypeVHD:
360372
kernelArgs = "root=/dev/pmem0 init=/init"
361373
}
362374

@@ -428,10 +440,22 @@ func Create(opts *UVMOptions) (_ *UtilityVM, err error) {
428440
}
429441

430442
kernelArgs += ` pci=off -- ` + initArgs
431-
vm.Chipset.Uefi.BootThis = &hcsschema.UefiBootEntry{
432-
DevicePath: `\` + opts.KernelFile,
433-
DeviceType: "VmbFs",
434-
OptionalData: kernelArgs,
443+
444+
if !opts.KernelDirect {
445+
vm.Chipset.Uefi.BootThis = &hcsschema.UefiBootEntry{
446+
DevicePath: `\` + opts.KernelFile,
447+
DeviceType: "VmbFs",
448+
OptionalData: kernelArgs,
449+
}
450+
} else {
451+
vm.Chipset.Uefi = nil
452+
vm.Chipset.LinuxKernelDirect = &hcsschema.LinuxKernelDirect{
453+
KernelFilePath: filepath.Join(opts.BootFilesPath, opts.KernelFile),
454+
KernelCmdLine: kernelArgs,
455+
}
456+
if actualRootFSType == PreferredRootFSTypeInitRd {
457+
vm.Chipset.LinuxKernelDirect.InitRdPath = filepath.Join(opts.BootFilesPath, opts.RootFSFile)
458+
}
435459
}
436460
}
437461

0 commit comments

Comments
 (0)