OSDev http://osdev.su/ |
|
EFI Boot Services - загрузка файла http://osdev.su/viewtopic.php?f=6&t=1118 |
Страница 1 из 1 |
Автор: | KIV [ 10 окт 2015, 02:39 ] |
Заголовок сообщения: | EFI Boot Services - загрузка файла |
Решил, что пора бы разобраться с UEFI, всё же подавляющее большинство новых материнских плат уже его поддерживает. Для начала поигрался с консольным вводом-выводом, но этого явно мало для создания полноценного загрузчика. А именно - нужно уметь грузить файлы в ОЗУ с загрузочного диска. Если под BIOS был простой int 0x13, а драйвер ФС каждый лепил сам, то на UEFI эти функции уже реализованы в прошивке. Более того, до вызова Exit Boot Services прямой доступ к железу строго-настрого запрещён спецификацией. В отличии от BIOS UEFI куда более универсальная и всеохватывающая спецификация (местами, быть может даже слишком), поэтому так сходу разобраться у меня не получается. Никто не может подкинуть примера чтения в ОЗУ файла, находящегося на той же ФС, что и наш загрузчик? |
Автор: | dixie [ 11 окт 2015, 12:49 ] |
Заголовок сообщения: | Re: EFI Boot Services - загрузка файла |
EFI местами крив и уныл до безобразия... Работа с экраном, с клавиатурой - даже новые протоколы. Дикие баги - в общем, бяка Но есть уже везде, да. Я использую древний EFI тулкит, аж под 1.x, добавляя прямо в свой код описание новых протоколов - поскольку он ближе и понятней (проще ). Вот в этом архиве есть архив с 64-битной частью EFIшного варианта загрузчика (QSINIT_EFI.ZIP), там можно покурить на тему работы с клавиатурой, экраном, чтение файла, определение загрузочного диска/раздела. Это, собстно, типа hal функций, которые зовутся из 32-битной части. Чтение файла там mfs_open/read/close (имя в статическом буфере). |
Автор: | KIV [ 16 окт 2015, 13:48 ] |
Заголовок сообщения: | Re: EFI Boot Services - загрузка файла |
В итоге реализовал следующую функцию загрузки файла: Код: if (efiSysTable->BootServices->OpenProtocol(efiImageHandle, &loadedImageProtocol, (void**)&efiLoadedImage, efiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL) != EFI_SUCCESS) { fatalError("failed to get LoadedImageProtocol"); } if (efiSysTable->BootServices->OpenProtocol(efiLoadedImage->DeviceHandle, &simpleFileSystemProtocol, (void**)&efiFileIoInterface, efiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL) != EFI_SUCCESS) { fatalError("failed to get SimpleFileSystemProtocol"); } if (efiFileIoInterface->OpenVolume(efiFileIoInterface, &efiFileSystem) != EFI_SUCCESS) { fatalError("failed to get FileProtocol"); } ... int platform_loadFile(const char *fileName, void *buffer, int bufferSize) { CHAR16 *fileNameUTF16 = makeUTF16(fileName); if (fileNameUTF16 == NULL) return -1; for (CHAR16 *chr = fileNameUTF16; *chr; chr++) { if (*chr == '/') { *chr = '\\'; } } EFI_FILE_HANDLE file; int count = -1; if (efiFileSystem->Open(efiFileSystem, &file, fileNameUTF16, EFI_FILE_MODE_READ, 0) == EFI_SUCCESS) { UINTN infoSize = 0; if (file->GetInfo(file, &fileInfoId, &infoSize, NULL) == EFI_BUFFER_TOO_SMALL) { EFI_FILE_INFO *info = malloc(infoSize); if (file->GetInfo(file, &fileInfoId, &infoSize, info) == EFI_SUCCESS) { if (buffer && bufferSize) { UINTN cnt = bufferSize; if (file->Read(file, &cnt, buffer) == EFI_SUCCESS) { count = cnt; } } else { count = info->FileSize; } } else free(info); } else file->Close(file); } free(fileNameUTF16); return count; } Если не указывать буфер для загрузки, то можно узнать размер файла, затем выделить под него место и прочитать данные. Мне этого в принципе достаточно - гружу файл целиком, а потом в ОЗУ разбираюсь уже что загрузил. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |