Windows Research Kernel @ HPI News, Tutorials and Lab Descriptions 2011-06-27T12:10:53Z WordPress http://www.dcl.hpi.uni-potsdam.de/research/WRK/feed/atom/ Alexander Schmidt http://kolleg.hpi.uni-potsdam.de/index.php?id=77 <![CDATA[Last Post]]> http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=335 2011-06-27T12:10:53Z 2011-06-27T12:10:53Z Hi folks,

with this very last article, I would like to inform you that this blog will be closed at the end of June. This decision was made for two reasons. (1) The Windows Research Kernel was a great step from Microsoft towards academia. Together with its license the WRK enabled universities to use the Windows source code for their teaching efforts. Unfortunately, there is no news about next versions of the WRK, which makes it hard to study and teach new trends in hardware design, such as multi-core architectures, hybrid systems, and memory hierarchies, in the context of the Windows operating system and to share those insights via this blog. (2) With the submission of my PhD thesis, my affiliation with the HPI will come to a close at the end of the year.

Nevertheless, we are going to maintain a static version of all the blog posts submitted so far. We will, however, disable comments for individual blogs. The transition to the static version should be completed by the end of June. In case you encounter any broken links, even past the migration time, please let us know via email.

Cheers,
Alex

]]>
0
Alexander Schmidt http://kolleg.hpi.uni-potsdam.de/index.php?id=77 <![CDATA[How To: Import VMs into Hyper-V]]> http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=297 2011-06-27T09:11:00Z 2011-03-30T10:00:16Z We use Hyper-V to run some of our WRK-related experiments. In order to keep management simple, I created a virtual machine that contains all the setup for those experiments. After creating that image, I used Hyper-V (running on Windows Server 2008 R2) to export this machine to have the template image ready at hand. Once this was done, I thought I would be able to import that image multilple times so that would have enough instances for running our experiment (30 in our case). However, when I imported the second instance, Hyper-V failed to import the template since the VHD file already existed. In this post I will explain how you can easily import multiple virtual machines from one single template image using PowerShell.

The only GUI Hyper-V provides for importing a VM from a template is as follows:

Hyper-V dialog for importing a virtual machine

Hyper-V dialog for importing a virtual machine

The GUI dialog does not provide any options for specifying a different import location. If you import a virtual machine through that GUI, Hyper-V will attempt to import the VHD file into its base directory (usually \Users\Public\Public Documents\Hyper-V\Virtual hard disks). This behavior leads to the file collision mentioned above. Looking for another alternative, I stumbled upon the PowerShell Management Library for Hyper-V (PsHyperV), a cool and rich PowerShell scripting library for Hyper-V.

PsHyperV provides the Import-VM commandlet, which allows you to import a virtual machine programmatically via PowerShell. Unfortunately, it only provides the same amount of paramters as the GUI version and thus fails to import a second instance of the same virtual machine, since it does not allow you to specify a location to which the VM should be imported to. However, the source code of the commandlet was a good starting point for learning about WMI management classes for Hyper-V.

Digging into the documentation of Hyper-V’s WMI classes, I found the following method, which is available since Server 2008 R2:

uint32 ImportVirtualSystemEx(
  [in]   string ImportDirectory,
  [in]   string ImportSettingData,
  [out]  CIM_ConcreteJob REF Job
);

This method allows you to import a virtual computer system from a specified folder (ImportDirectory) and to specify import settings (ImportSettingData). The ImportSettingData parameter, prior to serialization, has the following type:

class Msvm_VirtualSystemImportSettingData : CIM_SettingData
{
  string  Description;
  string  Caption;
  string  InstanceID;
  string  ElementName;
  boolean GenerateNewId;
  boolean CreateCopy;
  string  Name;
  string  SourceVmDataRoot;
  string  SourceSnapshotDataRoot;
  string  SourceVhdDataRoot;
  string  TargetVmDataRoot;
  string  TargetSnapshotDataRoot;
  string  TargetVhdDataRoot;
  string  SecurityScope;
  string  CurrentResourcePaths[];
  string  SourceResourcePaths[];
  string  TargetResourcePaths[];
  string  SourceNetworkConnections[];
  string  TargetNetworkConnections[];
};

The properties TargetVmDataRoot, TargetSnapshotDataRoot, and TargetVhdDataRoot allow you to specify a directory for where the respective information is stored. So, back to my original problem: I ended up writing a small PowerShell script that creates a directory for each instance that should be imported and then points the Target* properties to that location. Finally the script calls the ImportVirtualSystemEx method to import the VM. It takes quite a while for importing one single instance, but at the end all 30 instances were imported successfully. Here is my script:

$exportDir = "C:\Exports\InstantLab Test Instance Debugger"
$cloneRoot = "C:\Users\Public\Documents\Hyper-V\Clones"
$i = 0
 
# Load management class

$managementService = Get-WmiObject -Namespace "root\virtualization" -Class "Msvm_VirtualSystemManagementService"
$importSettings = $managementService.GetVirtualSystemImportSettingData($exportDir)
$importSettings = $importSettings.ImportSettingData
 
# set global import settings

$importSettings.GenerateNewId = $true
$importSettings.CreateCopy = $true
 
# now do the following in a loop per instance
while ($i -le 30) {
	echo "Creating debugger instance $i"
	$importDir = "$cloneRoot\Debugger$i"
	echo "  Making import directory: $importDir"
	mkdir $importDir
	echo "  Updating import settings"
	$importSettings.Name = "InstantLab Debugger $i"
	$importSettings.TargetVhdDataRoot = $importDir
	$importSettings.TargetSnapshotDataRoot = $importDir
	$importSettings.TargetVmDataRoot = $importDir
	$result = $managementService.ImportVirtualSystemEx($exportDir, $importSettings.GetText(1))
 
         # wait for the job to be finished
	
         Test-WMIJob $result.Job -wait -StatusOnly -Description "  Importing VM"
	$i += 1
	echo "Done."
}
echo "Done."
]]>
0
Alexander Schmidt http://kolleg.hpi.uni-potsdam.de/index.php?id=77 <![CDATA[WRK Compatibility With Windows Server 2003 SP2]]> http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=268 2011-06-27T09:24:17Z 2011-03-07T13:33:35Z The deployment of Windows Server 2008 R2 Hyper-V based virtual machines to facilitate our operating system course assignments has brought up the issue that virtual machines have to run at least Windows Server 2003 SP2. Since the WRK documentation says that Windows Server 2003 SP1 is needed to run the kernel, the question remains whether the application binary interface (ABI) of those two versions are compatible. As others indicated (thanks for your comments :) ) and evaluated on our server, the WRK appears to be able to run on Windows Server 2003 SP2. Nevertheless, I wanted to examine if at least the user-kernel mode ABI is compatible, for which I will give an answer in this post.

