@@ -21,13 +21,15 @@ use {std::fs::Permissions, std::os::unix::fs::PermissionsExt};
2121enum OvmfFileType {
2222 Code ,
2323 Vars ,
24+ Shell ,
2425}
2526
2627impl OvmfFileType {
2728 fn as_str ( & self ) -> & ' static str {
2829 match self {
2930 Self :: Code => "code" ,
3031 Self :: Vars => "vars" ,
32+ Self :: Shell => "shell" ,
3133 }
3234 }
3335
@@ -47,6 +49,10 @@ impl OvmfFileType {
4749 opt_path = & opt. ovmf_vars ;
4850 var_name = "OVMF_VARS" ;
4951 }
52+ Self :: Shell => {
53+ opt_path = & None ;
54+ var_name = "OVMF_SHELL" ;
55+ }
5056 }
5157 if let Some ( path) = opt_path {
5258 Some ( path. clone ( ) )
@@ -59,6 +65,7 @@ impl OvmfFileType {
5965struct OvmfPaths {
6066 code : PathBuf ,
6167 vars : PathBuf ,
68+ shell : PathBuf ,
6269}
6370
6471impl OvmfPaths {
@@ -78,6 +85,7 @@ impl OvmfPaths {
7885 match file_type {
7986 OvmfFileType :: Code => & self . code ,
8087 OvmfFileType :: Vars => & self . vars ,
88+ OvmfFileType :: Shell => & self . shell ,
8189 }
8290 }
8391
@@ -88,16 +96,19 @@ impl OvmfPaths {
8896 UefiArch :: AArch64 => Self {
8997 code : "/usr/share/edk2-armvirt/aarch64/QEMU_CODE.fd" . into ( ) ,
9098 vars : "/usr/share/edk2-armvirt/aarch64/QEMU_VARS.fd" . into ( ) ,
99+ shell : "" . into ( ) ,
91100 } ,
92101 // Package "edk2-ovmf".
93102 UefiArch :: IA32 => Self {
94103 code : "/usr/share/edk2-ovmf/ia32/OVMF_CODE.fd" . into ( ) ,
95104 vars : "/usr/share/edk2-ovmf/ia32/OVMF_VARS.fd" . into ( ) ,
105+ shell : "" . into ( ) ,
96106 } ,
97107 // Package "edk2-ovmf".
98108 UefiArch :: X86_64 => Self {
99109 code : "/usr/share/edk2-ovmf/x64/OVMF_CODE.fd" . into ( ) ,
100110 vars : "/usr/share/edk2-ovmf/x64/OVMF_VARS.fd" . into ( ) ,
111+ shell : "" . into ( ) ,
101112 } ,
102113 }
103114 }
@@ -109,6 +120,7 @@ impl OvmfPaths {
109120 UefiArch :: AArch64 => Some ( Self {
110121 code : "/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw" . into ( ) ,
111122 vars : "/usr/share/edk2/aarch64/vars-template-pflash.raw" . into ( ) ,
123+ shell : "" . into ( ) ,
112124 } ) ,
113125 // There's no official ia32 package.
114126 UefiArch :: IA32 => None ,
@@ -118,6 +130,7 @@ impl OvmfPaths {
118130 // doesn't have a plain "OVMF_CODE.fd".
119131 code : "/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd" . into ( ) ,
120132 vars : "/usr/share/edk2/ovmf/OVMF_VARS.fd" . into ( ) ,
133+ shell : "" . into ( ) ,
121134 } ) ,
122135 }
123136 }
@@ -130,16 +143,19 @@ impl OvmfPaths {
130143 UefiArch :: AArch64 => Self {
131144 code : "/usr/share/AAVMF/AAVMF_CODE.fd" . into ( ) ,
132145 vars : "/usr/share/AAVMF/AAVMF_VARS.fd" . into ( ) ,
146+ shell : "" . into ( ) ,
133147 } ,
134148 // Package "ovmf-ia32".
135149 UefiArch :: IA32 => Self {
136150 code : "/usr/share/OVMF/OVMF32_CODE_4M.secboot.fd" . into ( ) ,
137151 vars : "/usr/share/OVMF/OVMF32_VARS_4M.fd" . into ( ) ,
152+ shell : "" . into ( ) ,
138153 } ,
139154 // Package "ovmf".
140155 UefiArch :: X86_64 => Self {
141156 code : "/usr/share/OVMF/OVMF_CODE.fd" . into ( ) ,
142157 vars : "/usr/share/OVMF/OVMF_VARS.fd" . into ( ) ,
158+ shell : "" . into ( ) ,
143159 } ,
144160 }
145161 }
@@ -151,16 +167,19 @@ impl OvmfPaths {
151167 UefiArch :: AArch64 => Self {
152168 code : "/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw" . into ( ) ,
153169 vars : "/usr/share/edk2/aarch64/vars-template-pflash.raw" . into ( ) ,
170+ shell : "" . into ( ) ,
154171 } ,
155172 // Package "edk2-ovmf-ia32".
156173 UefiArch :: IA32 => Self {
157174 code : "/usr/share/edk2/ovmf-ia32/OVMF_CODE.fd" . into ( ) ,
158175 vars : "/usr/share/edk2/ovmf-ia32/OVMF_VARS.fd" . into ( ) ,
176+ shell : "/usr/share/edk2/ovmf-ia32/Shell.efi" . into ( ) ,
159177 } ,
160178 // Package "edk2-ovmf".
161179 UefiArch :: X86_64 => Self {
162180 code : "/usr/share/edk2/ovmf/OVMF_CODE.fd" . into ( ) ,
163181 vars : "/usr/share/edk2/ovmf/OVMF_VARS.fd" . into ( ) ,
182+ shell : "/usr/share/edk2/ovmf/Shell.efi" . into ( ) ,
164183 } ,
165184 }
166185 }
@@ -189,15 +208,18 @@ impl OvmfPaths {
189208 UefiArch :: AArch64 => Self {
190209 code : r"C:\Program Files\qemu\share\edk2-aarch64-code.fd" . into ( ) ,
191210 vars : r"C:\Program Files\qemu\share\edk2-arm-vars.fd" . into ( ) ,
211+ shell : "" . into ( ) ,
192212 } ,
193213 UefiArch :: IA32 => Self {
194214 code : r"C:\Program Files\qemu\share\edk2-i386-code.fd" . into ( ) ,
195215 vars : r"C:\Program Files\qemu\share\edk2-i386-vars.fd" . into ( ) ,
216+ shell : "" . into ( ) ,
196217 } ,
197218 UefiArch :: X86_64 => Self {
198219 code : r"C:\Program Files\qemu\share\edk2-x86_64-code.fd" . into ( ) ,
199220 // There's no x86_64 vars file, but the i386 one works.
200221 vars : r"C:\Program Files\qemu\share\edk2-i386-vars.fd" . into ( ) ,
222+ shell : "" . into ( ) ,
201223 } ,
202224 }
203225 }
@@ -271,8 +293,9 @@ impl OvmfPaths {
271293
272294 let code = Self :: find_ovmf_file ( OvmfFileType :: Code , opt, & candidates) ?;
273295 let vars = Self :: find_ovmf_file ( OvmfFileType :: Vars , opt, & candidates) ?;
296+ let shell = Self :: find_ovmf_file ( OvmfFileType :: Shell , opt, & candidates) . unwrap_or_default ( ) ;
274297
275- Ok ( Self { code, vars } )
298+ Ok ( Self { code, vars, shell } )
276299 }
277300}
278301
@@ -415,7 +438,7 @@ fn process_qemu_io(mut monitor_io: Io, mut serial_io: Io, tmp_dir: &Path) -> Res
415438}
416439
417440/// Create an EFI boot directory to pass into QEMU.
418- fn build_esp_dir ( opt : & QemuOpt ) -> Result < PathBuf > {
441+ fn build_esp_dir ( opt : & QemuOpt , ovmf_paths : & OvmfPaths ) -> Result < PathBuf > {
419442 let build_mode = if opt. build_mode . release {
420443 "release"
421444 } else {
@@ -425,24 +448,37 @@ fn build_esp_dir(opt: &QemuOpt) -> Result<PathBuf> {
425448 . join ( opt. target . as_triple ( ) )
426449 . join ( build_mode) ;
427450 let esp_dir = build_dir. join ( "esp" ) ;
451+
452+ // Create boot dir.
428453 let boot_dir = esp_dir. join ( "EFI" ) . join ( "Boot" ) ;
429- let built_file = if let Some ( example) = & opt. example {
430- build_dir. join ( "examples" ) . join ( format ! ( "{example}.efi" ) )
431- } else {
432- build_dir. join ( "uefi-test-runner.efi" )
433- } ;
434- let output_file = match * opt. target {
454+ if !boot_dir. exists ( ) {
455+ fs_err:: create_dir_all ( & boot_dir) ?;
456+ }
457+
458+ let boot_file_name = match * opt. target {
435459 UefiArch :: AArch64 => "BootAA64.efi" ,
436460 UefiArch :: IA32 => "BootIA32.efi" ,
437461 UefiArch :: X86_64 => "BootX64.efi" ,
438462 } ;
439- if !boot_dir. exists ( ) {
440- fs_err:: create_dir_all ( & boot_dir) ?;
441- }
442- fs_err:: copy ( built_file, boot_dir. join ( output_file) ) ?;
443463
444- // Add a test file that is used in the media protocol tests.
445- fs_err:: write ( boot_dir. join ( "test_input.txt" ) , "test input data" ) ?;
464+ if let Some ( example) = & opt. example {
465+ let src_path = build_dir. join ( "examples" ) . join ( format ! ( "{example}.efi" ) ) ;
466+ fs_err:: copy ( src_path, boot_dir. join ( boot_file_name) ) ?;
467+ } else {
468+ let shell_launcher = build_dir. join ( "shell_launcher.efi" ) ;
469+ fs_err:: copy ( shell_launcher, boot_dir. join ( boot_file_name) ) ?;
470+
471+ let test_runner = build_dir. join ( "uefi-test-runner.efi" ) ;
472+ fs_err:: copy ( test_runner, boot_dir. join ( "test_runner.efi" ) ) ?;
473+
474+ // TODO:
475+ // Does Ubuntu (as used in the CI pipeline) even ship the shell app?
476+ // Ignore error since there may not be a shell app.
477+ let _ = fs_err:: copy ( & ovmf_paths. shell , boot_dir. join ( "shell.efi" ) ) ;
478+
479+ // Add a test file that is used in the media protocol tests.
480+ fs_err:: write ( boot_dir. join ( "test_input.txt" ) , "test input data" ) ?;
481+ } ;
446482
447483 Ok ( esp_dir)
448484}
@@ -469,8 +505,6 @@ impl Drop for ChildWrapper {
469505}
470506
471507pub fn run_qemu ( arch : UefiArch , opt : & QemuOpt ) -> Result < ( ) > {
472- let esp_dir = build_esp_dir ( opt) ?;
473-
474508 let qemu_exe = match arch {
475509 UefiArch :: AArch64 => "qemu-system-aarch64" ,
476510 UefiArch :: IA32 | UefiArch :: X86_64 => "qemu-system-x86_64" ,
@@ -526,9 +560,9 @@ pub fn run_qemu(arch: UefiArch, opt: &QemuOpt) -> Result<()> {
526560 }
527561
528562 // Exit instead of rebooting in the CI.
529- if opt. ci {
530- cmd. arg ( "-no-reboot" ) ;
531- }
563+ // if opt.ci {
564+ // cmd.arg("-no-reboot");
565+ // }
532566
533567 // Map the QEMU exit signal to port f4.
534568 cmd. args ( [ "-device" , "isa-debug-exit,iobase=0xf4,iosize=0x04" ] ) ;
@@ -566,6 +600,7 @@ pub fn run_qemu(arch: UefiArch, opt: &QemuOpt) -> Result<()> {
566600 // Mount a local directory as a FAT partition.
567601 cmd. arg ( "-drive" ) ;
568602 let mut drive_arg = OsString :: from ( "format=raw,file=fat:rw:" ) ;
603+ let esp_dir = build_esp_dir ( opt, & ovmf_paths) ?;
569604 drive_arg. push ( esp_dir) ;
570605 cmd. arg ( drive_arg) ;
571606
0 commit comments