「コアに釘付け」グラフィックサブシステム





一般に「カーネル内のグラフィックス」と呼ばれるものは、通常win32kを指します。 Win32k.sysは、グラフィックスサブシステムの中核です。 他のすべてのサブシステムの初期化中に、ユーザープロセスsmss.exeによってロードされます。 「kmode」サブシステムの実行可能イメージへのパスは、次の場所に登録されています。





これはどのように起こりますか?







ここ(スクリーンショットの下部のトレーススタック)では、smssユーザーモードのwin32kブートプロセス(とり​​わけ、ページングファイル、レジストリ、環境変数を初期化し、前にバグチェックがあった場合はwininitでサービスを開始する)がはっきりと見えます。コントロールマネージャーとローカルセキュリティ機関サブシステム、ログオンセッションなどを作成します。..)、win32kが最初に行うことの1つは、カーネルとの「接続の確立」です。 理由は次のとおりです。win32kはカーネルよりも高いレベルにあるため、カーネルは(特定の実装)win32kに依存関係を持つことができません(この場合の「依存関係」は古典的な「変更の理由」を意味します)が、カーネルとwin32kの両方は安全にインターフェイスに依存します。 このようなインターフェイスはKWIN32_CALLOUTS_FPNS構造であり、カーネルでこのインターフェイスの特定の実装を登録するための関数はPsEstablishWin32Calloutsです。



さらに、win32kは、Object Managerが提供する汎用インターフェースを介して、いくつかのタイプのオブジェクト(特に、デスクトップおよびWindowStation)を登録します。



したがって、カーネルはwin32kに依存しません。 さらに、NT4より前は、すべてのユーザー/ gdi APIがcsrssで処理され、もちろん速度が低下していました。 NT4以降、ユーザー/ gdiプリミティブのPARTがカーネルに移植され、パフォーマンスが向上しました。



一般に、win32kは完全に削除するか、独自の核パーツに置き換えるか、ユーザーモードですべてを完全に実装できます(たとえば、カーネルと通信するioctlを使用して)が、これは遅くなります。 これが行われない唯一の理由は、必要ないからです。 別の方法で書くことができます-はい、書く方がはるかに良いです-ほとんど。 まあ、書き換えのために書き換えることは良い考えではありません。



実践は真実の基準、または「膝の上のMinWin」です



誤解を排除するために、すぐに言いたいことがあります。 私がやることはMinWinではありません 。 少なくとも実際のMinWinにはユーザー(ユーザーモード)バイナリの最小限のセットが含まれているためではありませんが、完全にロードされたカーネルをデモンストレーションします(別の違いは、MinWinに最小限のドライバーのセットが含まれていますが、ドライバーのセットは通常の読み込みに比べて変化しないことです) )ユーザーモードがまったくない場合(1つのプロセスと1つのdllがまだ存在しますが、少なくとも何らかの形で何かが発生していることをユーザーに示す必要があります)。 リフレクションの追加の理由は、Windows 7コードを「バンドル」する作業に関連して実際のMinWinが登場したことかもしれません。原則としてXPとNT3.51でも同じことが可能です。



したがって、前のセクションで書かれた内容を注意深く読んだ場合、smssをサブシステムを初期化しないものに置き換える必要があると推測できますが、それでも多かれ少なかれ対話のままです。 smss.exeは通常のネイティブプロセスです(おおよそ、ネイティブアプリケーションはntdll.dllにのみリンクし、したがってネイティブAPIのみを使用して動作するアプリケーションです)。 幸いなことに、以前のReactOSチーフデベロッパーであるAlex Ionescuは、(長期にわたる)tinykrnlプロジェクトの一部として、同様のアプリケーションを既に作成しました。 このアプリケーションはamd64でビルドされておらず、最新のWDKでビルドされておらず、いくつかのバグがありますが、通常は動作します。 次の画像はアーカイバで開くことができます-それにはソースと小さなアプリケーションnative.exeのコンパイルされたamd64バイナリが含まれています:





申し訳ありませんが、完成した画像は違法であるためレイアウトできません。そのため、インストールイメージからvhdイメージを収集できるコードを投稿します。

次のコードは、Win7でのみ実行できます。 それをWindows 7のen-usインストールディスクから、minwin.ps1などの一時ディレクトリに保存します(\ sourcesディレクトリにあります)(これは重要です-このローカライズに必要なNLSファイルのみがコピーされます)。上記の画像のnative.exeファイルをこのディレクトリに保存し、管理者コンソールでこの同じディレクトリに移動して、次の操作を行います。

powershell -executionpolicy bypass .\minwin.ps1
      
      





簡潔にするために:

1. 1つのディレクトリの横に、minwin.ps1、install.wim、およびnative.exeのファイルがあります。

2.現在のディレクトリを上記のファイルを含むディレクトリに変更した後にのみ、minwin.ps1を実行する必要があります。



免責事項:あなたはあなた自身の責任で次のすべてを行います。 チームは非常に明白であり、害を及ぼすべきではありませんが、これは「ひざまずく」創造性であるため、どのような状況でも働く義務はありません。 EVERYコマンドの意味がわからない場合は、このスクリプトを実行しないでください(特に、実行は昇格したユーザーの下で実行する必要があるため)。 そうでない場合、以下は最終的にどのように見えるかの写真です。 単純化したバージョンでは、native.exeの名前をsmss.exeに変更し、既にロードされている仮想マシンの既存のsmss.exeにコピーして(XPから7までのすべてのx64 Windowsが動作します)、再起動できます。