The Application Binary Interface for the WRK is determined through the system call table and its calling conventions (system call number in EAX, parameters on the stack). Since I don’t assume that the calling conventions have changed, I concentrated on the system call table. If any of the system call numbers would differ, both versions are incompatible. On the Metasploit web site, you can find a comparison of system calls from various Windows versions. Unfortunately, system calls of Server 2003 SP2 are not listed in their table. It also appears that the site is not active anymore since the comparison ends with Windows Vista.

So, I had to find out the system call table myself. Fortunately, WinDbg is your friend in such a case. The user mode portion of a Windows system call is implemented in ntdll.dll and looks like this:

mov  eax,<system_call_number>
mov  edx,offset SharedUserData!SystemCallStub (<resolved_address>)
call dword ptr [edx]
ret  8

Since system calls are exported by ntdll.dll, we can scan through all the exported symbols starting with Nt. Then we can disassemble the instructions for each function. As shown in the snippet above, the first two instructions are enough to figure out, whether the symbol we found is actually a system call. To retrieve a disassembly of all exported symbols starting with Nt, I used the following WinDbg command:

.foreach /ps 5 (syscall {x ntdll!Nt*}) {u syscall L2}

The command x ntdll!Nt* examines all symbols from ntdll.dll that start with Nt. Each line is passed to a variable named syscall, for which we disassemble (u) the first two instructions (L2). Unfortunately, the .foreach command does not iterate line wise over an input stream but rather word wise. Since the x command delivers multiple words of information per symbol, the /ps switch tells .foreach to skip 5 of those (unnecessary) parameters. Finally, I wrote a small Python script to search through the generated output to identify all the included system calls and extract the system call number.

I performed this experiment twice: once on an SP1 and once on a SP2 machine. Here are the system call tables of these two versions:

