* Changed bootman.S to use the BIOS provided drive to stage load itself, as well

as when the boot menu entry has a 0 BIOS drive. This allows the boot loader to
  be installed on any drive.
* Implemented BootDrive class, and changed LegacyBootMenu the way it should
  work now. Installing the boot menu should now work again, and the first time
  while installing Haiku.
* Removed MakeArray.cpp - we already have such a tool in our repository.
* Build BootLoader.h automatically during the build process - the only
  disadvantage is that you can only build it on x86 now (but other systems
  don't use this boot loader, anyway).
* In general, the BootManager is prepared to handle different kinds of boot
  menus; one only needs to write a class BootMenu implementation for this to
  work - and have the possibility to choose between different menus, if there
  are more than one per platform/partitioning system.
* Renamed quite a few methods.
* Automatic whitespace cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40149 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2011-01-08 13:47:22 +00:00
parent 9f609ed7c6
commit 49c044ab9f
14 changed files with 449 additions and 345 deletions
+98
View File
@@ -0,0 +1,98 @@
/*
* Copyright 2011, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "BootDrive.h"
#include <DiskDevice.h>
#include <DiskDeviceRoster.h>
#include <Volume.h>
#include <VolumeRoster.h>
BootDrive::BootDrive(const char* path)
:
fPath(path)
{
}
BootDrive::~BootDrive()
{
}
BootMenu*
BootDrive::InstalledMenu(const BootMenuList& menus) const
{
for (int32 i = 0; i < menus.CountItems(); i++) {
BootMenu* menu = menus.ItemAt(i);
if (menu->IsInstalled(*this))
return menu;
}
return NULL;
}
status_t
BootDrive::CanMenuBeInstalled(const BootMenuList& menus) const
{
status_t status = B_ERROR;
for (int32 i = 0; i < menus.CountItems(); i++) {
status = menus.ItemAt(i)->CanBeInstalled(*this);
if (status == B_OK)
return status;
}
return status;
}
/*! Adds all boot menus from the list \a from that support the drive to \a to.
*/
void
BootDrive::AddSupportedMenus(const BootMenuList& from, BootMenuList& to)
{
for (int32 i = 0; i < from.CountItems(); i++) {
BootMenu* menu = from.ItemAt(i);
if (menu->CanBeInstalled(*this))
to.AddItem(menu);
}
}
const char*
BootDrive::Path() const
{
return fPath.Path();
}
bool
BootDrive::IsBootDrive() const
{
BVolumeRoster volumeRoster;
BVolume volume;
if (volumeRoster.GetBootVolume(&volume) != B_OK)
return false;
BDiskDeviceRoster roster;
BDiskDevice device;
if (roster.FindPartitionByVolume(volume, &device, NULL) == B_OK) {
BPath path;
if (device.GetPath(&path) == B_OK && path == fPath)
return true;
}
return false;
}
status_t
BootDrive::GetDiskDevice(BDiskDevice& device) const
{
BDiskDeviceRoster roster;
return roster.GetDeviceForPath(fPath.Path(), &device);
}
+15 -6
View File
@@ -6,21 +6,30 @@
#define BOOT_DRIVE_H #define BOOT_DRIVE_H
#include <File.h> #include <Path.h>
#include "BootMenu.h"
class BDiskDevice;
class BootDrive { class BootDrive {
public: public:
BootDrive(); BootDrive(const char* path);
virtual ~BootDrive(); virtual ~BootDrive();
bool IsBootMenuInstalled() const; BootMenu* InstalledMenu(
bool CanBootMenuBeInstalled() const; const BootMenuList& menus) const;
status_t CanMenuBeInstalled(
const BootMenuList& menus) const;
void AddSupportedMenus(const BootMenuList& from,
BootMenuList& to);
const char* Path() const;
bool IsBootDrive() const; bool IsBootDrive() const;
status_t GetStream(BPositionIO* stream); status_t GetDiskDevice(BDiskDevice& device) const;
status_t GetBIOSDrive(uint8* drive);
private: private:
BPath fPath; BPath fPath;
-71
View File
@@ -1,71 +0,0 @@
// THIS FILE WAS GENERATED WITH
// ./make_array kBootLoader bootman.bin
static const uint8 kBootLoader[] = {
0xb8, 0xc0, 0x07, 0x8e, 0xd8, 0x8e, 0xc0, 0x8e, 0xd0, 0xbc, 0xf3, 0xff, 0x89, 0xe5, 0xfc, 0xb4,
0x06, 0x30, 0xc0, 0xb7, 0x0f, 0x31, 0xc9, 0xba, 0x4f, 0x18, 0xcd, 0x10, 0xe8, 0x63, 0x00, 0xb7,
0x00, 0xba, 0x1f, 0x01, 0x89, 0x56, 0x08, 0xbe, 0xa9, 0x00, 0xb3, 0x0f, 0xe8, 0x2f, 0x00, 0xba,
0x1b, 0x17, 0x89, 0x56, 0x08, 0xb3, 0x07, 0xbe, 0xbc, 0x00, 0xe8, 0x21, 0x00, 0xb4, 0x42, 0xb2,
0x80, 0xbe, 0x99, 0x00, 0xcd, 0x13, 0x72, 0x03, 0xe9, 0xb5, 0x01, 0xe8, 0x43, 0x00, 0xbe, 0xd7,
0x00, 0xb3, 0x04, 0xe8, 0x08, 0x00, 0xb4, 0x00, 0xcd, 0x16, 0xb2, 0x80, 0xcd, 0x19, 0x50, 0x53,
0x51, 0x52, 0x30, 0xff, 0xe9, 0x11, 0x00, 0x8b, 0x56, 0x08, 0xb4, 0x02, 0xcd, 0x10, 0xfe, 0x46,
0x08, 0xb9, 0x01, 0x00, 0xb4, 0x09, 0xcd, 0x10, 0xac, 0x3c, 0x00, 0x75, 0xea, 0x5a, 0x59, 0x5b,
0x58, 0xc3, 0xb4, 0x03, 0xcd, 0x10, 0x89, 0x4e, 0x0a, 0xb4, 0x01, 0xb9, 0x00, 0x20, 0xcd, 0x10,
0xc3, 0x8b, 0x4e, 0x0a, 0xb4, 0x01, 0xcd, 0x10, 0xc3, 0x10, 0x00, 0x03, 0x00, 0x00, 0x02, 0xc0,
0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x61, 0x69, 0x6b, 0x75, 0x20, 0x42,
0x6f, 0x6f, 0x74, 0x20, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x00, 0x53, 0x65, 0x6c, 0x65,
0x63, 0x74, 0x20, 0x61, 0x6e, 0x20, 0x4f, 0x53, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68,
0x65, 0x20, 0x6d, 0x65, 0x6e, 0x75, 0x00, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x61,
0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x21, 0x00, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa,
0xa1, 0x17, 0x04, 0x89, 0x46, 0x00, 0xb8, 0x13, 0x00, 0xf7, 0x26, 0x19, 0x04, 0x89, 0xd3, 0x50,
0xb4, 0x00, 0xcd, 0x1a, 0x58, 0x01, 0xd0, 0x11, 0xcb, 0x89, 0x46, 0x04, 0x89, 0x5e, 0x06, 0xa0,
0x15, 0x04, 0xd0, 0xe8, 0xb3, 0x0c, 0x28, 0xc3, 0x88, 0x5e, 0x02, 0xb4, 0x02, 0xcd, 0x16, 0x24,
0x08, 0x74, 0x06, 0xc7, 0x06, 0x19, 0x04, 0xff, 0xff, 0xe8, 0x64, 0x00, 0x81, 0x3e, 0x19, 0x04,
0xff, 0xff, 0x74, 0x25, 0xb4, 0x01, 0xcd, 0x16, 0x75, 0x1f, 0xe8, 0x05, 0x00, 0x73, 0xf5, 0xe9,
0xa6, 0x00, 0xb4, 0x00, 0xcd, 0x1a, 0x3b, 0x4e, 0x06, 0x72, 0x07, 0x77, 0x07, 0x3b, 0x56, 0x04,
0x77, 0x02, 0xf8, 0xc3, 0xf9, 0xc3, 0xe8, 0x37, 0x00, 0xb4, 0x00, 0xcd, 0x16, 0x80, 0xfc, 0x50,
0x74, 0x0d, 0x80, 0xfc, 0x48, 0x74, 0x19, 0x80, 0xfc, 0x1c, 0x75, 0xed, 0xe9, 0x79, 0x00, 0x8b,
0x46, 0x00, 0x40, 0x3b, 0x06, 0x15, 0x04, 0x75, 0x02, 0x31, 0xc0, 0x89, 0x46, 0x00, 0xeb, 0xd6,
0x8b, 0x46, 0x00, 0x09, 0xc0, 0x75, 0x03, 0xa1, 0x15, 0x04, 0x48, 0x89, 0x46, 0x00, 0xeb, 0xc6,
0x8a, 0x46, 0x02, 0x88, 0x46, 0x09, 0xbe, 0x1b, 0x04, 0x31, 0xc9, 0xac, 0x04, 0x03, 0xd0, 0xe8,
0xb2, 0x28, 0x28, 0xc2, 0x88, 0x56, 0x08, 0xb0, 0x10, 0xe8, 0x30, 0x00, 0xfe, 0x46, 0x08, 0x89,
0xcf, 0x81, 0xe7, 0x03, 0x00, 0x8a, 0x9d, 0xda, 0x03, 0x3b, 0x4e, 0x00, 0x75, 0x03, 0x80, 0xf3,
0x08, 0xe8, 0xb6, 0x00, 0x81, 0xc6, 0x09, 0x00, 0x80, 0x46, 0x08, 0x01, 0xb0, 0x11, 0xe8, 0x0b,
0x00, 0xfe, 0x46, 0x09, 0x41, 0x3b, 0x0e, 0x15, 0x04, 0x75, 0xc0, 0xc3, 0x3b, 0x4e, 0x00, 0x74,
0x02, 0xb0, 0x20, 0xb3, 0x0f, 0xe9, 0xb6, 0x00, 0xe8, 0x96, 0xfd, 0xe8, 0x83, 0x00, 0xac, 0x88,
0xc2, 0xbf, 0xd2, 0x03, 0xb9, 0x04, 0x00, 0xad, 0xab, 0xe2, 0xfc, 0xb4, 0x42, 0xbe, 0xca, 0x03,
0xcd, 0x13, 0xbe, 0xde, 0x03, 0x72, 0x40, 0xa1, 0xfe, 0x01, 0x3d, 0x55, 0xaa, 0xbe, 0xf4, 0x03,
0x75, 0x35, 0xb4, 0x06, 0x30, 0xc0, 0xb7, 0x0f, 0x31, 0xc9, 0xba, 0x4f, 0x18, 0xcd, 0x10, 0xc7,
0x46, 0x08, 0x00, 0x00, 0xbe, 0x0d, 0x04, 0xb3, 0x07, 0xe8, 0x4e, 0x00, 0xfe, 0x46, 0x08, 0xe8,
0x29, 0x00, 0x46, 0xe8, 0x44, 0x00, 0xba, 0x00, 0x01, 0x30, 0xff, 0xb4, 0x02, 0xcd, 0x10, 0xe8,
0x2f, 0x00, 0x8a, 0x14, 0xe9, 0xa9, 0xfc, 0xba, 0x1a, 0x15, 0x89, 0x56, 0x08, 0xbb, 0x0f, 0x00,
0xe8, 0x27, 0x00, 0xb4, 0x00, 0xcd, 0x16, 0xb2, 0x80, 0xcd, 0x19, 0xbe, 0x1b, 0x04, 0x8b, 0x4e,
0x00, 0x41, 0x30, 0xe4, 0xe9, 0x07, 0x00, 0xac, 0x01, 0xc6, 0x81, 0xc6, 0x09, 0x00, 0xe2, 0xf7,
0xc3, 0xe8, 0xe7, 0xff, 0xac, 0x30, 0xe4, 0x01, 0xc6, 0xc3, 0x50, 0x53, 0x51, 0x52, 0x30, 0xff,
0xe9, 0x11, 0x00, 0x8b, 0x56, 0x08, 0xb4, 0x02, 0xcd, 0x10, 0xfe, 0x46, 0x08, 0xb9, 0x01, 0x00,
0xb4, 0x09, 0xcd, 0x10, 0xac, 0x3c, 0x00, 0x75, 0xea, 0x5a, 0x59, 0x5b, 0x58, 0xc3, 0x50, 0x53,
0x51, 0x52, 0x30, 0xff, 0x8b, 0x56, 0x08, 0xb4, 0x02, 0xcd, 0x10, 0xfe, 0x46, 0x08, 0xb9, 0x01,
0x00, 0xb4, 0x09, 0xcd, 0x10, 0x5a, 0x59, 0x5b, 0x58, 0xc3, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00,
0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x02, 0x03, 0x45, 0x72,
0x72, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x63, 0x74,
0x6f, 0x72, 0x73, 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62,
0x6c, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x4c, 0x6f, 0x61,
0x64, 0x69, 0x6e, 0x67, 0x00
};
+35 -14
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Axel Dörfler, [email protected]
* Michael Pfeiffer <[email protected]> * Michael Pfeiffer <[email protected]>
*/ */
@@ -18,6 +19,7 @@
#include <Path.h> #include <Path.h>
#include <String.h> #include <String.h>
#include "BootDrive.h"
#include "DefaultPartitionPage.h" #include "DefaultPartitionPage.h"
#include "DescriptionPage.h" #include "DescriptionPage.h"
#include "DrivesPage.h" #include "DrivesPage.h"
@@ -39,11 +41,12 @@
BootManagerController::BootManagerController() BootManagerController::BootManagerController()
:
fBootDrive(NULL),
fBootMenu(NULL)
{ {
#if USE_TEST_BOOT_DRIVE #if USE_TEST_BOOT_DRIVE
fBootMenu = new TestBootDrive(); fBootMenu = new TestBootDrive();
#else
fBootMenu = new LegacyBootMenu();
#endif #endif
// set defaults // set defaults
@@ -65,7 +68,8 @@ BootManagerController::BootManagerController()
fSettings.AddString("file", ""); fSettings.AddString("file", "");
} }
fReadPartitionsStatus = fBootMenu->ReadPartitions(&fSettings); // That's the only boot menu we support at the moment.
fBootMenus.AddItem(new LegacyBootMenu());
} }
@@ -80,8 +84,8 @@ BootManagerController::Previous(WizardView* wizard)
if (CurrentState() != kStateEntry) if (CurrentState() != kStateEntry)
WizardController::Previous(wizard); WizardController::Previous(wizard);
else { else {
WizardController::Next(wizard);
fSettings.ReplaceBool("install", false); fSettings.ReplaceBool("install", false);
WizardController::Next(wizard);
} }
} }
@@ -89,9 +93,7 @@ BootManagerController::Previous(WizardView* wizard)
int32 int32
BootManagerController::InitialState() BootManagerController::InitialState()
{ {
if (fReadPartitionsStatus == B_OK) return kStateEntry;
return kStateEntry;
return kStateErrorEntry;
} }
@@ -101,11 +103,29 @@ BootManagerController::NextState(int32 state)
switch (state) { switch (state) {
case kStateEntry: case kStateEntry:
{ {
if (fSettings.FindBool("install")) { const char* path;
if (fBootMenu->IsBootMenuInstalled(&fSettings)) if (fSettings.FindString("disk", &path) != B_OK)
return kStatePartitions; return kStateErrorEntry;
return kStateSaveMBR; delete fBootDrive;
fBootDrive = new BootDrive(path);
fBootMenu = fBootDrive->InstalledMenu(fBootMenus);
if (fSettings.FindBool("install")) {
int32 nextState = fBootMenu != NULL
? kStatePartitions : kStateSaveMBR;
// TODO: call BootDrive::AddSupportedMenus() once we support
// more than one type of boot menu - we'll probably need a
// requester to choose from them then as well.
if (fBootMenu == NULL)
fBootMenu = fBootMenus.ItemAt(0);
fCollectPartitionsStatus = fBootMenu->CollectPartitions(
*fBootDrive, fSettings);
return nextState;
} }
return kStateUninstall; return kStateUninstall;
@@ -186,7 +206,7 @@ BootManagerController::_WriteBootMenu()
if (alert->Go() == 1) if (alert->Go() == 1)
return false; return false;
fWriteBootMenuStatus = fBootMenu->WriteBootMenu(&fSettings); fWriteBootMenuStatus = fBootMenu->Install(*fBootDrive, fSettings);
return true; return true;
} }
@@ -238,7 +258,8 @@ BootManagerController::CreatePage(int32 state, WizardView* wizard)
switch (state) { switch (state) {
case kStateEntry: case kStateEntry:
page = new DrivesPage(wizard, &fSettings, "drives"); fSettings.ReplaceBool("install", true);
page = new DrivesPage(wizard, fBootMenus, &fSettings, "drives");
break; break;
case kStateErrorEntry: case kStateErrorEntry:
page = _CreateErrorEntryPage(); page = _CreateErrorEntryPage();
@@ -286,7 +307,7 @@ BootManagerController::_CreateErrorEntryPage()
{ {
BString description; BString description;
if (fReadPartitionsStatus == B_PARTITION_TOO_SMALL) { if (fCollectPartitionsStatus == B_PARTITION_TOO_SMALL) {
description << B_TRANSLATE_COMMENT("Partition table not compatible", description << B_TRANSLATE_COMMENT("Partition table not compatible",
"Title") << "\n\n" "Title") << "\n\n"
<< B_TRANSLATE("The partition table of the first hard disk is not " << B_TRANSLATE("The partition table of the first hard disk is not "
+5 -2
View File
@@ -13,9 +13,10 @@
#include <Message.h> #include <Message.h>
#include "BootMenu.h"
class BootDrive; class BootDrive;
class BootMenu;
class WizardView; class WizardView;
class WizardPageView; class WizardPageView;
@@ -72,9 +73,11 @@ private:
WizardPageView* _CreateUninstalledPage(); WizardPageView* _CreateUninstalledPage();
BMessage fSettings; BMessage fSettings;
BootMenuList fBootMenus;
BootDrive* fBootDrive;
BootMenu* fBootMenu; BootMenu* fBootMenu;
status_t fReadPartitionsStatus; status_t fCollectPartitionsStatus;
status_t fWriteBootMenuStatus; status_t fWriteBootMenuStatus;
status_t fSaveMBRStatus; status_t fSaveMBRStatus;
status_t fRestoreMBRStatus; status_t fRestoreMBRStatus;
+14 -5
View File
@@ -11,12 +11,14 @@
#include <File.h> #include <File.h>
#include <Message.h> #include <Message.h>
#include <ObjectList.h>
class BootDrive;
/* Setting BMessage Format: /* Setting BMessage Format:
"disk" String (path to boot disk)
"partition" array of BMessage: "partition" array of BMessage:
"show" bool (flag if entry should be added to boot menu) "show" bool (flag if entry should be added to boot menu)
"name" String (the name as shown in boot menu) "name" String (the name as shown in boot menu)
@@ -31,9 +33,14 @@ public:
BootMenu() {} BootMenu() {}
virtual ~BootMenu() {} virtual ~BootMenu() {}
virtual bool IsBootMenuInstalled(BMessage* settings) = 0; virtual bool IsInstalled(const BootDrive& drive) = 0;
virtual status_t ReadPartitions(BMessage* settings) = 0; virtual status_t CanBeInstalled(const BootDrive& drive) = 0;
virtual status_t WriteBootMenu(BMessage* settings) = 0;
virtual status_t CollectPartitions(const BootDrive& drive,
BMessage& settings) = 0;
virtual status_t Install(const BootDrive& drive,
BMessage& settings) = 0;
virtual status_t SaveMasterBootRecord(BMessage* settings, virtual status_t SaveMasterBootRecord(BMessage* settings,
BFile* file) = 0; BFile* file) = 0;
virtual status_t RestoreMasterBootRecord(BMessage* settings, virtual status_t RestoreMasterBootRecord(BMessage* settings,
@@ -45,5 +52,7 @@ public:
BString& displayText) = 0; BString& displayText) = 0;
}; };
typedef BObjectList<BootMenu> BootMenuList;
#endif // BOOT_MENU_H #endif // BOOT_MENU_H
+30 -16
View File
@@ -31,7 +31,8 @@ const uint32 kMsgSelectionChanged = 'slch';
class DriveItem : public BListItem { class DriveItem : public BListItem {
public: public:
DriveItem(const BDiskDevice& device); DriveItem(const BDiskDevice& device,
const BootMenuList& menus);
virtual ~DriveItem(); virtual ~DriveItem();
bool IsInstalled() const; bool IsInstalled() const;
@@ -39,7 +40,6 @@ public:
bool IsBootDrive() const; bool IsBootDrive() const;
const char* Path() const { return fPath.Path(); } const char* Path() const { return fPath.Path(); }
BMessage& Settings() { return fSettings; }
BootDrive* Drive() { return fDrive; } BootDrive* Drive() { return fDrive; }
protected: protected:
@@ -48,7 +48,6 @@ protected:
virtual void Update(BView* owner, const BFont* font); virtual void Update(BView* owner, const BFont* font);
private: private:
BMessage fSettings;
BootDrive* fDrive; BootDrive* fDrive;
BString fName; BString fName;
BPath fPath; BPath fPath;
@@ -56,21 +55,28 @@ private:
float fBaselineOffset; float fBaselineOffset;
float fSecondBaselineOffset; float fSecondBaselineOffset;
float fSizeWidth; float fSizeWidth;
status_t fCanBeInstalled;
bool fIsInstalled;
}; };
DriveItem::DriveItem(const BDiskDevice& device) DriveItem::DriveItem(const BDiskDevice& device, const BootMenuList& menus)
: :
fBaselineOffset(0), fBaselineOffset(0),
fSizeWidth(0) fSizeWidth(0)
{ {
// TODO: retrieve disk name! device.GetPath(&fPath);
if (device.Name() != NULL && device.Name()[0]) if (device.Name() != NULL && device.Name()[0])
fName = device.Name(); fName = device.Name();
else if (strstr(fPath.Path(), "usb") != NULL)
fName = B_TRANSLATE_COMMENT("USB Drive", "Default disk name");
else else
fName = B_TRANSLATE_COMMENT("Hard Drive", "Default disk name"); fName = B_TRANSLATE_COMMENT("Hard Drive", "Default disk name");
device.GetPath(&fPath); fDrive = new BootDrive(fPath.Path());
fIsInstalled = fDrive->InstalledMenu(menus) != NULL;
fCanBeInstalled = fDrive->CanMenuBeInstalled(menus);
char buffer[256]; char buffer[256];
fSize = string_for_size(device.Size(), buffer, sizeof(buffer)); fSize = string_for_size(device.Size(), buffer, sizeof(buffer));
@@ -85,21 +91,21 @@ DriveItem::~DriveItem()
bool bool
DriveItem::IsInstalled() const DriveItem::IsInstalled() const
{ {
return true; return fIsInstalled;
} }
bool bool
DriveItem::CanBeInstalled() const DriveItem::CanBeInstalled() const
{ {
return true; return fCanBeInstalled == B_OK;
} }
bool bool
DriveItem::IsBootDrive() const DriveItem::IsBootDrive() const
{ {
return true; return fDrive->IsBootDrive();
} }
@@ -142,6 +148,14 @@ DriveItem::DrawItem(BView* owner, BRect frame, bool complete)
owner->MovePenTo(frame.left + 4, frame.top + fBaselineOffset); owner->MovePenTo(frame.left + 4, frame.top + fBaselineOffset);
owner->DrawString(fName.String()); owner->DrawString(fName.String());
if (fCanBeInstalled != B_OK) {
owner->SetHighColor(140, 0, 0);
owner->MovePenBy(fBaselineOffset, 0);
owner->DrawString(fCanBeInstalled == B_PARTITION_TOO_SMALL
? B_TRANSLATE_COMMENT("No space available!", "Cannot install")
: B_TRANSLATE_COMMENT("Cannot access!", "Cannot install"));
}
owner->PopState(); owner->PopState();
} }
@@ -177,8 +191,8 @@ DriveItem::Update(BView* owner, const BFont* font)
// #pragma mark - // #pragma mark -
DrivesPage::DrivesPage(WizardView* wizardView, BMessage* settings, DrivesPage::DrivesPage(WizardView* wizardView, const BootMenuList& menus,
const char* name) BMessage* settings, const char* name)
: :
WizardPageView(settings, name), WizardPageView(settings, name),
fWizardView(wizardView) fWizardView(wizardView)
@@ -193,7 +207,7 @@ DrivesPage::DrivesPage(WizardView* wizardView, BMessage* settings,
fDrivesView = new BListView("drives"); fDrivesView = new BListView("drives");
fDrivesView->SetSelectionMessage(new BMessage(kMsgSelectionChanged)); fDrivesView->SetSelectionMessage(new BMessage(kMsgSelectionChanged));
bool any = _FillDrivesView(); bool any = _FillDrivesView(menus);
BScrollView* scrollView = new BScrollView("scrollView", fDrivesView, 0, BScrollView* scrollView = new BScrollView("scrollView", fDrivesView, 0,
false, true); false, true);
@@ -208,6 +222,8 @@ DrivesPage::DrivesPage(WizardView* wizardView, BMessage* settings,
fWizardView->SetPreviousButtonLabel( fWizardView->SetPreviousButtonLabel(
B_TRANSLATE_COMMENT("Uninstall", "Button")); B_TRANSLATE_COMMENT("Uninstall", "Button"));
fWizardView->SetPreviousButtonHidden(false); fWizardView->SetPreviousButtonHidden(false);
fWizardView->SetPreviousButtonEnabled(false);
fWizardView->SetPreviousButtonEnabled(false);
} else { } else {
fWizardView->SetPreviousButtonHidden(true); fWizardView->SetPreviousButtonHidden(true);
fWizardView->SetNextButtonLabel( fWizardView->SetNextButtonLabel(
@@ -228,8 +244,6 @@ DrivesPage::PageCompleted()
if (fSettings->ReplaceString("disk", item->Path()) != B_OK) if (fSettings->ReplaceString("disk", item->Path()) != B_OK)
fSettings->AddString("disk", item->Path()); fSettings->AddString("disk", item->Path());
fSettings->ReplaceBool("install", true);
} }
@@ -262,7 +276,7 @@ DrivesPage::MessageReceived(BMessage* message)
selects the boot drive. selects the boot drive.
*/ */
bool bool
DrivesPage::_FillDrivesView() DrivesPage::_FillDrivesView(const BootMenuList& menus)
{ {
bool any = false; bool any = false;
@@ -270,7 +284,7 @@ DrivesPage::_FillDrivesView()
BDiskDevice device; BDiskDevice device;
while (roster.GetNextDevice(&device) == B_OK) { while (roster.GetNextDevice(&device) == B_OK) {
if (device.HasMedia() && !device.IsReadOnly()) { if (device.HasMedia() && !device.IsReadOnly()) {
DriveItem* item = new DriveItem(device); DriveItem* item = new DriveItem(device, menus);
if (item->CanBeInstalled()) if (item->CanBeInstalled())
any = true; any = true;
fDrivesView->AddItem(item); fDrivesView->AddItem(item);
+3 -1
View File
@@ -6,6 +6,7 @@
#define DRIVES_PAGE_H #define DRIVES_PAGE_H
#include "BootMenu.h"
#include "WizardPageView.h" #include "WizardPageView.h"
@@ -19,6 +20,7 @@ class WizardView;
class DrivesPage : public WizardPageView { class DrivesPage : public WizardPageView {
public: public:
DrivesPage(WizardView* wizardView, DrivesPage(WizardView* wizardView,
const BootMenuList& menus,
BMessage* settings, const char* name); BMessage* settings, const char* name);
virtual ~DrivesPage(); virtual ~DrivesPage();
@@ -29,7 +31,7 @@ protected:
void MessageReceived(BMessage* message); void MessageReceived(BMessage* message);
private: private:
bool _FillDrivesView(); bool _FillDrivesView(const BootMenuList& menus);
DriveItem* _SelectedDriveItem(); DriveItem* _SelectedDriveItem();
void _UpdateWizardButtons(DriveItem* item); void _UpdateWizardButtons(DriveItem* item);
+23 -14
View File
@@ -3,6 +3,7 @@ SubDir HAIKU_TOP src apps bootmanager ;
UsePrivateHeaders shared storage tracker ; UsePrivateHeaders shared storage tracker ;
local cataloguedSources = local cataloguedSources =
BootDrive.cpp
BootManager.cpp BootManager.cpp
BootManagerController.cpp BootManagerController.cpp
BootManagerWindow.cpp BootManagerWindow.cpp
@@ -18,21 +19,29 @@ local cataloguedSources =
Application BootManager : Application BootManager :
$(cataloguedSources) $(cataloguedSources)
DescriptionPage.cpp DescriptionPage.cpp
# TestBootDrive.cpp
WizardController.cpp WizardController.cpp
WizardPageView.cpp WizardPageView.cpp
:
be : be textencoding tracker $(HAIKU_LOCALE_LIBS) $(TARGET_LIBSUPC++)
textencoding : BootManager.rdef
tracker
$(HAIKU_LOCALE_LIBS)
$(TARGET_LIBSUPC++)
:
BootManager.rdef
; ;
DoCatalogs BootManager : DoCatalogs BootManager : x-vnd.Haiku-BootManager : $(cataloguedSources) ;
x-vnd.Haiku-BootManager
: # Assemble the boot loader, and convert it into a header file
$(cataloguedSources)
; rule AssembleYasmBin object : source
{
SEARCH on $(source) = $(SUBDIR) ;
Depends $(object) : $(source) ;
}
actions AssembleYasmBin
{
$(HAIKU_YASM) -f bin -o $(1) $(2)
}
AssembleYasmBin [ FGristFiles bootman.bin ] : bootman.S ;
DataFileToSourceFile [ FGristFiles BootLoader.h ] : [ FGristFiles bootman.bin ]
: kBootLoader : kBootLoaderSize ;
+131 -87
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Axel Dörfler, [email protected]
* Michael Pfeiffer <[email protected]> * Michael Pfeiffer <[email protected]>
*/ */
@@ -10,6 +11,8 @@
#include "LegacyBootMenu.h" #include "LegacyBootMenu.h"
#include <new> #include <new>
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <Catalog.h> #include <Catalog.h>
@@ -17,19 +20,19 @@
#include <DiskDevice.h> #include <DiskDevice.h>
#include <DiskDeviceRoster.h> #include <DiskDeviceRoster.h>
#include <DiskDeviceVisitor.h> #include <DiskDeviceVisitor.h>
#include <Drivers.h>
#include <File.h> #include <File.h>
#include <Partition.h> #include <Partition.h>
#include <Path.h> #include <Path.h>
#include <String.h> #include <String.h>
#include <UTF8.h> #include <UTF8.h>
#include "BootDrive.h"
#include "BootLoader.h" #include "BootLoader.h"
#undef B_TRANSLATE_CONTEXT #undef B_TRANSLATE_CONTEXT
#define B_TRANSLATE_CONTEXT "LegacyBootMenu" #define B_TRANSLATE_CONTEXT "LegacyBootMenu"
#define USE_SECOND_DISK 0
#define GET_FIRST_BIOS_DRIVE 1
struct MasterBootRecord { struct MasterBootRecord {
@@ -53,10 +56,9 @@ public:
}; };
class PartitionRecorder : public BDiskDeviceVisitor { class PartitionVisitor : public BDiskDeviceVisitor {
public: public:
PartitionRecorder(BMessage* settings, PartitionVisitor();
int8 drive);
virtual bool Visit(BDiskDevice* device); virtual bool Visit(BDiskDevice* device);
virtual bool Visit(BPartition* partition, int32 level); virtual bool Visit(BPartition* partition, int32 level);
@@ -65,13 +67,25 @@ public:
off_t FirstOffset() const; off_t FirstOffset() const;
private: private:
bool _Record(BPartition* partition); off_t fFirstOffset;
};
class PartitionRecorder : public BDiskDeviceVisitor {
public:
PartitionRecorder(BMessage& settings,
int8 biosDrive);
virtual bool Visit(BDiskDevice* device);
virtual bool Visit(BPartition* partition, int32 level);
bool FoundPartitions() const;
private: private:
BMessage* fSettings; BMessage& fSettings;
int8 fDrive; int32 fUnnamedIndex;
int32 fIndex; int8 fBIOSDrive;
off_t fFirstOffset; bool fFound;
}; };
@@ -149,12 +163,53 @@ LittleEndianMallocIO::Fill(int16 size, int8 fillByte)
// #pragma mark - // #pragma mark -
PartitionRecorder::PartitionRecorder(BMessage* settings, int8 drive) PartitionVisitor::PartitionVisitor()
:
fFirstOffset(LONGLONG_MAX)
{
}
bool
PartitionVisitor::Visit(BDiskDevice* device)
{
return false;
}
bool
PartitionVisitor::Visit(BPartition* partition, int32 level)
{
if (partition->Offset() < fFirstOffset)
fFirstOffset = partition->Offset();
return false;
}
bool
PartitionVisitor::HasPartitions() const
{
return fFirstOffset != LONGLONG_MAX;
}
off_t
PartitionVisitor::FirstOffset() const
{
return fFirstOffset;
}
// #pragma mark -
PartitionRecorder::PartitionRecorder(BMessage& settings, int8 biosDrive)
: :
fSettings(settings), fSettings(settings),
fDrive(drive), fUnnamedIndex(0),
fIndex(0), fBIOSDrive(biosDrive),
fFirstOffset(LONGLONG_MAX) fFound(false)
{ {
} }
@@ -168,27 +223,6 @@ PartitionRecorder::Visit(BDiskDevice* device)
bool bool
PartitionRecorder::Visit(BPartition* partition, int32 level) PartitionRecorder::Visit(BPartition* partition, int32 level)
{
return _Record(partition);
}
bool
PartitionRecorder::HasPartitions() const
{
return fFirstOffset != LONGLONG_MAX;
}
off_t
PartitionRecorder::FirstOffset() const
{
return fFirstOffset;
}
bool
PartitionRecorder::_Record(BPartition* partition)
{ {
if (partition->ContainsPartitioningSystem()) if (partition->ContainsPartitioningSystem())
return false; return false;
@@ -199,9 +233,8 @@ PartitionRecorder::_Record(BPartition* partition)
BString buffer; BString buffer;
const char* name = partition->ContentName(); const char* name = partition->ContentName();
if (name == NULL) { if (name == NULL) {
fIndex ++;
BString number; BString number;
number << fIndex; number << ++fUnnamedIndex;
buffer << B_TRANSLATE_COMMENT("Unnamed %d", buffer << B_TRANSLATE_COMMENT("Unnamed %d",
"Default name of a partition whose name could not be read from " "Default name of a partition whose name could not be read from "
"disk; characters in codepage 437 are allowed only"); "disk; characters in codepage 437 are allowed only");
@@ -220,21 +253,25 @@ PartitionRecorder::_Record(BPartition* partition)
message.AddString("name", name); message.AddString("name", name);
message.AddString("type", type); message.AddString("type", type);
message.AddString("path", partitionPath.Path()); message.AddString("path", partitionPath.Path());
message.AddInt8("drive", fDrive); if (fBIOSDrive != 0)
message.AddInt8("drive", fBIOSDrive);
message.AddInt64("size", partition->Size()); message.AddInt64("size", partition->Size());
// Specific data message.AddInt64("offset", partition->Offset());
off_t offset = partition->Offset();
message.AddInt64("offset", offset);
fSettings->AddMessage("partition", &message); fSettings.AddMessage("partition", &message);
fFound = true;
if (offset < fFirstOffset)
fFirstOffset = offset;
return false; return false;
} }
bool
PartitionRecorder::FoundPartitions() const
{
return fFound;
}
// #pragma mark - // #pragma mark -
@@ -249,67 +286,78 @@ LegacyBootMenu::~LegacyBootMenu()
bool bool
LegacyBootMenu::IsBootMenuInstalled(BMessage* settings) LegacyBootMenu::IsInstalled(const BootDrive& drive)
{ {
// TODO detect bootman // TODO: detect bootman
return false; return false;
} }
status_t status_t
LegacyBootMenu::ReadPartitions(BMessage *settings) LegacyBootMenu::CanBeInstalled(const BootDrive& drive)
{
BDiskDevice device;
status_t status = drive.GetDiskDevice(device);
if (status != B_OK)
return status;
PartitionVisitor visitor;
device.VisitEachDescendant(&visitor);
// Enough space to write boot menu to drive?
if (!visitor.HasPartitions() || visitor.FirstOffset() < sizeof(kBootLoader))
return B_PARTITION_TOO_SMALL;
return B_OK;
}
status_t
LegacyBootMenu::CollectPartitions(const BootDrive& drive, BMessage& settings)
{ {
status_t status = B_ERROR; status_t status = B_ERROR;
// Remove previous partitions, if any
settings.RemoveName("partition");
BDiskDeviceRoster diskDeviceRoster; BDiskDeviceRoster diskDeviceRoster;
BDiskDevice device; BDiskDevice device;
bool diskFound = false; bool partitionsFound = false;
while (diskDeviceRoster.GetNextDevice(&device) == B_OK) { while (diskDeviceRoster.GetNextDevice(&device) == B_OK) {
BPath path; BPath path;
status_t status = device.GetPath(&path); status_t status = device.GetPath(&path);
if (status != B_OK) if (status != B_OK)
continue; continue;
// skip not from BIOS bootable drives // Skip not from BIOS bootable drives that are not the target disk
int8 drive; int8 biosDrive = 0;
if (!_GetBiosDrive(path.Path(), &drive)) if (path != drive.Path()
&& _GetBIOSDrive(path.Path(), biosDrive) != B_OK)
continue; continue;
PartitionRecorder recorder(settings, drive); PartitionRecorder recorder(settings, biosDrive);
device.VisitEachDescendant(&recorder); device.VisitEachDescendant(&recorder);
if (!diskFound) { partitionsFound |= recorder.FoundPartitions();
settings->AddString("disk", path.Path());
diskFound = true;
// Enough space to write boot menu to drive?
// (ignored in test build)
off_t size = sizeof(kBootLoader);
if (!recorder.HasPartitions() || recorder.FirstOffset() < size)
status = B_PARTITION_TOO_SMALL;
}
} }
return diskFound ? B_OK : status; return partitionsFound ? B_OK : status;
} }
status_t status_t
LegacyBootMenu::WriteBootMenu(BMessage *settings) LegacyBootMenu::Install(const BootDrive& drive, BMessage& settings)
{ {
BString path;
if (settings->FindString("disk", &path) != B_OK)
return B_BAD_VALUE;
int32 defaultPartitionIndex; int32 defaultPartitionIndex;
if (settings->FindInt32("defaultPartition", &defaultPartitionIndex) != B_OK) if (settings.FindInt32("defaultPartition", &defaultPartitionIndex) != B_OK)
return B_BAD_VALUE; return B_BAD_VALUE;
int32 timeout; int32 timeout;
if (settings->FindInt32("timeout", &timeout) != B_OK) if (settings.FindInt32("timeout", &timeout) != B_OK)
return B_BAD_VALUE; return B_BAD_VALUE;
int fd = open(path.String(), O_RDWR); int fd = open(drive.Path(), O_RDWR);
if (fd < 0) if (fd < 0)
return B_IO_ERROR; return B_IO_ERROR;
@@ -338,7 +386,7 @@ LegacyBootMenu::WriteBootMenu(BMessage *settings)
int defaultMenuEntry = 0; int defaultMenuEntry = 0;
BMessage partition; BMessage partition;
int32 index; int32 index;
for (index = 0; settings->FindMessage("partition", index, for (index = 0; settings.FindMessage("partition", index,
&partition) == B_OK; index ++) { &partition) == B_OK; index ++) {
bool show; bool show;
partition.FindBool("show", &show); partition.FindBool("show", &show);
@@ -353,7 +401,7 @@ LegacyBootMenu::WriteBootMenu(BMessage *settings)
newBootLoader.WriteInt16(defaultMenuEntry); newBootLoader.WriteInt16(defaultMenuEntry);
newBootLoader.WriteInt16(timeout); newBootLoader.WriteInt16(timeout);
for (index = 0; settings->FindMessage("partition", index, for (index = 0; settings.FindMessage("partition", index,
&partition) == B_OK; index ++) { &partition) == B_OK; index ++) {
bool show; bool show;
BString name; BString name;
@@ -537,20 +585,16 @@ LegacyBootMenu::_ConvertToBIOSText(const char* text, BString& biosText)
} }
bool status_t
LegacyBootMenu::_GetBiosDrive(const char* device, int8* drive) LegacyBootMenu::_GetBIOSDrive(const char* device, int8& drive)
{ {
#if !GET_FIRST_BIOS_DRIVE int fd = open(device, O_RDONLY);
int fd = open(device, O_RDONLY); if (fd < 0)
if (fd < 0) return errno;
return false;
bool isBootableDrive = ioctl(fd, B_GET_BIOS_DRIVE_ID, drive, 1) == B_OK; status_t status = ioctl(fd, B_GET_BIOS_DRIVE_ID, drive, 1);
close(fd); close(fd);
return isBootableDrive; return status;
#else
*drive = 0x80;
return true;
#endif
} }
+11 -4
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Axel Dörfler, [email protected]
* Michael Pfeiffer <[email protected]> * Michael Pfeiffer <[email protected]>
*/ */
#ifndef LEGACY_BOOT_MENU_H #ifndef LEGACY_BOOT_MENU_H
@@ -22,9 +23,14 @@ public:
LegacyBootMenu(); LegacyBootMenu();
virtual ~LegacyBootMenu(); virtual ~LegacyBootMenu();
virtual bool IsBootMenuInstalled(BMessage* settings); virtual bool IsInstalled(const BootDrive& drive);
virtual status_t ReadPartitions(BMessage* settings); virtual status_t CanBeInstalled(const BootDrive& drive);
virtual status_t WriteBootMenu(BMessage* settings);
virtual status_t CollectPartitions(const BootDrive& drive,
BMessage& settings);
virtual status_t Install(const BootDrive& drive,
BMessage& settings);
virtual status_t SaveMasterBootRecord(BMessage* settings, virtual status_t SaveMasterBootRecord(BMessage* settings,
BFile* file); BFile* file);
virtual status_t RestoreMasterBootRecord(BMessage* settings, virtual status_t RestoreMasterBootRecord(BMessage* settings,
@@ -35,7 +41,8 @@ public:
private: private:
bool _ConvertToBIOSText(const char* text, bool _ConvertToBIOSText(const char* text,
BString& biosText); BString& biosText);
bool _GetBiosDrive(const char* device, int8* drive); status_t _GetBIOSDrive(const char* device,
int8& drive);
status_t _ReadBlocks(int fd, uint8* buffer, size_t size); status_t _ReadBlocks(int fd, uint8* buffer, size_t size);
status_t _WriteBlocks(int fd, const uint8* buffer, status_t _WriteBlocks(int fd, const uint8* buffer,
size_t size); size_t size);
-51
View File
@@ -1,51 +0,0 @@
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int
main(int argc, char* argv[])
{
const char* application = argv[0];
if (argc != 3) {
fprintf(stderr, "Usage:\n%s <variable name> <file>", application);
return 1;
}
const char* variableName = argv[1];
const char* fileName = argv[2];
int fd = open(fileName, 0);
if (fd < 0) {
fprintf(stderr, "%s: Error opening file '%s'!\n", application,
fileName);
return 1;
}
const int kSize = 1024;
unsigned char buffer[kSize];
int size = read(fd, buffer, kSize);
const int COLUMNS = 16;
int column = COLUMNS - 1;
bool first = true;
printf("// THIS FILE WAS GENERATED WITH\n");
printf("// %s %s %s\n\n", application, variableName, fileName);
printf("static const uint8 %s[] = {", variableName);
while (size > 0) {
for (int i = 0; i < size; i ++) {
if (first)
first = false;
else
printf(", ");
column ++;
if (column == COLUMNS) {
printf("\n\t");
column = 0;
}
printf("0x%2.2x", (int)buffer[i]);
}
size = read(fd, buffer, kSize);
}
printf("\n};\n");
close(fd);
}
+4
View File
@@ -64,8 +64,12 @@ WizardView::PageCompleted()
if (fPage != NULL) if (fPage != NULL)
fPage->PageCompleted(); fPage->PageCompleted();
// Restore initial state
SetNextButtonLabel(B_TRANSLATE_COMMENT("Next", "Button")); SetNextButtonLabel(B_TRANSLATE_COMMENT("Next", "Button"));
SetPreviousButtonLabel(B_TRANSLATE_COMMENT("Previous", "Button")); SetPreviousButtonLabel(B_TRANSLATE_COMMENT("Previous", "Button"));
SetNextButtonEnabled(true);
SetPreviousButtonEnabled(true);
SetPreviousButtonHidden(false);
} }
+80 -74
View File
@@ -2,14 +2,9 @@
; Copyright 2007, Dengg David, [email protected]. All rights reserved. ; Copyright 2007, Dengg David, [email protected]. All rights reserved.
; Copyright 2008, Michael Pfeiffer, [email protected]. All rights reserved. ; Copyright 2008, Michael Pfeiffer, [email protected]. All rights reserved.
; Copyright 2005, Ingo Weinhold, [email protected]. ; Copyright 2005, Ingo Weinhold, [email protected].
; Copyright 2011, Axel Dörfler, [email protected].
; Distributed under the terms of the MIT License. ; Distributed under the terms of the MIT License.
; Steps to create BootLoader.h
; 1. nasm -f bin bootman.S -o bootman.bin
; 2. cc MakeArray.cpp -o make_array -lstdc++
; 3. ./make_array kBootLoader bootman.bin > BootLoader.h
; or
; nasm -f bin bootman.S -o bootman.bin && ./make_array kBootLoader bootman.bin > BootLoader.h
%assign USE_TEST_MENU 0 %assign USE_TEST_MENU 0
@@ -155,7 +150,7 @@
%define TITLE 'Haiku Boot Manager' %define TITLE 'Haiku Boot Manager'
%strlen TITLE_LENGTH TITLE %strlen TITLE_LENGTH TITLE
%define SELECT_OS_MESSAGE 'Select an OS from the menu' %define SELECT_OS_MESSAGE 'Select an OS from the menu'
%strlen SELECT_OS_MESSAGE_LENGTH SELECT_OS_MESSAGE %strlen SELECT_OS_MESSAGE_LENGTH SELECT_OS_MESSAGE
; 16 bit code ; 16 bit code
SECTION SECTION
@@ -212,13 +207,13 @@ cursorPosition equ cursorX
mov dx, [bp + cursorPosition] mov dx, [bp + cursorPosition]
mov ah, SET_CURSOR mov ah, SET_CURSOR
int BIOS_VIDEO_SERVICES int BIOS_VIDEO_SERVICES
inc byte [bp + cursorX] inc byte [bp + cursorX]
mov cx, 1 mov cx, 1
mov ah, WRITE_CHAR mov ah, WRITE_CHAR
int BIOS_VIDEO_SERVICES int BIOS_VIDEO_SERVICES
.loop_condition .loop_condition
lodsb lodsb
cmp al, 0 cmp al, 0
jnz .loop jnz .loop
@@ -254,22 +249,23 @@ endstruc
%define printstr printStringStage1 %define printstr printStringStage1
stage1: stage1:
mov ax, 0x07C0 ; BOOT_BLOCK_START_ADDRESS / 16 mov ax, 0x07c0 ; BOOT_BLOCK_START_ADDRESS / 16
mov ds, ax ; Setup segment registers mov ds, ax ; Setup segment registers
mov es, ax mov es, ax
mov ss, ax mov ss, ax
mov sp, 0xFFFF - sizeof(Locals) ; Make stack empty mov sp, 0xFFFF - sizeof(Locals) ; Make stack empty
mov bp, sp mov bp, sp
cld ; String operations increment index registers mov [bootDrive], dl ; Store boot drive
cld ; String operations increment index
; registers
CLEAR_SCREEN CLEAR_SCREEN
call hideCursor call hideCursor
mov bh, 0 ; Text output on page 0 mov bh, 0 ; Text output on page 0
; Print title centered at row 2 ; Print title centered at row 2
mov dx, 1 * 0x100 + (40 - TITLE_LENGTH / 2) mov dx, 1 * 0x100 + (40 - TITLE_LENGTH / 2)
mov [bp + cursorPosition], dx mov [bp + cursorPosition], dx
@@ -281,28 +277,28 @@ stage1:
mov dx, (TEXT_ROWS-2) * 0x100 + (40 - SELECT_OS_MESSAGE_LENGTH / 2) mov dx, (TEXT_ROWS-2) * 0x100 + (40 - SELECT_OS_MESSAGE_LENGTH / 2)
mov [bp + cursorPosition], dx mov [bp + cursorPosition], dx
mov bl, LIGHT_GRAY mov bl, LIGHT_GRAY
mov si, kSelectOSMessage mov si, kSelectOSMessage
call printstr call printstr
; Chain load rest of boot loader ; Chain load rest of boot loader
mov ah, EXTENDED_READ ; Load 3 more sectors mov ah, EXTENDED_READ ; Load 3 more sectors
mov dl, 0x80 ; First HDD mov dl, [bootDrive]
mov si, nextStageDAP mov si, nextStageDAP
int BIOS_DISK_SERVICES int BIOS_DISK_SERVICES
jc .error ; I/O error jc .error ; I/O error
jmp stage2 ; Continue in loaded stage 2 jmp stage2 ; Continue in loaded stage 2
.error: .error:
call showCursor call showCursor
mov si, kError mov si, kError
mov bl, RED mov bl, RED
call printstr call printstr
mov ah, READ_CHAR mov ah, READ_CHAR
int BIOS_KEYBOARD_SERVICES int BIOS_KEYBOARD_SERVICES
mov dl, 0x80 mov dl, [bootDrive]
int BIOS_REBOOT int BIOS_REBOOT
printStringStage1: printStringStage1:
@@ -312,10 +308,10 @@ hideCursor:
mov ah, GET_CURSOR mov ah, GET_CURSOR
int BIOS_VIDEO_SERVICES int BIOS_VIDEO_SERVICES
mov [bp + cursorShape], cx mov [bp + cursorShape], cx
mov ah, SET_CURSOR_SHAPE mov ah, SET_CURSOR_SHAPE
mov cx, 0x2000 mov cx, 0x2000
int BIOS_VIDEO_SERVICES int BIOS_VIDEO_SERVICES
ret ret
showCursor: showCursor:
@@ -324,7 +320,7 @@ showCursor:
int BIOS_VIDEO_SERVICES int BIOS_VIDEO_SERVICES
ret ret
nextStageDAP: nextStageDAP:
istruc AddressPacket istruc AddressPacket
at AddressPacket.packet_size, db 0x10 at AddressPacket.packet_size, db 0x10
at AddressPacket.block_count, db 0x03 at AddressPacket.block_count, db 0x03
@@ -332,6 +328,9 @@ nextStageDAP:
at AddressPacket.offset, dw 1 at AddressPacket.offset, dw 1
iend iend
bootDrive:
db 0
kTitle: kTitle:
db TITLE, 0x00 db TITLE, 0x00
kSelectOSMessage: kSelectOSMessage:
@@ -367,21 +366,21 @@ kMBRSignature:
stage2: stage2:
mov ax, [defaultItem] ; Select default item mov ax, [defaultItem] ; Select default item
mov [bp + selection], ax mov [bp + selection], ax
mov ax, TICKS_PER_SECOND ; Calculate timeout ticks mov ax, TICKS_PER_SECOND ; Calculate timeout ticks
mul word [timeout] mul word [timeout]
mov bx, dx mov bx, dx
push ax push ax
mov ah, READ_CLOCK mov ah, READ_CLOCK
int BIOS_TIME_SERVICES int BIOS_TIME_SERVICES
pop ax ; Add current ticks pop ax ; Add current ticks
add ax, dx add ax, dx
adc bx, cx adc bx, cx
mov [bp + timeoutTicks], ax mov [bp + timeoutTicks], ax
mov [bp + timeoutTicks + 2], bx mov [bp + timeoutTicks + 2], bx
mov al, [listItemCount] ; Calculate start row for menu mov al, [listItemCount] ; Calculate start row for menu
shr al, 1 shr al, 1
mov bl, TEXT_ROWS / 2 mov bl, TEXT_ROWS / 2
@@ -422,21 +421,21 @@ isTimeoutReached:
.returnTrue: .returnTrue:
stc stc
ret ret
; ================== Wait for a key and do something with it ================== ; ================== Wait for a key and do something with it ==================
mainLoop: mainLoop:
call printMenu call printMenu
inputLoop: inputLoop:
mov ah, READ_CHAR mov ah, READ_CHAR
int BIOS_KEYBOARD_SERVICES ; AL = ASCII Code, AH = Scancode int BIOS_KEYBOARD_SERVICES ; AL = ASCII Code, AH = Scancode
cmp ah, KEY_DOWN cmp ah, KEY_DOWN
je selectNextPartition je selectNextPartition
cmp ah, KEY_UP cmp ah, KEY_UP
je selectPreviousPartition je selectPreviousPartition
cmp ah, KEY_RETURN cmp ah, KEY_RETURN
jne inputLoop jne inputLoop
jmp bootSelectedPartition jmp bootSelectedPartition
@@ -450,26 +449,26 @@ selectNextPartition:
.done: .done:
mov [bp + selection], ax mov [bp + selection], ax
jmp mainLoop jmp mainLoop
selectPreviousPartition: selectPreviousPartition:
mov ax, [bp + selection] mov ax, [bp + selection]
or ax, ax or ax, ax
jnz .done ; At top of list? jnz .done ; At top of list?
mov ax, [listItemCount] ; Then jump to last entry mov ax, [listItemCount] ; Then jump to last entry
.done: .done:
dec ax dec ax
mov [bp + selection], ax mov [bp + selection], ax
jmp mainLoop jmp mainLoop
; ======================= Print the OS list ============================ ; ======================= Print the OS list ============================
printMenu: printMenu:
mov al, [bp + firstLine] mov al, [bp + firstLine]
mov [bp + cursorY], al mov [bp + cursorY], al
mov si, list ; Start at top of list mov si, list ; Start at top of list
xor cx, cx ; The index of the current item xor cx, cx ; The index of the current item
.loop: .loop:
lodsb ; String length incl. 0-terminator lodsb ; String length incl. 0-terminator
add al, 3 ; center menu item add al, 3 ; center menu item
@@ -493,17 +492,17 @@ printMenu:
.print: .print:
call printstr call printstr
add si, sizeof(BootLoaderAddress) add si, sizeof(BootLoaderAddress)
add byte [bp + cursorX], 1 add byte [bp + cursorX], 1
mov al, TRIANGLE_TO_LEFT mov al, TRIANGLE_TO_LEFT
call updateMarker call updateMarker
inc byte [bp + cursorY] inc byte [bp + cursorY]
inc cx inc cx
cmp cx, [listItemCount] cmp cx, [listItemCount]
jne .loop jne .loop
ret ret
updateMarker: updateMarker:
cmp cx, [bp + selection] cmp cx, [bp + selection]
@@ -520,10 +519,10 @@ bootSelectedPartition:
call showCursor call showCursor
call getSelectedBootLoaderAddress call getSelectedBootLoaderAddress
lodsb ; Set boot drive lodsb ; Set boot drive
mov dl, al mov dl, al
mov di, bootSectorDAP+AddressPacket.offset ; Copy start sector mov di, bootSectorDAP+AddressPacket.offset ; Copy start sector
mov cx, 4 ; It is stored in a quad word mov cx, 4 ; It is stored in a quad word
.copy_start_sector .copy_start_sector
@@ -541,39 +540,39 @@ bootSelectedPartition:
cmp ax, MBR_SIGNATURE cmp ax, MBR_SIGNATURE
mov si, kNoBootablePartitionError mov si, kNoBootablePartitionError
jne printAndHalt ; Missing signature jne printAndHalt ; Missing signature
CLEAR_SCREEN CLEAR_SCREEN
; Print "Loading <name>" at top of screen ; Print "Loading <name>" at top of screen
mov word [bp + cursorPosition], 0 mov word [bp + cursorPosition], 0
mov si, kLoadingMessage mov si, kLoadingMessage
mov bl, LIGHT_GRAY mov bl, LIGHT_GRAY
call printstr call printstr
inc byte [bp + cursorX] inc byte [bp + cursorX]
call getSelectedMenuItem call getSelectedMenuItem
inc si ; Skip string length byte inc si ; Skip string length byte
call printstr call printstr
mov dx, 0x100 mov dx, 0x100
xor bh, bh xor bh, bh
mov ah, SET_CURSOR mov ah, SET_CURSOR
int BIOS_VIDEO_SERVICES int BIOS_VIDEO_SERVICES
call getSelectedBootLoaderAddress call getSelectedBootLoaderAddress
mov dl, [si] ; drive number in dl mov dl, [si] ; drive number in dl
jmp $$ ; Start loaded boot loader jmp $$ ; Start loaded boot loader
printAndHalt: printAndHalt:
mov dx, (TEXT_ROWS-4) * 0x100 + (TEXT_COLUMNS / 3) mov dx, (TEXT_ROWS-4) * 0x100 + (TEXT_COLUMNS / 3)
mov [bp + cursorPosition], dx mov [bp + cursorPosition], dx
mov bx, 0x0F ; Page number and foreground color mov bx, 0x0F ; Page number and foreground color
call printstr call printstr
mov ah, READ_CHAR mov ah, READ_CHAR
int BIOS_KEYBOARD_SERVICES int BIOS_KEYBOARD_SERVICES
mov dl, 0x80 mov dl, 0x80
int BIOS_REBOOT int BIOS_REBOOT
@@ -582,15 +581,15 @@ printAndHalt:
; Trashes: ; Trashes:
; ax, cx ; ax, cx
getSelectedMenuItem: getSelectedMenuItem:
mov si, list ; Search address of start sector mov si, list ; Search address of start sector
; of the selected item. ; of the selected item.
mov cx, [bp + selection] mov cx, [bp + selection]
inc cx ; Number of required iterations inc cx ; Number of required iterations
xor ah, ah ; The high-byte of the string length xor ah, ah ; The high-byte of the string length
; see loop body ; see loop body
jmp .entry jmp .entry
.loop: .loop:
lodsb ; Length of menu item name lodsb ; Length of menu item name
add si, ax ; Skip name to BootLoaderAddess add si, ax ; Skip name to BootLoaderAddess
@@ -598,13 +597,20 @@ getSelectedMenuItem:
.entry: .entry:
loop .loop loop .loop
ret ret
getSelectedBootLoaderAddress: getSelectedBootLoaderAddress:
call getSelectedMenuItem call getSelectedMenuItem
lodsb lodsb
xor ah, ah xor ah, ah
add si, ax ; Skip name add si, ax ; Skip name
mov dl, [si]
test dl, 0 ; if drive is 0, use boot drive
jz .takeOverBootDrive
ret
.takeOverBootDrive:
mov dl, [bootDrive]
mov [si], dl
ret ret
printStringStage2: printStringStage2:
@@ -617,13 +623,13 @@ printChar:
push bx push bx
push cx push cx
push dx push dx
xor bh, bh ; Write on page 0 xor bh, bh ; Write on page 0
mov dx, [bp + cursorPosition] mov dx, [bp + cursorPosition]
mov ah, SET_CURSOR mov ah, SET_CURSOR
int BIOS_VIDEO_SERVICES int BIOS_VIDEO_SERVICES
inc byte [bp + cursorX] inc byte [bp + cursorX]
mov cx, 1 mov cx, 1
@@ -635,7 +641,7 @@ printChar:
pop bx pop bx
pop ax pop ax
ret ret
; ================================ DATA =========================== ; ================================ DATA ===========================
bootSectorDAP: bootSectorDAP:
@@ -646,7 +652,7 @@ bootSectorDAP:
iend iend
kColorTable: kColorTable:
db BLUE, RED, GREEN, CYAN db BLUE, RED, GREEN, CYAN
kReadError: kReadError:
db 'Error loading sectors', 0x00 db 'Error loading sectors', 0x00
kNoBootablePartitionError: kNoBootablePartitionError:
@@ -659,7 +665,7 @@ listItemCount:
defaultItem equ listItemCount + 2 defaultItem equ listItemCount + 2
timeout equ defaultItem + 2 timeout equ defaultItem + 2
list equ timeout + 2 list equ timeout + 2
; dw number of entries ; dw number of entries
; dw the default entry ; dw the default entry
; dw the timeout (-1 for none) ; dw the timeout (-1 for none)
@@ -671,9 +677,9 @@ list equ timeout + 2
%if USE_TEST_MENU %if USE_TEST_MENU
dw 0x06 dw 0x06
dw 2 dw 2
dw 5 dw 5
db 0x06 db 0x06
@@ -705,7 +711,7 @@ list equ timeout + 2
db 'OpenBSD', 0 db 'OpenBSD', 0
db 0x80 db 0x80
dw 0xAAAA, 0, 0, 0 dw 0xAAAA, 0, 0, 0
dw kStage1UnusedSpace dw kStage1UnusedSpace
%endif %endif