Compare commits

..

No commits in common. "master" and "v2.0.0" have entirely different histories.

10 changed files with 81 additions and 84 deletions

View File

@ -53,8 +53,3 @@ refer to the appropriate platform specific README:
#### Windows #### Windows
- Win32/README.txt ([online](Win32/README.txt)) - Win32/README.txt ([online](Win32/README.txt))
### Odin protocol and PIT format
For more details on the Odin protocol, and the PIT files, see the
external project [samsung-loki/samsung-docs](https://samsung-loki.github.io/samsung-docs/).

View File

@ -114,7 +114,7 @@
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:400; font-style:normal;"> </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Heimdall Frontend</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Heimdall Frontend</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Version 2.0.2</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Version 1.4.2</p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2010-2017 Benjamin Dobell, Glass Echidna</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2010-2017 Benjamin Dobell, Glass Echidna</p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Heimdall (command line)</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Heimdall (command line)</span></p>

View File

@ -20,7 +20,6 @@
// C Standard Library // C Standard Library
#include <cstdio> #include <cstdio>
#include <fstream>
// libusb // libusb
#include <libusb.h> #include <libusb.h>
@ -81,17 +80,16 @@ int BridgeManager::FindDeviceInterface(void)
Interface::Print("Detecting device...\n"); Interface::Print("Detecting device...\n");
struct libusb_device **devices; struct libusb_device **devices;
unsigned int deviceCount = libusb_get_device_list(libusbContext, &devices); int deviceCount = libusb_get_device_list(libusbContext, &devices);
for (unsigned int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) for (int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
{ {
libusb_device_descriptor descriptor; libusb_device_descriptor descriptor;
libusb_get_device_descriptor(devices[deviceIndex], &descriptor); libusb_get_device_descriptor(devices[deviceIndex], &descriptor);
for (int i = 0; i < BridgeManager::kSupportedDeviceCount; i++) for (int i = 0; i < BridgeManager::kSupportedDeviceCount; i++)
{ {
if (descriptor.idVendor == supportedDevices[i].vendorId && if (descriptor.idVendor == supportedDevices[i].vendorId && descriptor.idProduct == supportedDevices[i].productId)
descriptor.idProduct == supportedDevices[i].productId)
{ {
heimdallDevice = devices[deviceIndex]; heimdallDevice = devices[deviceIndex];
libusb_ref_device(heimdallDevice); libusb_ref_device(heimdallDevice);
@ -312,20 +310,14 @@ bool BridgeManager::InitialiseProtocol(void)
memcpy(dataBuffer, "ODIN", 4); memcpy(dataBuffer, "ODIN", 4);
memset(dataBuffer + 4, 0, 1); memset(dataBuffer + 4, 0, 1);
#ifdef OS_LINUX if (libusb_reset_device(deviceHandle))
if (IsUbuntu())
{ {
Interface::Print("Resetting device...\n"); Interface::PrintError("Failed to reset device!");
if (libusb_reset_device(deviceHandle))
{
Interface::PrintError("Failed to reset device!\n");
}
} }
#endif
if (!SendBulkTransfer(dataBuffer, 4, 1000)) if (!SendBulkTransfer(dataBuffer, 4, 1000))
{ {
Interface::PrintError("Failed to send handshake!\n"); Interface::PrintError("Failed to send handshake!");
} }
// Expect "LOKE" // Expect "LOKE"
@ -415,8 +407,29 @@ bool BridgeManager::DetectDevice(void)
return (false); return (false);
} }
// Set libusb log level. // Setup libusb log level.
SetUsbLogLevel(usbLogLevel); switch (usbLogLevel)
{
case UsbLogLevel::None:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_NONE);
break;
case UsbLogLevel::Error:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_ERROR);
break;
case UsbLogLevel::Warning:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_WARNING);
break;
case UsbLogLevel::Info:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
break;
case UsbLogLevel::Debug:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
break;
}
// Get handle to Galaxy S device // Get handle to Galaxy S device
struct libusb_device **devices; struct libusb_device **devices;
@ -429,8 +442,7 @@ bool BridgeManager::DetectDevice(void)
for (int i = 0; i < BridgeManager::kSupportedDeviceCount; i++) for (int i = 0; i < BridgeManager::kSupportedDeviceCount; i++)
{ {
if (descriptor.idVendor == supportedDevices[i].vendorId && if (descriptor.idVendor == supportedDevices[i].vendorId && descriptor.idProduct == supportedDevices[i].productId)
descriptor.idProduct == supportedDevices[i].productId)
{ {
libusb_free_device_list(devices, deviceCount); libusb_free_device_list(devices, deviceCount);
@ -456,13 +468,34 @@ int BridgeManager::Initialise(bool resume)
if (result != LIBUSB_SUCCESS) if (result != LIBUSB_SUCCESS)
{ {
Interface::PrintError("Failed to initialise libusb. libusb error: %d\n", result); Interface::PrintError("Failed to initialise libusb. libusb error: %d\n", result);
Interface::Print("Failed to connect to device!\n"); Interface::Print("Failed to connect to device!");
return (BridgeManager::kInitialiseFailed); return (BridgeManager::kInitialiseFailed);
} }
// Setup libusb log level. // Setup libusb log level.
SetUsbLogLevel(usbLogLevel); switch (usbLogLevel)
{
case UsbLogLevel::None:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_NONE);
break;
case UsbLogLevel::Error:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_ERROR);
break;
case UsbLogLevel::Warning:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_WARNING);
break;
case UsbLogLevel::Info:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
break;
case UsbLogLevel::Debug:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
break;
}
result = FindDeviceInterface(); result = FindDeviceInterface();
if (result != BridgeManager::kInitialiseSucceeded) if (result != BridgeManager::kInitialiseSucceeded)
@ -716,7 +749,7 @@ bool BridgeManager::ReceivePacket(InboundPacket *packet, int timeout, int emptyT
if (receivedSize < 0) if (receivedSize < 0)
return (false); return (false);
if (static_cast<unsigned int>(receivedSize) != packet->GetSize() && !packet->IsSizeVariable()) if (receivedSize != packet->GetSize() && !packet->IsSizeVariable())
{ {
if (verbose) if (verbose)
Interface::PrintError("Incorrect packet size received - expected size = %d, received size = %d.\n", packet->GetSize(), receivedSize); Interface::PrintError("Incorrect packet size received - expected size = %d, received size = %d.\n", packet->GetSize(), receivedSize);
@ -916,7 +949,7 @@ int BridgeManager::ReceivePitFile(unsigned char **pitBuffer) const
} }
int receiveEmptyTransferFlags = (i == transferCount - 1) ? kEmptyTransferAfter : kEmptyTransferNone; int receiveEmptyTransferFlags = (i == transferCount - 1) ? kEmptyTransferAfter : kEmptyTransferNone;
ReceiveFilePartPacket *receiveFilePartPacket = new ReceiveFilePartPacket(); ReceiveFilePartPacket *receiveFilePartPacket = new ReceiveFilePartPacket();
success = ReceivePacket(receiveFilePartPacket, kDefaultTimeoutReceive, receiveEmptyTransferFlags); success = ReceivePacket(receiveFilePartPacket, kDefaultTimeoutReceive, receiveEmptyTransferFlags);
@ -1244,32 +1277,3 @@ void BridgeManager::SetUsbLogLevel(UsbLogLevel usbLogLevel)
} }
} }
} }
#ifdef OS_LINUX
bool BridgeManager::IsUbuntu()
{
std::ifstream os_release("/etc/os-release");
std::string line, entry, os;
int pos;
while (std::getline(os_release, line))
{
pos = line.find("=");
entry = line.substr(0, pos);
if (entry == "ID")
{
os = line.substr(pos+1);
if (verbose)
{
Interface::Print("Linux distro ID: %s\n",
os.c_str());
}
if (os == "ubuntu")
{
return true;
}
break;
}
}
return false;
}
#endif