Number Service Pack 1 Service Pack 2
0 NtAcceptConnectPort NtAcceptConnectPort
1 NtAccessCheck NtAccessCheck
2 NtAccessCheckAndAuditAlarm NtAccessCheckAndAuditAlarm
3 NtAccessCheckByType NtAccessCheckByType
4 NtAccessCheckByTypeAndAuditAlarm NtAccessCheckByTypeAndAuditAlarm
5 NtAccessCheckByTypeResultList NtAccessCheckByTypeResultList
6 NtAccessCheckByTypeResultListAnd-AuditAlarm NtAccessCheckByTypeResultListAnd-AuditAlarm
7 NtAccessCheckByTypeResultListAnd-AuditAlarmByHandle NtAccessCheckByTypeResultListAnd-AuditAlarmByHandle
8 NtAddAtom NtAddAtom
9 NtAddBootEntry NtAddBootEntry
10 NtAddDriverEntry NtAddDriverEntry
11 NtAdjustGroupsToken NtAdjustGroupsToken
12 NtAdjustPrivilegesToken NtAdjustPrivilegesToken
13 NtAlertResumeThread NtAlertResumeThread
14 NtAlertThread NtAlertThread
15 NtAllocateLocallyUniqueId NtAllocateLocallyUniqueId
16 NtAllocateUserPhysicalPages NtAllocateUserPhysicalPages
17 NtAllocateUuids NtAllocateUuids
18 NtAllocateVirtualMemory NtAllocateVirtualMemory
19 NtApphelpCacheControl NtApphelpCacheControl
20 NtAreMappedFilesTheSame NtAreMappedFilesTheSame
21 NtAssignProcessToJobObject NtAssignProcessToJobObject
22 NtCallbackReturn NtCallbackReturn
23 NtCancelDeviceWakeupRequest NtCancelDeviceWakeupRequest
24 NtCancelIoFile NtCancelIoFile
25 NtCancelTimer NtCancelTimer
26 NtClearEvent NtClearEvent
27 NtClose NtClose
28 NtCloseObjectAuditAlarm NtCloseObjectAuditAlarm
29 NtCompactKeys NtCompactKeys
30 NtCompareTokens NtCompareTokens
31 NtCompleteConnectPort NtCompleteConnectPort
32 NtCompressKey NtCompressKey
33 NtConnectPort NtConnectPort
34 NtContinue NtContinue
35 NtCreateDebugObject NtCreateDebugObject
36 NtCreateDirectoryObject NtCreateDirectoryObject
37 NtCreateEvent NtCreateEvent
38 NtCreateEventPair NtCreateEventPair
39 NtCreateFile NtCreateFile
40 NtCreateIoCompletion NtCreateIoCompletion
41 NtCreateJobObject NtCreateJobObject
42 NtCreateJobSet NtCreateJobSet
43 NtCreateKey NtCreateKey
44 NtCreateMailslotFile NtCreateMailslotFile
45 NtCreateMutant NtCreateMutant
46 NtCreateNamedPipeFile NtCreateNamedPipeFile
47 NtCreatePagingFile NtCreatePagingFile
48 NtCreatePort NtCreatePort
49 NtCreateProcess NtCreateProcess
50 NtCreateProcessEx NtCreateProcessEx
51 NtCreateProfile NtCreateProfile
52 NtCreateSection NtCreateSection
53 NtCreateSemaphore NtCreateSemaphore
54 NtCreateSymbolicLinkObject NtCreateSymbolicLinkObject
55 NtCreateThread NtCreateThread
56 NtCreateTimer NtCreateTimer
57 NtCreateToken NtCreateToken
58 NtCreateWaitablePort NtCreateWaitablePort
59 NtDebugActiveProcess NtDebugActiveProcess
60 NtDebugContinue NtDebugContinue
61 NtDelayExecution NtDelayExecution
62 NtDeleteAtom NtDeleteAtom
63 NtDeleteBootEntry NtDeleteBootEntry
64 NtDeleteDriverEntry NtDeleteDriverEntry
65 NtDeleteFile NtDeleteFile
66 NtDeleteKey NtDeleteKey
67 NtDeleteObjectAuditAlarm NtDeleteObjectAuditAlarm
68 NtDeleteValueKey NtDeleteValueKey
69 NtDeviceIoControlFile NtDeviceIoControlFile
70 NtDisplayString NtDisplayString
71 NtDuplicateObject NtDuplicateObject
72 NtDuplicateToken NtDuplicateToken
73 NtEnumerateBootEntries NtEnumerateBootEntries
74 NtEnumerateDriverEntries NtEnumerateDriverEntries
75 NtEnumerateKey NtEnumerateKey
76 NtEnumerateSystemEnvironment-ValuesEx NtEnumerateSystemEnvironment-ValuesEx
77 NtEnumerateValueKey NtEnumerateValueKey
78 NtExtendSection NtExtendSection
79 NtFilterToken NtFilterToken
80 NtFindAtom NtFindAtom
81 NtFlushBuffersFile NtFlushBuffersFile
82 NtFlushInstructionCache NtFlushInstructionCache
83 NtFlushKey NtFlushKey
84 NtFlushVirtualMemory NtFlushVirtualMemory
85 NtFlushWriteBuffer NtFlushWriteBuffer
86 NtFreeUserPhysicalPages NtFreeUserPhysicalPages
87 NtFreeVirtualMemory NtFreeVirtualMemory
88 NtFsControlFile NtFsControlFile
89 NtGetContextThread NtGetContextThread
90 NtGetDevicePowerState NtGetDevicePowerState
91 NtGetPlugPlayEvent NtGetPlugPlayEvent
92 NtGetWriteWatch NtGetWriteWatch
93 NtImpersonateAnonymousToken NtImpersonateAnonymousToken
94 NtImpersonateClientOfPort NtImpersonateClientOfPort
95 NtImpersonateThread NtImpersonateThread
96 NtInitializeRegistry NtInitializeRegistry
97 NtInitiatePowerAction NtInitiatePowerAction
98 NtIsProcessInJob NtIsProcessInJob
99 NtIsSystemResumeAutomatic NtIsSystemResumeAutomatic
100 NtListenPort NtListenPort
101 NtLoadDriver NtLoadDriver
102 NtLoadKey NtLoadKey
103 NtLoadKey2 NtLoadKey2
104 NtLoadKeyEx NtLoadKeyEx
105 NtLockFile NtLockFile
106 NtLockProductActivationKeys NtLockProductActivationKeys
107 NtLockRegistryKey NtLockRegistryKey
108 NtLockVirtualMemory NtLockVirtualMemory
109 NtMakePermanentObject NtMakePermanentObject
110 NtMakeTemporaryObject NtMakeTemporaryObject
111 NtMapUserPhysicalPages NtMapUserPhysicalPages
112 NtMapUserPhysicalPagesScatter NtMapUserPhysicalPagesScatter
113 NtMapViewOfSection NtMapViewOfSection
114 NtModifyBootEntry NtModifyBootEntry
115 NtModifyDriverEntry NtModifyDriverEntry
116 NtNotifyChangeDirectoryFile NtNotifyChangeDirectoryFile
117 NtNotifyChangeKey NtNotifyChangeKey
118 NtNotifyChangeMultipleKeys NtNotifyChangeMultipleKeys
119 NtOpenDirectoryObject NtOpenDirectoryObject
120 NtOpenEvent NtOpenEvent
121 NtOpenEventPair NtOpenEventPair
122 NtOpenFile NtOpenFile
123 NtOpenIoCompletion NtOpenIoCompletion
124 NtOpenJobObject NtOpenJobObject
125 NtOpenKey NtOpenKey
126 NtOpenMutant NtOpenMutant
127 NtOpenObjectAuditAlarm NtOpenObjectAuditAlarm
128 NtOpenProcess NtOpenProcess
129 NtOpenProcessToken NtOpenProcessToken
130 NtOpenProcessTokenEx NtOpenProcessTokenEx
131 NtOpenSection NtOpenSection
132 NtOpenSemaphore NtOpenSemaphore
133 NtOpenSymbolicLinkObject NtOpenSymbolicLinkObject
134 NtOpenThread NtOpenThread
135 NtOpenThreadToken NtOpenThreadToken
136 NtOpenThreadTokenEx NtOpenThreadTokenEx
137 NtOpenTimer NtOpenTimer
138 NtPlugPlayControl NtPlugPlayControl
139 NtPowerInformation NtPowerInformation
140 NtPrivilegeCheck NtPrivilegeCheck
141 NtPrivilegeObjectAuditAlarm NtPrivilegeObjectAuditAlarm
142 NtPrivilegedServiceAuditAlarm NtPrivilegedServiceAuditAlarm
143 NtProtectVirtualMemory NtProtectVirtualMemory
144 NtPulseEvent NtPulseEvent
145 NtQueryAttributesFile NtQueryAttributesFile
146 NtQueryBootEntryOrder NtQueryBootEntryOrder
147 NtQueryBootOptions NtQueryBootOptions
148 NtQueryDebugFilterState NtQueryDebugFilterState
149 NtQueryDefaultLocale NtQueryDefaultLocale
150 NtQueryDefaultUILanguage NtQueryDefaultUILanguage
151 NtQueryDirectoryFile NtQueryDirectoryFile
152 NtQueryDirectoryObject NtQueryDirectoryObject
153 NtQueryDriverEntryOrder NtQueryDriverEntryOrder
154 NtQueryEaFile NtQueryEaFile
155 NtQueryEvent NtQueryEvent
156 NtQueryFullAttributesFile NtQueryFullAttributesFile
157 NtQueryInformationAtom NtQueryInformationAtom
158 NtQueryInformationFile NtQueryInformationFile
159 NtQueryInformationJobObject NtQueryInformationJobObject
160 NtQueryInformationPort NtQueryInformationPort
161 NtQueryInformationProcess NtQueryInformationProcess
162 NtQueryInformationThread NtQueryInformationThread
163 NtQueryInformationToken NtQueryInformationToken
164 NtQueryInstallUILanguage NtQueryInstallUILanguage
165 NtQueryIntervalProfile NtQueryIntervalProfile
166 NtQueryIoCompletion NtQueryIoCompletion
167 NtQueryKey NtQueryKey
168 NtQueryMultipleValueKey NtQueryMultipleValueKey
169 NtQueryMutant NtQueryMutant
170 NtQueryObject NtQueryObject
171 NtQueryOpenSubKeys NtQueryOpenSubKeys
172 NtQueryOpenSubKeysEx NtQueryOpenSubKeysEx
173 NtQueryPerformanceCounter NtQueryPerformanceCounter
174 NtQueryQuotaInformationFile NtQueryQuotaInformationFile
175 NtQuerySection NtQuerySection
176 NtQuerySecurityObject NtQuerySecurityObject
177 NtQuerySemaphore NtQuerySemaphore
178 NtQuerySymbolicLinkObject NtQuerySymbolicLinkObject
179 NtQuerySystemEnvironmentValue NtQuerySystemEnvironmentValue
180 NtQuerySystemEnvironmentValueEx NtQuerySystemEnvironmentValueEx
181 NtQuerySystemInformation NtQuerySystemInformation
182 NtQuerySystemTime NtQuerySystemTime
183 NtQueryTimer NtQueryTimer
184 NtQueryTimerResolution NtQueryTimerResolution
185 NtQueryValueKey NtQueryValueKey
186 NtQueryVirtualMemory NtQueryVirtualMemory
187 NtQueryVolumeInformationFile NtQueryVolumeInformationFile
188 NtQueueApcThread NtQueueApcThread
189 NtRaiseException NtRaiseException
190 NtRaiseHardError NtRaiseHardError
191 NtReadFile NtReadFile
192 NtReadFileScatter NtReadFileScatter
193 NtReadRequestData NtReadRequestData
194 NtReadVirtualMemory NtReadVirtualMemory
195 NtRegisterThreadTerminatePort NtRegisterThreadTerminatePort
196 NtReleaseMutant NtReleaseMutant
197 NtReleaseSemaphore NtReleaseSemaphore
198 NtRemoveIoCompletion NtRemoveIoCompletion
199 NtRemoveProcessDebug NtRemoveProcessDebug
200 NtRenameKey NtRenameKey
201 NtReplaceKey NtReplaceKey
202 NtReplyPort NtReplyPort
203 NtReplyWaitReceivePort NtReplyWaitReceivePort
204 NtReplyWaitReceivePortEx NtReplyWaitReceivePortEx
205 NtReplyWaitReplyPort NtReplyWaitReplyPort
206 NtRequestDeviceWakeup NtRequestDeviceWakeup
207 NtRequestPort NtRequestPort
208 NtRequestWaitReplyPort NtRequestWaitReplyPort
209 NtRequestWakeupLatency NtRequestWakeupLatency
210 NtResetEvent NtResetEvent
211 NtResetWriteWatch NtResetWriteWatch
212 NtRestoreKey NtRestoreKey
213 NtResumeProcess NtResumeProcess
214 NtResumeThread NtResumeThread
215 NtSaveKey NtSaveKey
216 NtSaveKeyEx NtSaveKeyEx
217 NtSaveMergedKeys NtSaveMergedKeys
218 NtSecureConnectPort NtSecureConnectPort
219 NtSetBootEntryOrder NtSetBootEntryOrder
220 NtSetBootOptions NtSetBootOptions
221 NtSetContextThread NtSetContextThread
222 NtSetDebugFilterState NtSetDebugFilterState
223 NtSetDefaultHardErrorPort NtSetDefaultHardErrorPort
224 NtSetDefaultLocale NtSetDefaultLocale
225 NtSetDefaultUILanguage NtSetDefaultUILanguage
226 NtSetDriverEntryOrder NtSetDriverEntryOrder
227 NtSetEaFile NtSetEaFile
228 NtSetEvent NtSetEvent
229 NtSetEventBoostPriority NtSetEventBoostPriority
230 NtSetHighEventPair NtSetHighEventPair
231 NtSetHighWaitLowEventPair NtSetHighWaitLowEventPair
232 NtSetInformationDebugObject NtSetInformationDebugObject
233 NtSetInformationFile NtSetInformationFile
234 NtSetInformationJobObject NtSetInformationJobObject
235 NtSetInformationKey NtSetInformationKey
236 NtSetInformationObject NtSetInformationObject
237 NtSetInformationProcess NtSetInformationProcess
238 NtSetInformationThread NtSetInformationThread
239 NtSetInformationToken NtSetInformationToken
240 NtSetIntervalProfile NtSetIntervalProfile
241 NtSetIoCompletion NtSetIoCompletion
242 NtSetLdtEntries NtSetLdtEntries
243 NtSetLowEventPair NtSetLowEventPair
244 NtSetLowWaitHighEventPair NtSetLowWaitHighEventPair
245 NtSetQuotaInformationFile NtSetQuotaInformationFile
246 NtSetSecurityObject NtSetSecurityObject
247 NtSetSystemEnvironmentValue NtSetSystemEnvironmentValue
248 NtSetSystemEnvironmentValueEx NtSetSystemEnvironmentValueEx
249 NtSetSystemInformation NtSetSystemInformation
250 NtSetSystemPowerState NtSetSystemPowerState
251 NtSetSystemTime NtSetSystemTime
252 NtSetThreadExecutionState NtSetThreadExecutionState
253 NtSetTimer NtSetTimer
254 NtSetTimerResolution NtSetTimerResolution
255 NtSetUuidSeed NtSetUuidSeed
256 NtSetValueKey NtSetValueKey
257 NtSetVolumeInformationFile NtSetVolumeInformationFile
258 NtShutdownSystem NtShutdownSystem
259 NtSignalAndWaitForSingleObject NtSignalAndWaitForSingleObject
260 NtStartProfile NtStartProfile
261 NtStopProfile NtStopProfile
262 NtSuspendProcess NtSuspendProcess
263 NtSuspendThread NtSuspendThread
264 NtSystemDebugControl NtSystemDebugControl
265 NtTerminateJobObject NtTerminateJobObject
266 NtTerminateProcess NtTerminateProcess
267 NtTerminateThread NtTerminateThread
268 NtTestAlert NtTestAlert
269 NtTraceEvent NtTraceEvent
270 NtTranslateFilePath NtTranslateFilePath
271 NtUnloadDriver NtUnloadDriver
272 NtUnloadKey NtUnloadKey
273 NtUnloadKey2 NtUnloadKey2
274 NtUnloadKeyEx NtUnloadKeyEx
275 NtUnlockFile NtUnlockFile
276 NtUnlockVirtualMemory NtUnlockVirtualMemory
277 NtUnmapViewOfSection NtUnmapViewOfSection
278 NtVdmControl NtVdmControl
279 NtWaitForDebugEvent NtWaitForDebugEvent
280 NtWaitForMultipleObjects NtWaitForMultipleObjects
281 NtWaitForSingleObject NtWaitForSingleObject
282 NtWaitHighEventPair NtWaitHighEventPair
283 NtWaitLowEventPair NtWaitLowEventPair
284 NtWriteFile NtWriteFile
285 NtWriteFileGather NtWriteFileGather
286 NtWriteRequestData NtWriteRequestData
287 NtWriteVirtualMemory NtWriteVirtualMemory
288 NtYieldExecution NtYieldExecution
289 NtCreateKeyedEvent NtCreateKeyedEvent
290 NtOpenKeyedEvent NtOpenKeyedEvent
291 NtReleaseKeyedEvent NtReleaseKeyedEvent
292 NtWaitForKeyedEvent NtWaitForKeyedEvent
293 NtQueryPortInformationProcess NtQueryPortInformationProcess
294 NtGetCurrentProcessorNumber NtGetCurrentProcessorNumber
295 NtWaitForMultipleObjects32 NtWaitForMultipleObjects32

