Skip to content

Commit f52c1a1

Browse files
committed
efi: Implement writing to block device
Using the SectorWrite trait added to the block device implement writing to the block device. This is useful for bootloaders that need to write to the block device in order to be able support fallback booting. In particular this enables the firmware to be used with Ubuntu 19.10 ("eoan".) Signed-off-by: Rob Bradford <robert.bradford@intel.com>
1 parent 7381a97 commit f52c1a1

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

src/efi/block.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,18 +145,43 @@ pub extern "win64" fn read_blocks(
145145

146146
#[cfg(not(test))]
147147
pub extern "win64" fn write_blocks(
148-
_: *mut BlockIoProtocol,
148+
proto: *mut BlockIoProtocol,
149149
_: u32,
150-
_: u64,
151-
_: usize,
152-
_: *mut c_void,
150+
start: u64,
151+
size: usize,
152+
buffer: *mut c_void,
153153
) -> Status {
154-
Status::UNSUPPORTED
154+
let wrapper = container_of!(proto, BlockWrapper, proto);
155+
let wrapper = unsafe { &*wrapper };
156+
157+
let blocks = (size / 512) as usize;
158+
let mut region = crate::mem::MemoryRegion::new(buffer as u64, size as u64);
159+
160+
for i in 0..blocks {
161+
use crate::block::SectorWrite;
162+
let data = region.as_mut_slice(i as u64 * 512, 512);
163+
let block = unsafe { &*wrapper.block };
164+
match block.write(wrapper.start_lba + start + i as u64, data) {
165+
Ok(()) => continue,
166+
Err(_) => {
167+
return Status::DEVICE_ERROR;
168+
}
169+
};
170+
}
171+
172+
Status::SUCCESS
155173
}
156174

157175
#[cfg(not(test))]
158-
pub extern "win64" fn flush_blocks(_: *mut BlockIoProtocol) -> Status {
159-
Status::UNSUPPORTED
176+
pub extern "win64" fn flush_blocks(proto: *mut BlockIoProtocol) -> Status {
177+
let wrapper = container_of!(proto, BlockWrapper, proto);
178+
let wrapper = unsafe { &*wrapper };
179+
use crate::block::SectorWrite;
180+
let block = unsafe { &*wrapper.block };
181+
match block.flush() {
182+
Ok(()) => Status::SUCCESS,
183+
Err(_) => Status::DEVICE_ERROR,
184+
}
160185
}
161186

162187
#[cfg(not(test))]

0 commit comments

Comments
 (0)