View File

@ -166,9 +166,7 @@ namespace Heimdall
bool SendFile(FILE *file, unsigned int destination, unsigned int deviceType, unsigned int fileIdentifier = 0xFFFFFFFF) const; bool SendFile(FILE *file, unsigned int destination, unsigned int deviceType, unsigned int fileIdentifier = 0xFFFFFFFF) const;
void SetUsbLogLevel(UsbLogLevel usbLogLevel); void SetUsbLogLevel(UsbLogLevel usbLogLevel);
#ifdef OS_LINUX
bool IsUbuntu(void);
#endif
UsbLogLevel GetUsbLogLevel(void) const UsbLogLevel GetUsbLogLevel(void) const
{ {
return usbLogLevel; return usbLogLevel;

View File

@ -148,7 +148,7 @@ int DownloadPitAction::Execute(int argc, char **argv)
if (fileSize > 0) if (fileSize > 0)
{ {
if (fwrite(pitBuffer, 1, fileSize, outputPitFile) != static_cast<size_t>(fileSize)) if (fwrite(pitBuffer, 1, fileSize, outputPitFile) != fileSize)
{ {
Interface::PrintError("Failed to write PIT data to output file.\n"); Interface::PrintError("Failed to write PIT data to output file.\n");
success = false; success = false;

View File

@ -116,16 +116,16 @@ static bool openFiles(Arguments& arguments, vector<PartitionFile>& partitionFile
{ {
const StringArgument *stringArgument = static_cast<const StringArgument *>(*it); const StringArgument *stringArgument = static_cast<const StringArgument *>(*it);
FILE *file = FileOpen(stringArgument->GetValue().c_str(), "rb"); FILE *file = FileOpen(stringArgument->GetValue().c_str(), "rb");
FileSeek(file, 0, SEEK_END);
unsigned long fileSize = (unsigned long)FileTell(file);
FileRewind(file);
if (!file) if (!file)
{ {
Interface::PrintError("Failed to open file \"%s\"\n", stringArgument->GetValue().c_str()); Interface::PrintError("Failed to open file \"%s\"\n", stringArgument->GetValue().c_str());
return (false); return (false);
} }
FileSeek(file, 0, SEEK_END);
unsigned long fileSize = (unsigned long)FileTell(file);
FileRewind(file);
partitionFiles.push_back(PartitionFile(argumentName.c_str(), file, fileSize)); partitionFiles.push_back(PartitionFile(argumentName.c_str(), file, fileSize));
} }
} }
@ -303,11 +303,11 @@ static bool flashPartitions(BridgeManager *bridgeManager, const vector<Partition
{ {
const PitEntry *part = pitData->FindEntry(it->argumentName); const PitEntry *part = pitData->FindEntry(it->argumentName);
if (part->GetDeviceType() != PitEntry::kDeviceTypeMMC && if (part->GetDeviceType() != PitEntry::kDeviceTypeMMC &&
part->GetDeviceType() != PitEntry::kDeviceTypeUFS) part->GetDeviceType() != PitEntry::kDeviceTypeMMC4096)
continue; continue;
unsigned long partitionSize = part->GetBlockCount(); unsigned long partitionSize = part->GetBlockCount();
unsigned int blockSize = 512; unsigned int blockSize = 512;
if (part->GetDeviceType() == PitEntry::kDeviceTypeUFS) if (part->GetDeviceType() == PitEntry::kDeviceTypeMMC4096)
blockSize = 4096; blockSize = 4096;
if (partitionSize > 0 && it->fileSize > partitionSize*blockSize) if (partitionSize > 0 && it->fileSize > partitionSize*blockSize)
{ {

View File

@ -42,7 +42,7 @@ using namespace Heimdall;
map<string, Interface::ActionInfo> actionMap; map<string, Interface::ActionInfo> actionMap;
bool stdoutErrors = false; bool stdoutErrors = false;
const char *version = "v2.0.2"; const char *version = "v2.0.0";
const char *actionUsage = "Usage: heimdall <action> <action arguments>\n"; const char *actionUsage = "Usage: heimdall <action> <action arguments>\n";
const char *releaseInfo = "Heimdall %s\n\n\ const char *releaseInfo = "Heimdall %s\n\n\
@ -211,7 +211,7 @@ void Interface::PrintPit(const PitData *pitData)
Interface::Print("Entry Count: %d\n", pitData->GetEntryCount()); Interface::Print("Entry Count: %d\n", pitData->GetEntryCount());
Interface::Print("Unknown string: %s\n", pitData->GetComTar2()); Interface::Print("Unknown string: %s\n", pitData->GetComTar2());
Interface::Print("CPU/bootloader tag: %s\n", pitData->GetCpuBlId()); Interface::Print("CPU/bootloader tag: %s\n", pitData->GetCpuBlId());
Interface::Print("Logic unit count: %d\n", pitData->GetLUCount()); Interface::Print("Version(?): 0x%04x\n", pitData->GetUnknown());
for (unsigned int i = 0; i < pitData->GetEntryCount(); i++) for (unsigned int i = 0; i < pitData->GetEntryCount(); i++)
{ {
@ -257,8 +257,8 @@ void Interface::PrintPit(const PitData *pitData)
Interface::Print("All (?)"); Interface::Print("All (?)");
break; break;
case PitEntry::kDeviceTypeUFS: case PitEntry::kDeviceTypeMMC4096:
Interface::Print("UFS"); Interface::Print("MMC 4096");
break; break;
default: default:

View File

@ -45,7 +45,7 @@ namespace Heimdall
memset(data, 0, size); memset(data, 0, size);
} }
virtual ~Packet() ~Packet()
{ {
delete [] data; delete [] data;
} }

View File

@ -69,7 +69,7 @@ PitData::PitData()
com_tar2[0] = '\0'; com_tar2[0] = '\0';
cpu_bl_id[0] = '\0'; cpu_bl_id[0] = '\0';
luCount = 0; unknown_version = 0;
} }
PitData::~PitData() PitData::~PitData()
@ -98,7 +98,7 @@ bool PitData::Unpack(const unsigned char *data)
return (false); return (false);
cpu_bl_id[8]='\0'; cpu_bl_id[8]='\0';
luCount = PitData::UnpackShort(data, 24); unknown_version = PitData::UnpackShort(data, 24);
unsigned int integerValue; unsigned int integerValue;
unsigned int entryOffset; unsigned int entryOffset;
@ -153,7 +153,7 @@ void PitData::Pack(unsigned char *data) const
memcpy(&data[8], com_tar2, 8); memcpy(&data[8], com_tar2, 8);
memcpy(&data[16], cpu_bl_id, 8); memcpy(&data[16], cpu_bl_id, 8);
PitData::PackShort(data, 24, luCount); PitData::PackShort(data, 24, unknown_version);
int entryOffset; int entryOffset;
@ -187,7 +187,7 @@ bool PitData::Matches(const PitData *otherPitData) const
if (entryCount == otherPitData->entryCount && if (entryCount == otherPitData->entryCount &&
(strncmp(com_tar2, otherPitData->com_tar2, 8) == 0) && (strncmp(com_tar2, otherPitData->com_tar2, 8) == 0) &&
(strncmp(cpu_bl_id, otherPitData->cpu_bl_id, 8) == 0) && (strncmp(cpu_bl_id, otherPitData->cpu_bl_id, 8) == 0) &&
luCount == otherPitData->luCount) unknown_version == otherPitData->unknown_version)
{ {
for (unsigned int i = 0; i < entryCount; i++) for (unsigned int i = 0; i < entryCount; i++)
{ {
@ -211,7 +211,7 @@ void PitData::Clear(void)
cpu_bl_id[0] = '\0'; cpu_bl_id[0] = '\0';
luCount = 0; unknown_version = 0;
for (unsigned int i = 0; i < entries.size(); i++) for (unsigned int i = 0; i < entries.size(); i++)
delete entries[i]; delete entries[i];

View File

@ -62,7 +62,7 @@ namespace libpit
kDeviceTypeFile, // FAT kDeviceTypeFile, // FAT
kDeviceTypeMMC, kDeviceTypeMMC,
kDeviceTypeAll, // ? kDeviceTypeAll, // ?
kDeviceTypeUFS = 8 kDeviceTypeMMC4096 = 8 // block size 4096
}; };
enum enum
@ -261,12 +261,12 @@ namespace libpit
private: private:
unsigned int entryCount; // 0x04 unsigned int entryCount; // 0x04
char com_tar2[8+1]; // 0x08 char com_tar2[8+1]; // 0x08
char cpu_bl_id[8+1]; // 0x10 char cpu_bl_id[8+1]; // 0x10
unsigned short luCount; // 0x18 unsigned short unknown_version; // 0x18
// Entries start at 0x1C // Entries start at 0x1C
std::vector<PitEntry *> entries; std::vector<PitEntry *> entries;
@ -375,9 +375,9 @@ namespace libpit
return cpu_bl_id; return cpu_bl_id;
} }
unsigned int GetLUCount(void) const unsigned int GetUnknown(void) const
{ {
return luCount; return unknown_version;
} }
}; };
} }