As you can see in the table above, both versions offer the same amount of system calls, which is why, from an ABI perspective, the WRK can run on both operating system versions. Unfortunately, there is one uncertainty left: the WRK links against modules such as the HAL. If there are any dependencies broken, which I think is pretty unlikely, you may encounter unexpected crashes or unpredictable behavior.

If you have any comments or hints about how to resolve the issue, please let us know.

]]>
2
Alexander Schmidt http://kolleg.hpi.uni-potsdam.de/index.php?id=77 <![CDATA[How To: Debug the WRK on Mac OS X Using VMware Fusion]]> http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=236 2011-06-27T09:44:53Z 2011-01-03T10:00:07Z Debugging the WRK on Mac OS requires two virtual machines (VM): the WRK VM, which will be used to debug the kernel, and the debugger VM, which hosts the kernel debugger. Both VMs will use their serial port to communicate with each other. In a previous post, we have shown for VirtualBox how to connect both serial ports over a named pipe. Now, we are going to describe how to configure VMware Fusion 3.0 virtual machines to accomplish the same goal.

Before we begin, here is a sketch of the architecture of our WRK debug scenario:

WRK debug architecture on Mac OS.

WRK debug architecture on Mac OS.

In this tutorial, we will not describe how to configure WinDbg or the WRK to communicate via the COM1 port since this is described elsewhere. We only concentrate on the configuration of the named pipe to connect both VMs. You will notice that the following screenshots were taken on a German system installation. However, the menu locations should be the same in your language and we will also describe what is shown in the image.