スクリプト自体:

 $vhdName = "disk.vhd" $wimName = "install.wim" $vhdDisk = "V" $wimMountName = "MountedWim" md $wimMountName dism /mount-wim /wimfile:$wimName /index:1 /mountdir:$wimMountName #del $vhdName @" create vdisk file=$pwd\$vhdName type=expandable maximum=128 select vdisk file=$pwd\$vhdName attach vdisk create partition primary format fs=ntfs quick assign letter=$vhdDisk active "@ | diskpart bcdboot "$pwd\$wimMountName\Windows" /s "${vhdDisk}:" #cmd /c "$wimMountName\Windows\System32\bootsect /nt60 ${vhdDisk}: /mbr /force" $disk = gwmi win32_diskdrive -filter "Model = 'Msft Virtual Disk SCSI Disk Device'" $part = $disk.GetRelated("win32_diskpartition") | select -first 1 $bootmgr = [wmi]"root\wmi:BcdObject.Id=`"{9dea862c-5cdd-4e70-acc1-f32b344d4795}`",StoreFilePath=`"${vhdDisk}:\\boot\\bcd`"" $osloader = [wmi]"root\wmi:BcdObject.Id=`"$($bootmgr.GetElement(0x23000003).Element.Id)`",StoreFilePath=`"${vhdDisk}:\\boot\\bcd`"" $bootmgr.SetQualifiedPartitionDeviceElement(0x11000001, 0, $disk.Signature, $part.StartingOffset) $osloader.SetQualifiedPartitionDeviceElement(0x11000001, 0, $disk.Signature, $part.StartingOffset) $osloader.SetQualifiedPartitionDeviceElement(0x21000001, 0, $disk.Signature, $part.StartingOffset) $osloader.SetStringElement(0x12000002, "\Windows\system32\winload.exe") $osloader.SetStringElement(0x22000002, "\Windows") $osloader.SetBooleanElement(0x26000022, $true) md "${vhdDisk}:\Windows\System32\config\", "${vhdDisk}:\Windows\Fonts", "${vhdDisk}:\Windows\inf", "${vhdDisk}:\Windows\SysWOW64" copy -r "$wimMountName\Windows\System32\drivers" "${vhdDisk}:\Windows\System32\drivers" del "${vhdDisk}:\Windows\System32\drivers\termdd.sys" copy "$wimMountName\Windows\Fonts\vgaoem.fon" "${vhdDisk}:\Windows\Fonts" copy "$wimMountName\Windows\inf\errata.inf" "${vhdDisk}:\Windows\inf" copy "$wimMountName\Windows\System32\config\SYSTEM" "${vhdDisk}:\Windows\System32\config" copy "$wimMountName\Windows\SysWOW64\ntdll.dll" "${vhdDisk}:\Windows\SysWOW64" copy native.exe "${vhdDisk}:\Windows\System32\smss.exe" "ntoskrnl.exe", "hal.dll", "ci.dll", "pshed.dll", "clfs.sys", "kdcom.dll", "ntdll.dll", "apisetschema.dll", "winload.exe", "bootvid.dll", "bootres.dll", "l_intl.nls", "c_1252.nls", "c_437.nls" |% { copy (Join-Path "$wimMountName\Windows\System32" $_) "${vhdDisk}:\Windows\System32" } @" select vdisk file=$pwd\$vhdName detach vdisk "@ | diskpart dism /unmount-wim /mountdir:$wimMountName /discard
      
      





次のようになります。





すべてが正しく行われた場合(そして運がよければ:-))、しばらくするとdisk.vhdファイルが同じディレクトリに表示されます-仮想マシンで実行できます(VirtualBoxでテストしましたが、これが必要ない理由はわかりません) Virtual PC、Hyper-Vなどで動作します):





さて、最後にいくつかのコメント。



1.ほぼ300個のドライバーがコピーされ、ダウンロードされます-約100個、特定のシステムで実際に必要です-10〜20個。

2. install.wimの高さ8メガバイトのSYSTEMは、boot.wimの2メガバイトに非常に普通に置き換えることができます。または、最大100キロバイトの何かを手動でブラインドすることができます。

3. bcdbootは、すべてのbootmgrローカリゼーションと数メガバイトのフォント(主にCJK用)をコピーします-カットできます

4.イメージの作成時にtermdd.sysが削除されることに気付くかもしれません-これは機能しないためではありません。 別のキーボードデバイス(通常モードではターミナルセッションでリモートマシンの「ボタンを押す」に使用される)を作成するだけで、native.exeを変更してすべてのキーボードからキーストロークを読み取るのは面倒でした。

5.起動時にグラフィックを抑制し、bootvid.dllとbootres.dllを拒否できます。



最も重要なことは、win32k.sysが作成されたイメージにコピーされないことです。これにより、このイメージがグラフィックスなしで比較的うまく機能することを妨げません。 私が言ったように、完全なコンソールシェルをねじ込み、Windowsサブシステムを切り取り、Posixだけを残すことができます(私にとってはこれは非常に奇妙な欲望ですが、人々はしばしば奇妙なものを望んでいます)。 または(さらに奇妙な望み)NTカーネルの上にネイティブX11を実装します。 smssを置き換えて、カーネル上で動作するすべてを「完全に制御」できます。または、smssのままにして、レジストリ内のいくつかの編集でロード済みサブシステムのセットを変更できます。 つまり、「コアにしっかりと固定された」グラフィックはまったくありません。



ご清聴ありがとうございました。



All Articles