241 lines
8.4 KiB
PHP
241 lines
8.4 KiB
PHP
<?php
|
|
namespace libTononix;
|
|
|
|
require_once("vendor/autoload.php");
|
|
use Noodlehaus\Config;
|
|
use \Noodlehaus\Parser\Json;
|
|
use \Noodlehaus\Parser\Properties;
|
|
use \Noodlehaus\Parser\Xml;
|
|
|
|
class KernelManagement
|
|
{
|
|
|
|
protected $cKernelVersion;
|
|
protected $cKernelName;
|
|
protected $cKernelFeatures;
|
|
protected $cKernelBinary;
|
|
protected $cKernelHash;
|
|
|
|
private $cBootPath;
|
|
private $aInstalledKernels;
|
|
private $oConfiguration;
|
|
private $cPrefixPath;
|
|
private $aPartitionInfo;
|
|
private $aBootConfiguration;
|
|
private $abootimg;
|
|
|
|
function __construct()
|
|
{
|
|
if(!defined("IN_PREFIX"))
|
|
{
|
|
$this->cBootPath = "/boot";
|
|
} else {
|
|
if(!getenv("EPREFIX"))
|
|
{
|
|
// We're gonna assume the directory, we seem to be inside a prefix but the EPREFIX variable is missing.
|
|
$this->cBootPath = "/home/phablet/.local/system/boot";
|
|
$this->cPrefixPath = "/home/phablet/.local/system";
|
|
} else {
|
|
$this->cBootPath = getenv("EPREFIX") . "/boot";
|
|
$this->cPrefixPath = getenv("EPREFIX");
|
|
}
|
|
}
|
|
// Genkernel is nice enough to make a symlink to the last compiled kernel, so we'll use that.
|
|
$this->cKernelBinary = realpath($this->cBootPath."/kernel");
|
|
$this->cKernelHash = md5(file_get_contents($this->cKernelBinary));
|
|
|
|
$this->loadConfiguration();
|
|
|
|
if(!$this->aInstalledKernels)
|
|
{
|
|
// TODO: Replace this with an actual error code indicating the configuration file is not set up.
|
|
$this->doLibraryFirstInit();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private function saveConfiguration()
|
|
{
|
|
$this->oConfiguration->set("device.installed-kernels", json_encode($this->aInstalledKernels));
|
|
$this->oConfiguration->set("device.info.partitions", $this->aPartitionInfo);
|
|
$this->oConfiguration->set("device.boot.configuration", $this->aBootConfiguration);
|
|
$this->oConfiguration->toFile($this->cPrefixPath."/etc/tononixOS/kernel.conf", new \Noodlehaus\Writer\Xml());
|
|
}
|
|
|
|
private function installKernel($kernelVersion = "3.4.0107", $kernelPath = null)
|
|
{
|
|
if(!$kernelPath)
|
|
{
|
|
$kernelPath = realpath($this->cPrefixPath."/boot/kernel");
|
|
}
|
|
// TODO: Finish Function
|
|
}
|
|
|
|
private function loadConfiguration()
|
|
{
|
|
$this->oConfiguration = null;
|
|
$this->aInstalledKernels = null;
|
|
$this->aPartitionInfo = null;
|
|
$this->aBootConfiguration = null;
|
|
|
|
$this->oConfiguration = new Config($this->cPrefixPath."/etc/tononixOS/kernel.conf", New Xml);
|
|
$this->aInstalledKernels = json_decode($this->oConfiguration->get("device.installed-kernels"));
|
|
$this->aPartitionInfo = $this->oConfiguration->get("device.info.partitions");
|
|
$this->aBootConfiguration = $this->oConfiguration->get("device.boot.configuration");
|
|
|
|
}
|
|
|
|
public function getPartitionNode($sPartitionNode)
|
|
{
|
|
if(key_exists($sPartitionNode, $this->aPartitionInfo))
|
|
{
|
|
return $this->aPartitionInfo[$sPartitionNode];
|
|
}
|
|
}
|
|
|
|
|
|
public function retrieveCurrentInstalledBootImage($storePath = null)
|
|
{
|
|
if(!$storePath)
|
|
{
|
|
$storePath = $this->cPrefixPath."/boot/old_boot.img";
|
|
}
|
|
if(!$this->aPartitionInfo)
|
|
{
|
|
$this->detectPartitionLayout();
|
|
}
|
|
|
|
exec("dd if=".$this->aPartitionInfo['kernel']." of=".$storePath);
|
|
|
|
}
|
|
|
|
// Pulls currently installed boot image from the defined boot partition, then extracts it with abootimg.
|
|
public function extractCurrentInstalledBootImage()
|
|
{
|
|
if(!`which abootimg`)
|
|
{
|
|
return false;
|
|
}
|
|
$this->retrieveCurrentInstalledBootImage();
|
|
$pwd = getcwd();
|
|
chdir($this->cPrefixPath."/boot");
|
|
exec("abootimg -x old_boot.img");
|
|
chdir($pwd);
|
|
|
|
}
|
|
|
|
private function __getBootSlot()
|
|
{
|
|
// This will allow us to know what boot slot we're supposed to be flashing into, perhaps we can make a treble compatible system updater with this?
|
|
$bootSlot = trim(`getprop ro.boot.slot_suffix`);
|
|
if(empty($bootSlot))
|
|
{
|
|
$bootSlot = "";
|
|
}
|
|
return $bootSlot;
|
|
}
|
|
|
|
public function installKernelTree($branch = 'flo', $repository = "https://tonoxisisle.services/git/tononixOS/ubports_kernel_google_msm", $kernelName = "3.4.y-tononixOS")
|
|
{
|
|
$git = new CzProject\GitPhp\Git;
|
|
$repo = $git->cloneRepository($repository, $_ENV['HOME']."/.local/system/usr/src/".$kernelName);
|
|
if(!empty($branch))
|
|
{
|
|
$repo->checkout($branch);
|
|
}
|
|
$repo->pull();
|
|
$cwd = getcwd();
|
|
chdir($_ENV['HOME']."/.local/system/usr/src/".$kernelName);
|
|
$kVersion = shell_exec("make kernelversion");
|
|
if(empty($kVersion)) {
|
|
$versionArray = explode("-", $kernelName);
|
|
$kVersion = $versionArray[0];
|
|
}
|
|
// Until we implement the Kernel Features detection, we're going to null it out for the NYI string
|
|
$this->addInstalledKernel($kVersion, $_ENV['HOME']."/.local/system/usr/src/".$kernelName, null, $kernelName);
|
|
}
|
|
|
|
public function removeKernelTree($kernelName)
|
|
{
|
|
|
|
}
|
|
|
|
public function buildKernel($kernelName)
|
|
{
|
|
|
|
}
|
|
|
|
public function detectBootConfiguration()
|
|
{
|
|
if(!file_exists($this->cPrefixPath."/boot/old_boot.img"))
|
|
{
|
|
$this->extractCurrentInstalledBootImage();
|
|
}
|
|
|
|
$aboot = new Config($this->cPrefixPath."/boot/bootimg.cfg", new Properties);
|
|
$this->aBootConfiguration = array();
|
|
$this->aBootConfiguration['bootsize'] = $aboot->get("bootsize");
|
|
$this->aBootConfiguration['pagesize'] = $aboot->get("pagesize");
|
|
$this->aBootConfiguration['kerneladdr'] = $aboot->get("kerneladdr");
|
|
$this->aBootConfiguration['ramdiskaddr'] = $aboot->get("ramdiskaddr");
|
|
$this->aBootConfiguration['secondaddr'] = $aboot->get("secondaddr");
|
|
$this->aBootConfiguration['tagsaddr'] = $aboot->get("tagsaddr");
|
|
$this->aBootConfiguration['cmdline'] = $aboot->get("cmdline");
|
|
$bootSlot = $this->__getBootSlot();
|
|
if(!empty($bootSlot)) $this->aBootConfiguration['bootslot'] = $bootSlot;
|
|
$this->saveConfiguration();
|
|
}
|
|
|
|
function detectPartitionLayout()
|
|
{
|
|
$partitionLayout = array();
|
|
if(!is_dir("/dev/disk"))
|
|
{
|
|
return false;
|
|
}
|
|
$partitionLayout['system'] = realpath("/dev/disk/by-partlabel/system");
|
|
$partitionLayout['cache'] = realpath("/dev/disk/by-partlabel/cache");
|
|
$partitionLayout['userdata'] = realpath("/dev/disk/by-partlabel/userdata");
|
|
$partitionLayout['bootloader'] = realpath("/dev/disk/by-partlabel/aboot");
|
|
$partitionLayout['bootloaderb'] = realpath("/dev/disk/by-partlabel/abootb");
|
|
$partitionLayout['baseband'] = realpath("/dev/disk/by-partlabel/radio");
|
|
$partitionLayout['recovery'] = realpath("/dev/disk/by-partlabel/recovery");
|
|
$partitionLayout['kernel'] = realpath("/dev/disk/by-partlabel/boot");
|
|
$partitionLayout['modemst1'] = realpath("/dev/disk/by-partlabel/modemst1");
|
|
$partitionLayout['modemst2'] = realpath("/dev/disk/by-partlabel/modemst2");
|
|
|
|
$this->aPartitionInfo = $partitionLayout;
|
|
$this->saveConfiguration();
|
|
}
|
|
|
|
private function addInstalledKernel($version, $path, $aFeaturesList = "NYI", $sKernelName = null)
|
|
{
|
|
$this->aInstalledKernels[] = array("path" => "$path",
|
|
"version" => "$version",
|
|
"features" => $aFeaturesList,
|
|
"name" => "$sKernelName");
|
|
return;
|
|
}
|
|
|
|
private function delInstalledKernel($version)
|
|
{
|
|
|
|
}
|
|
|
|
function doLibraryFirstInit()
|
|
{
|
|
if(file_exists($this->cPrefixPath."/boot/kernel"))
|
|
{
|
|
// We already have an installed kernel, let's record it as our first installed kernel in the array.
|
|
$this->addInstalledKernel("0.0.0-stock", realpath($this->cPrefixPath."/boot/kernel"));
|
|
|
|
}
|
|
$this->detectPartitionLayout();
|
|
$this->detectBootConfiguration();
|
|
$this->saveConfiguration();
|
|
$this->loadConfiguration();
|
|
return true;
|
|
}
|
|
}
|