If you want to configure the serial port in VMware Fusion 3.0, you will only get this dialog:

Serial Port Configuration in VMware Fusion.

Serial Port Configuration in VMware Fusion.

Which means that the standard configuration for the serial port is used to connect your virtual machine with printers available on Mac OS. The only other option in the GUI you have is to connect the serial port with a file, which is not appropriate for our purpose.

The solution is to manually configure the VM configuration file. Configuration files have the suffix .vmx attached. If you are using a version of VMware Fusion prior to version 3, you will find the configuration file right next to the virtual hard disk file. On Mac OS, virtual machines typically reside in ~/Library/Application Support/VMware Fusion/Virtual Machines/, but you may be using a different location for your VMs. If you are using VMware Fusion 3, VMs and their associated files are organized in packages with the suffix .vmwarevm. To locate the VM configuration file, simply right click the .vmwarevm package in Finder and select Show Packet Contents, as shown in the following figure for the Boot Camp VM.

Use the context menu to see packet contents.

Use the context menu to see packet contents.

After locating the .vmx files for the WRK VM and the debugger VM, open each file with a text editor and locate the lines containing serial0. If your VM is configured to connect with printers, you will find the following two lines in your configuration file:

serial0.present = "TRUE"
serial0.fileType = "thinprint"

Please note that the contents may differ or that the serial connection may not be present at all.

Since we are using a pipe, we need to define a server, which creates the pipe, and a client, which connects to the pipe. My proposal here is to use the WRK VM as a client and the debugger VM as the server. For example, on my Mac, I am using my Boot Camp partition as debugger VM. To configure the server end of the named pipe, replace all the lines starting with serial0 in your debugger VM configuration file with the following:

serial0.present = "TRUE"
serial0.fileType = "pipe"
serial0.fileName = "/private/tmp/com1"
serial0.tryNoRxLoss = "FALSE"
serial0.pipe.endPoint = "server"

This tells VMware that the serial port (serial0) is available (present) and represented by a pipe. The named pipe must be located on the local file system in a directory, for which VMware Fusion has write permissions. My suggestion is to use /tmp/com1 or /private/tmp/com1, since /tmp is only a link. The endpoint property tells VMware that this virtual machine is supposed to create the named pipe.

To configure the client end of the named pipe, replace all the lines starting with serial0 in your WRK VM configuration file with the following:

serial0.present = "TRUE"
serial0.fileType = "pipe"
serial0.fileName = "/private/tmp/com1"
serial0.tryNoRxLoss = "FALSE"
serial0.pipe.endPoint = "client"

Again, we are using the named pipe /private/tmp/com1 but this time as a client, which means that VMware expects the named pipe to already being created. Apparently, this specification has implications on the boot order of your virtual machines: since the debugger VM is the server, it must be started prior to the WRK VM.

Now safe the configuration files and close the editor. If you check the virtual machine settings in VMware Fusion for either VM, you will now find the following options dialog for the serial port (which reads: Use user defined, unsupported settings):

Serial port configuration after manually setting the configuration file.

Serial port configuration after manually setting the configuration file.

If you boot the debugger VM first and then the WRK VM in /debug mode with /debugport=com1, you should be able to connect the kernel debugger with the WRK.

DISCLAIMER

Please note that this description is provided “as is” with absolutely no warranties. Since we are using undocumented properties, the configuration described herein may not be working in future releases of VMware Fusion. If that should be the case or you found out another way of how to connect two VMs with a named pipe in a documented fashion, please feel free to post your experiences here.

]]>
2
Alexander Schmidt http://kolleg.hpi.uni-potsdam.de/index.php?id=77 <![CDATA[Browse Through the WRK Sources]]> http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=230 2011-06-27T10:09:56Z 2010-12-01T07:00:50Z In a recent post, we introduced PXR, a cross-referencing source code documentation compiler. If you are interested in how the results look like and how it feels to interactively browse through the sources, the generated HTML files are now available on Microsoft’s Faculty Connection. We decided to publish these files in that way because we need to make sure that only eligible persons access the source code. Faculty Connection already provides this kind of service.

