ACC SHELL
/**
* File:
* include/bootloader/routines/i386.ycp
*
* Module:
* Bootloader installation and configuration
*
* Summary:
* Functions for i386 architecture
*
* Authors:
* Jiri Srain <jsrain@suse.cz>
*
* $Id: i386.ycp 57010 2009-04-28 14:39:07Z juhliarik $
*
*/
{
textdomain "bootloader";
// general MBR reading cache
/**
* The last disk that was checked for the sequence
*/
string _old_mbr_disk = nil;
/**
* Contents of the last read MBR
*/
string _old_mbr = nil;
// info about ThinkPad
/**
* Does MBR contain special thinkpadd stuff?
*/
boolean _thinkpad_mbr = nil;
/**
* The last disk that was checked for the sequence
*/
string _old_thinkpad_disk = nil;
// Info about keeping MBR contents
/**
* Keep the MBR contents?
*/
boolean _keep_mbr = nil;
/**
* Sequence specific for IBM ThinkPad laptops, see bug 86762
*/
string thinkpad_seq = "50e46124108ae0e461241038e074f8e2f458c332edb80103ba8000cd13c3be05068a04240cc0e802c3";
/**
* Get the contents of the MBR of a disk
* @param disk string the disk to be checked
* @return strign the contents of the MBR of the disk in hexa form
*/
string GetMBRContents (string disk) {
if (_old_mbr == nil || disk != _old_mbr_disk)
{
_old_mbr_disk = disk;
map out = (map)SCR::Execute (.target.bash_output, sformat (
"dd if=%1 bs=512 count=1 | od -v -t x1 -", disk));
if (out["exit"]:0 != 0)
{
y2error ("Reading MBR contents failed");
return nil;
}
string mbr = out["stdout"]:"";
list<string> mbrl = splitstring (mbr, "\n");
mbrl = maplist (string s, mbrl, {
list<string> l = splitstring (s, " ");
l[0] = "";
return mergestring (l, "");
});
mbr = mergestring (mbrl, "");
y2debug ("MBR contents: %1", mbr);
_old_mbr = mbr;
}
return _old_mbr;
}
/**
* Does MBR of the disk contain special IBM ThinkPad stuff?
* @param disk string the disk to be checked
* @return boolean true if it is MBR
*/
global boolean ThinkPadMBR (string disk) {
if (_thinkpad_mbr == nil || disk != _old_thinkpad_disk)
{
_old_thinkpad_disk = disk;
string mbr = GetMBRContents (disk);
integer x02 = tointeger ("0x" + substring (mbr, 4, 2));
integer x03 = tointeger ("0x" + substring (mbr, 6, 2));
string x0e = substring (mbr, 28, 2);
string x0f = substring (mbr, 30, 2);
y2internal ("Data: %1 %2 %3 %4", x02, x03, x0e, x0f);
_thinkpad_mbr = (2 <= x02 && x02 <= tointeger ("0x63") && 2 <= x03 && x03 <= tointeger ("0x63") &&
tolower (x0e) == "4e" && tolower (x0f) == "50");
}
y2milestone ("MBR of %1 contains ThinkPad sequence: %2",
disk, _thinkpad_mbr);
return _thinkpad_mbr;
}
/**
* Keep the MBR contents on the specified disk? Check whether the contents
* should be kept because ot contains vendor-specific data
* @param disk string the disk to be checked
* @return boolean true to keep the contents
*/
global boolean KeepMBR (string disk) {
// FIXME: see bug #464485 there is problem with detection of
// MBR the 3rd byte is 0 after recovery thinkpad notebook with
// recovery CD, next missing cooperate with Lenovo there also
// missing any specification about Lenovo's changes in MBR
y2milestone("Skip checking of MBR for thinkpad sequence");
return false;
}
/**
* Add the partition holding firmware to bootloader?
* @param disk string the disk to be checked
* @return boolean true if firmware partition is to be added
*/
global boolean AddFirmwareToBootloader (string disk) {
return ! ThinkPadMBR (disk);
}
/**
* Display bootloader summary
* @return a list of summary lines
*/
global list<string> i386Summary () {
list<string> ret = Summary ();
string order_sum = DiskOrderSummary ();
if (order_sum != nil)
ret = add (ret, order_sum);
return ret;
}
/**
* Propose the boot loader location for i386 (and similar) platform
*/
global void i386LocationProposal () {
if (! was_proposed)
{
DetectDisks ();
del_parts = BootStorage::getPartitionList (`deleted, getLoaderType(false));
// check whether edd is loaded; if not: load it
string lsmod_command = "lsmod | grep edd";
y2milestone ("Running command %1", lsmod_command);
map lsmod_out = (map)SCR::Execute (.target.bash_output, lsmod_command);
y2milestone ("Command output: %1", lsmod_out);
boolean edd_loaded = lsmod_out["exit"]:0 == 0;
if (! edd_loaded)
{
string command = "/sbin/modprobe edd";
y2milestone ("Loading EDD module, running %1", command);
map out = (map)SCR::Execute (.target.bash_output, command);
y2milestone ("Command output: %1", out);
}
}
// refresh device map
if ((BootStorage::device_mapping == nil
|| size (BootStorage::device_mapping) == 0)
&& (getLoaderType(false) == "grub"))
{
BootStorage::ProposeDeviceMap ();
}
if (DisksChanged () && ! Mode::autoinst ()) {
if (askLocationResetPopup (loader_device)) {
selected_location = nil;
loader_device = nil;
y2milestone ("Reconfiguring locations");
DetectDisks ();
}
}
}
/**
* Do updates of MBR after the bootloader is installed
* @return boolean true on success
*/
global boolean PostUpdateMBR () {
boolean ret = true;
if (ThinkPadMBR (mbrDisk))
{
if (loader_device != mbrDisk)
{
string command = sformat
("/usr/lib/YaST2/bin/tp_mbr %1", mbrDisk);
y2milestone ("Running command %1", command);
map out = (map)SCR::Execute (.target.bash_output, command);
integer exit = out["exit"]:0;
y2milestone ("Command output: %1", out);
ret = ret && (0 == exit);
}
}
return ret;
}
} // EOF
ACC SHELL 2018