In the meantime, we are working on a release of the PXR sources, so that you can start building a documentation of your own projects.

]]>
0
Alexander Schmidt http://kolleg.hpi.uni-potsdam.de/index.php?id=77 <![CDATA[WRK Works With Windows Server 2003 SP2]]> http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=226 2011-06-27T10:11:09Z 2010-11-16T08:01:46Z For a recent project, we are going to host a bunch of WRK virtual machines with Hyper-V on a Windows Server 2008 R2 server system. When setting up the first virtual machine, we figured out that Hyper-V is only capable of running Windows Server 2003 with Service Pack 2 conveniently. That is, with mouse and network support!

Since the WRK documentation says that the WRK should be deployed on a Windows Server 2003 (W2K3) SP1 system, we were not sure how to proceed. We finally decided to give it a try and the WRK boots in this environment and works—so far. We do not know, if there may be any compatibility issues between the W2K3 SP2 environment and requirements demanded by the WRK. To further investigate the issue, we will run a set of experiments to figure out, if the WRK continues to run smoothly with W2K3 SP2 and keep you posted.

If you have any contrary or supporting experiences in this regard, please feel free to let us know.

]]>
3
Alexander Schmidt http://kolleg.hpi.uni-potsdam.de/index.php?id=77 <![CDATA[Introducing PXR: A Cross-Referencing Documentation Compiler]]> http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=205 2011-06-27T10:11:22Z 2010-09-22T11:23:23Z Quite some time ago, Michael posted an article about our filter for the Doxygen documentation compiler. While Doxygen is a great tool for documenting large source code repositories, we had some issues with the results that were generated. For example, we had several cases, where Doxygen linked to the prototype declaration of a function instead of its definition. We also wanted a Web site that leverages Web 2.0 capabilities such as AJAX to further enhance the user experience, which is why we decided to build our own documentation compiler: PXR. In this article, we want to briefly introduce PXR and to give you an impression of what it looks like:

The start page generated by PXR for the WRK sources.


PXR was designed as a middle- and back-end for the Microsoft C compiler by means of the Microsoft Phoenix compiler framework. That means, the compiler parses the source files and builds up its intermediate (internal) representation (IR) of the code. PXR then analyzes this IR to generate HTML output. In addition to the comiler information, we also leverage pre-processor output to analyze macros and their value at compile time.

One goal of PXR is to make access to certain aspects of the WRK sources as simple as possible, which is why PXR groups the resulting output into three categories: functions, types, and macros. We intentionally abstract from the file and module hierarchy, because when you start working with the WRK you start picking some functions and data structures first to continue digging into the internals. A fourth category, the typedef alias category, was added later for the sake of completeness. For each category, a list of items is shown in the navigation bar on the left side of the page shown above. The filter input allows a user to search for phrases in each of the categories. Besides of that, following is a list of features PXR provides.

Functions

For each function, PXR shows the following information section: the function signature, a description, a simplified call graph, callers, references, and the source code itself. Each section can be collapsed or expanded. In the following figure, only the signature, call graph, and source code section are open.

PXR generated information for function NtCreateFile.


The “Doc String” section contains a description of what the function is doing, what its parameters mean, and how the return value is to be interpreted. This information is directly parsed from the sources as the WRK follows a pretty strict annotation scheme. To give you an idea of the doc string, please see the following figure:

Doc String for function NtCreateFile

Data Type Dialogs

Whenever source code is shown on a PXR rendered page, it is both highlighted and hyperlinked. That means, if PXR is aware of further information for a particular identifier in the source code, it will embedd a link to the respective further information. For data types, we decided not to open another tab on the PXR screen, but rather to open a “window”, so as to not distract you from reading the source code of a function. However, if you want to follow a link to another function, PXR will open a new tab for this function as this item contains too much information to be reasonably presented in a window.

Dialog for the LARGE_INTEGER data structure.

Source Code Folding

PXR allows you to fold away unnecessary code blocks, such as if and else blocks. This is to make reading and understanding the flow through the code more easily, as you can concentrate on particular code paths while making invisible those paths that are of minor interest. In the following figure, the if block on lines 4832 thru 4869 was folded away. It can be made visible again by clicking the “+” icon.

Lines 4832 thru 4896 are folded away

Interested in PXR?

We have made our version of the WRK sources available online to faculty members at www.dcl.hpi.uni-potsdam.de/wrk-pxr/. If you want to have a look yourself and you are a faculty member, please contact compsci@microsoft.com and we will be happy to create an account for you. We further plan to publish our HTML version of the source code at Faculty Connection at the beginning of next month. The PXR tool itself is currently not available but we are working on that. Please feel free to leave us any comments or requests for features.

]]>
2
Thomas <![CDATA[Scalability Issues in CSRSS]]> http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=175 2011-06-27T10:11:29Z 2010-07-19T09:13:33Z One of our current topics is pushing the limits of operating systems. Inspired by Mark Russinovich’s article Pushing the Limits of Windows: Processes and Threads, we built a theoretical model for the amount of threads that can be created on a given system and then tried to reach these limits. However, the practical evaluation was kind of tricky and we stumbled upon an issue within CSRSS, Windows’ client server runtime subsystem.

Limits on Threads
The maximum number of threads in a system is limited by various resources. For example, on a 32-bit Windows system, the major limitation is the address space of a process. As each thread requires a certain number of memory in kernel space (NtCreateThread – memory allocations in kernel mode) and user space, you can easily calculate the number of threads you can create until the address space of the process is exhausted. In contrast, on 64-bit systems, the major limitation is not the address space, but the physical amount of memory plugged into the machine. For each thread, Windows allocates some memory in kernel space and also the thread stack in user mode. Once the total physical memory on a machine without paging is exhaustet, no further threads can be created.

Limitation by Physical Memory
The HPI recently established a laboratory – the Future SOC Lab – with absolutely stunning hardware. We managed to get access to a machine equipped with 64 cores and 1 TB of main memory to evaluate our hypothesis that once we would have enough memory in the machine, we could reach the theoretical limit.
So, how many threads could be created on such a machine? According to our calculation model a thread on a 64-bit Windows Server 2008 R2 system consumes at least 50KB of memory – using a minimal stack. Therefore we should be able to exceed the number of 20 million threads, spread across multiple processes.

Limitation by Kernel Constants
Having a closer look into the WRK, we found out another limit. The kernel itself holds a list of all process and thread IDs used in the system. And this list is an ordinary handle table. So the maximum size of 2^24 entries for a handle table also holds for the process/thread ID table.
The constant is defined in base\ntos\ex\handle.c, Line 101:

#define MAX_HANDLES (1<<24)

Thus, the maximum number of threads in the whole system is limited to 16,777,216. So let’s try to consume all those thread IDs.

First Tests
Here is our test setup: we wrote a little C program, which creates as many threads as possible. Of course we created our threads only with minimal stack sizes and and let Windows only reserve but not commit stack allocations. Also, we started our threads only in a suspended execution mode.

Our program tries to create threads in parallel. Therefore we start some dedicated threads that create as many threads as possible in a loop. The routine for the dedicated threads looks like:

DWORD WINAPI parallelCreateThreadFunc(LPVOID data)
{
	HANDLE hThread;
	// create threads until errors occur
	while(hThread = CreateThread(NULL, 0, sleepThread, NULL, CREATE_SUSPENDED, NULL))
	{
		// close the handle to keep the process-wide handle table clean
		CloseHandle(hThread);
		// count the created threads in a thread-safe manner 
		InterlockedIncrement(&totalThreadCount);
	}	
	return 0;
}

On another test system with 4GB of main memory, we reached the maximum of about 90,000 threads in 5 seconds. On the big system we stumbled upon an issue: Our test program created the first million of threads in about some minutes. Continuing to the next million, our program needed almost an hour! That was strange, so we decided to investigate the matter a little bit further. Unfortunately, we could not investigate it on the big Future SOC Lab machine, as our access time was restricted. Nevertheless, we will demonstrate that our findings apply to the big machine as well.

First tests indicated that the time for creating a thread increases with every new thread, instead of being constant. A linear correlation between the number of created threads and the creation time was documented by further measurements. But where is the bottleneck?

CSRSS
While starring at the taskmanager during our tests we noticed the increasing number of open handles in the CSRSS process. The more threads we created, the more handles showed up in Task Manager. During thread creation the number of threads and the open handles in CSRSS increased synchronously. But the reverse process, the termination of these threads, was not synchronized. The CSRSS took much more time for reducing the handle count towards zero. Maybe there’s the bottleneck. So what in the world is CSRSS doing?

The Windows Internals book told us that during process creation CSRSS is informed and a function named “CsrCreateProcess” is called via LPC. The Dependency Walker shows for csrss.exe that the corresponding csrsrv.dll also exports a function named “CsrCreateThread”. So maybe for thread creation something similar is going on.

Hash Table Full of Threads
In the WRK there are no sources for those DLLs. But the ReactOS project held some sources for CSRSS. Of course the ReactOS code is not the one underlying to our Windows Server 2008 R2, but the principles should be the same. The sources (thread.c) revealed that CSRSS maintains a hash table for threads inside of csrsrv.dll. It is implemented as chained hash table with doubly linked lists and only 256 buckets. Also, for every thread creation, CSRSS makes a lookup for the ID of current thread to receive the corresponding CSR_THREAD object.

Definition of the hash table in thread.c:

LIST_ENTRY CsrThreadHashTable[256];

Extract of the CsrCreateThread function in thread.c:

NTSTATUS
NTAPI
CsrCreateThread(IN PCSR_PROCESS CsrProcess,
                IN HANDLE hThread,
                IN PCLIENT_ID ClientId)
{
 
    //... more code
 
    /* Get the current Process and make sure the Thread is valid with this CID */
    CurrentThread = CsrLocateThreadByClientId(&CurrentProcess,
                                              &CurrentCid);
 
    //... more code
}

Implementation of lookup function CsrLocateThreadByClientId in thread.c:

PCSR_THREAD
NTAPI
CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL,
                          IN PCLIENT_ID ClientId)
{
    ULONG i;
    PLIST_ENTRY ListHead, NextEntry;
    PCSR_THREAD FoundThread;
 
    /* Hash the Thread */
    i = CsrHashThread(ClientId->UniqueThread);
 
    /* Set the list pointers */
    ListHead = &CsrThreadHashTable[i];
    NextEntry = ListHead->Flink;
 
    /* Star the loop */
    while (NextEntry != ListHead)
    {
        /* Get the thread */
        FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
 
        /* Compare the CID */
        if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread)
        {
            /* Match found, return the process */
            *Process = FoundThread->Process;
 
            /* Return thread too */
            return FoundThread;
        }
 
        /* Next */
        NextEntry = NextEntry->Flink;
    }
 
    /* Nothing found */
    return NULL;
}

With millions of threads created that hash table would degenerate more or less into a simple list with linear search complexity. However, these findings are based on ReactOS, so we needed to verify that something similar is going on in Windows Server 2008 R2.

Drill Into Windows Server 2008 R2
We started WinDbg for inspecting our CSRSS. If you intend to follow our experiment, be careful not to break into CSRSS in the same session as your debugger runs, as otherwise the system will halt. Debugging another session works fine. When using the debugging symbols provided by Microsoft, the inspection was quite simple. We could verify that there is still a hash table called CSRSRV!CsrThreadHashTable with linked lists for its buckets. The size of the hash table changed however in Windows Server 2008 R2. We determined the actual size right from the underlying hash function. In ReactOS this function was a simple macro and in the disassembly the hashing algorithm was inlined in many places.

The formula is: (ThreadID / 4) % 1024. Thus, the hash table has 1024 buckets – but that’s still too small. To prove that this hash table has a significant impact on thread creation time, we patched the hash algorithm into a constant function. So every thread ID was placed into the first bucket of the hash table. The time for creating a thread increased by an order of magnitude, compared to our unpatched version. And indeed, on the small 4GB machine the creation process extremely slowed down.
So we could prove that the performance degradation correlates to CSRSS’s hash table, which means that we found the bottleneck. But how can we fix this?

Working Around the Scalability Issues
We had three alternatives: either increasing the number of hash table entries, replacing the hash table with another data structure, or not using it at all. As we lack the sources of CSRSS, we decided for the latter. In this regard, we were not fixing the issue but rather working around to see if our assumptions were correct.

We extended our test program so that it patches the WinAPI CreateThread function in memory in order to avoid any LPC calls to CsrCreateThread. Therefore, we replaced the call instruction in the kernel32 module (more precisely: kernelbase.dll) at the right offset with NOP instructions. But beware of changes in global shared memory without activating copy-on-write for the corresponding pages.

Surprisingly, this quick and dirty hack worked very well and everything went as before except that CSRSS wasn’t informed about newly created threads. Though, we must admit that we don’t know about all the implications of our modification. Maybe, if we would use “real working” threads instead of “sleeping” threads, something might fail.
However, thread creation was fast, really fast. Within seconds we created 4.7 million threads – maybe more than anyone did before. We will provide detailed results of our performance measurements soon.

In conclusion, we could verify that CSRSS is having scalability issues upon thread creation, specifically when there are millions of those. Also, we ran into yet another limitation, which we have not been able to resolve yet. We could only create 4.7 millions of threads but not 16 millions. As soon as we figured out that limitation, we will post it here.

]]>
1
Alexander Schmidt http://kolleg.hpi.uni-potsdam.de/index.php?id=77 <![CDATA[How To: Boot the WRK in a Virtual Machine]]> http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=154 2011-06-27T10:11:37Z 2010-05-11T15:28:05Z In a previous post, we showed you how to debug the WRK on a Mac OS system using Sun’s VirtualBox. However, in that post, I only concentrated on how to link both virtual machines but not on how to create a WRK-ready virtual machine (VM), because I thought that this task is well documented on the WRK DVD. Unfortunately, on the latest revision of the WRK DVD (verion 1.3, series F), this documentation is missing. In general, this is not a problem, as Microsoft provides a WRK-ready Virtual PC image on the DVD, where all the settings have been done already, but it is of no help, if you plan to use VirtualBox in your environment. In this article, we want to re-iterate over the steps necessary to run the WRK in your virtual machine.

In this article, we assume that you are using Sun’s VirtualBox, but it should work with other vendors as well.

Disabling automatic updates

First of all, you must install Windows Server 2003 with Service Pack 1 in your virtual machine. You may choose between the 32-bit or 64-bit version, but the service pack version must be the exact same! Once the installation is complete, we recommend adjusting the Windows Update policy such that updates are not installed automatically. This step is necessary, as Windows Update will probably download a higher service pack version, which the WRK might be incompatible with.

Determining the HAL Version

The WRK requires a multi-processor version of the hardware abstraction layer (HAL) library, which abstracts from all the chipset specific settings of your mainboard. If the VM is not a multi-processor VM, the Windows Server 2003 installation process may choose to install the single processor version of the HAL. To figure out, which HAL you have on your VM, go to the %systemroot%\system32 directory and right click on the HAL.dll file, and select Properties. In the appearing dialog, choose the Version tab and select the Internal Name property, which shows you the internal name of the selected file.

HAL.dll file properties dialog.

Depending on the internal name, you need to copy one of the following files from the Resources\Windows_Research_Kernel\Get_WRK\WRK-v1.2\WS03SP1HALS\ folder on the DVD to the %systemroot%\system32 on your VM.

Internal Name File to Copy
halacpi.dll halacpim.dll
halaacpi.dll halmacpi.dll
halapic.dll halmps.dll

Deploying the Kernel

Once you have built the WRK, copy the resulting executable (either wrkx86.exe or wrkamd64.exe) to the %systemroot%\system32 folder on the WRK VM.

Configuring Boot Options

The last step to make your VM WRK-ready is to update your boot.ini file, which resides in the root directory of our boot partition (probably C:\). To edit the file on your VM, click on the Start menu, right click My Computer and select Properties. In the properies dialog, click on the Advanced tab. In the Advanced tab, click on the Settings button in the Startup and Recovery section:

System properties dialog box.

In the Startup and Recovery dialog, click the Edit button, which opens the boot.ini file in the Notepad editor.

The Startup and Recovery dialog box.

Edit the file as follows:


[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(2)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Windows Server 2003, Standard"
multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Windows Server 2003, WRK" /kernel=wrkx86.exe /hal=<your HAL> /debug /debugport=com1
multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Windows Server 2003, WRK - No Debugger" /kernel=wrkx86.exe /hal=<your HAL>

Update <your HAL> with the appropriate file name from the above table. Note that the filenames must be short (8.3) names.

Information about aditional boot options, such as the /debug switch, can be found here. For configuring the debugger, you may also have a look at this post. Do not forget to safe the file. You can then close the editor.

Booting the WRK

Once you configured the boot.ini file, re-boot the system. If you configured the operating system name of your boot.ini file as mentioned above, you should now see the following boot screen:

WRK-ready VM boot screen.

The second entry boots up your WRK with the debugger stub being active, while the last entry just boots your kernel without any debug features.

]]>
1
Alexander Schmidt http://kolleg.hpi.uni-potsdam.de/index.php?id=77 <![CDATA[Presenting at Windows Core Workshop 2010, Beijing, China]]> http://www.dcl.hpi.uni-potsdam.de/research/WRK/?p=148 2011-06-27T10:11:42Z 2010-04-02T06:00:48Z Taking place for the fourth time, the Microsoft Research Asia Windows Core Workshop brings together faculty from around the world and Microsoft kernel experts to provide information about and exchange experiences in Windows technologies for teaching operating systems.

As the WRK and CRK community is pretty active in the Asia/Pacific region, we are extremely proud to be invited to give a presentation about our experiences with the WRK here at HPI. Here is the abstract of Alexander’s talk.

The Windows Research Kernel (WRK) was released in 2006. Since then, at the Operating Systems and Middleware group at HPI, we have been using the WRK as a valuable complement to the Windows Internals Curriculum Resource Kit (CRK). However, although the WRK was especially designed for academia, it is still a software product that has to be carefully adapted to fit into the curriculum. The biggest challenges in this regard were the sheer complexity of the kernel, the high configuration overhead prior to usage, and the lack of suitable experiments, which we consider essential for teaching operating systems.

In this talk, we present our hands-on methodology for teaching operating systems and the lessons we learned from using the WRK in the classroom. We, therefore, designed and implemented a couple of projects that align nicely with the CRK and that help students easily master kernel programming projects inside the WRK. The talk concludes with interesting results of a survey among our students and some thoughts on and suggestions of future directions for the WRK we would be delighted to see.

The slides as well as a video of Alex’ presentation are finally available :)

]]>
0