replace common qcom sources with samsung ones

This commit is contained in:
SaschaNes
2025-08-12 22:13:00 +02:00
parent ba24dcded9
commit 6f7753de11
5682 changed files with 2450203 additions and 103634 deletions

View File

@@ -0,0 +1 @@
include $(all-subdir-makefiles)

View File

@@ -0,0 +1,46 @@
Copyright (c) 2011-2013, 2015-2016, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
________________________________________
Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License

View File

@@ -0,0 +1,19 @@
ifeq ($(TARGET_RECOVERY_UI_LIB),librecovery_ui_msm)
ifneq ($(TARGET_SIMULATOR),true)
ifneq ($(filter arm arm64, $(TARGET_ARCH)),)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := librecovery_ui_msm
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES += bootable/recovery/recovery_ui/include
LOCAL_SRC_FILES += msm_recovery_ui.cpp
include $(BUILD_STATIC_LIBRARY)
endif # TARGET_ARCH == arm
endif # !TARGET_SIMULATOR
endif

View File

@@ -0,0 +1,56 @@
/*
Copyright (c) 2015, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "recovery_ui/device.h"
#include "recovery_ui/screen_ui.h"
class MSM_Device : public Device
{
public:
MSM_Device(ScreenRecoveryUI* ui) : Device(ui) {}
bool PostWipeDevice() {
clear_keys_required = true;
return true;
}
char const* GetRebootReason() {
if (clear_keys_required)
return "keys clear";
return "";
}
private:
bool clear_keys_required = false;
};
Device* make_device() {
return new MSM_Device(new ScreenRecoveryUI);
}

View File

@@ -0,0 +1,56 @@
soong_config_module_type {
name: "ufsbsg_cc_defaults",
module_type: "cc_defaults",
config_namespace: "ufsbsg",
variables: ["ufsframework"],
properties: ["cflags"],
}
soong_config_string_variable {
name: "ufsframework",
values: ["sg", "bsg"],
}
ufsbsg_cc_defaults {
name: "ufsbsg_defaults",
soong_config_variables: {
ufsframework: {
bsg : {
cflags : ["-D_BSG_FRAMEWORK_KERNEL_HEADERS"],
},
},
},
}
cc_library {
name: "librecovery_updater",
vendor: true,
recovery_available: true,
defaults: ["libion_header_paths" ,"ufsbsg_defaults"],
srcs: [
"gpt-utils.cpp",
"recovery-ufs-bsg.cpp",
],
static_libs: [
"libbase",
],
shared_libs: [
"libcutils",
"libion",
"liblog",
"libz",
],
cflags: [
"-Wall",
"-Wno-unused-parameter",
],
sanitize: {
cfi: false,
},
owner: "qti",
export_include_dirs: ["."],
header_libs: [
"qti_kernel_headers",
"device_kernel_headers",
],
}

View File

@@ -0,0 +1,64 @@
ifeq ($(AB_OTA_UPDATER), true)
BUILD_OEM_UPDATER := true
endif
#disable dependency if target uses QMAA
ifeq ($(TARGET_USES_QMAA),true)
ifneq ($(TARGET_USES_QMAA_OVERRIDE_ANDROID_RECOVERY),true)
TARGET_HAS_GENERIC_KERNEL_HEADERS := true
endif
endif
ifneq ($(filter librecovery_updater_msm,$(TARGET_RECOVERY_UPDATER_LIBS)),)
BUILD_OEM_UPDATER := true
endif
ifeq ($(BUILD_OEM_UPDATER), true)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_LIBRARIES += libz
LOCAL_C_INCLUDES := bootable/recovery
include $(LIBION_HEADER_PATH_WRAPPER)
LOCAL_C_INCLUDES += $(LIBION_HEADER_PATHS)
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_SRC_FILES := gpt-utils.cpp recovery-ufs-bsg.cpp
LOCAL_CFLAGS := -Wall
LOCAL_NOSANITIZE := cfi
ifeq ($(TARGET_HAS_GENERIC_KERNEL_HEADERS),true)
LOCAL_CFLAGS += -D_GENERIC_KERNEL_HEADERS
LOCAL_CFLAGS += -Wno-unused-parameter
else ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
endif
LOCAL_SHARED_LIBRARIES += libion
LOCAL_MODULE := librecovery_updater_msm
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := bootable/recovery
include $(LIBION_HEADER_PATH_WRAPPER)
LOCAL_C_INCLUDES += $(LIBION_HEADER_PATHS)
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_SRC_FILES := gpt-utils.cpp recovery-ufs-bsg.cpp
LOCAL_CFLAGS := -Wall
ifeq ($(TARGET_HAS_GENERIC_KERNEL_HEADERS),true)
LOCAL_CFLAGS += -D_GENERIC_KERNEL_HEADERS
else ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
endif
LOCAL_SHARED_LIBRARIES += liblog libcutils libz libion
LOCAL_MODULE := librecovery_updater_msm
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
LOCAL_VENDOR_MODULE := true
include $(BUILD_SHARED_LIBRARY)
endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,196 @@
/*
* Copyright (c) 2013,2016,2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GPT_UTILS_H__
#define __GPT_UTILS_H__
#include <vector>
#include <string>
#include <map>
#ifdef __cplusplus
extern "C" {
#endif
#include <unistd.h>
#include <stdlib.h>
/******************************************************************************
* GPT HEADER DEFINES
******************************************************************************/
#define GPT_SIGNATURE "EFI PART"
#define HEADER_SIZE_OFFSET 12
#define HEADER_CRC_OFFSET 16
#define PRIMARY_HEADER_OFFSET 24
#define BACKUP_HEADER_OFFSET 32
#define FIRST_USABLE_LBA_OFFSET 40
#define LAST_USABLE_LBA_OFFSET 48
#define PENTRIES_OFFSET 72
#define PARTITION_COUNT_OFFSET 80
#define PENTRY_SIZE_OFFSET 84
#define PARTITION_CRC_OFFSET 88
#define TYPE_GUID_OFFSET 0
#define TYPE_GUID_SIZE 16
#define PTN_ENTRY_SIZE 128
#define UNIQUE_GUID_OFFSET 16
#define FIRST_LBA_OFFSET 32
#define LAST_LBA_OFFSET 40
#define ATTRIBUTE_FLAG_OFFSET 48
#define PARTITION_NAME_OFFSET 56
#define MAX_GPT_NAME_SIZE 72
/******************************************************************************
* AB RELATED DEFINES
******************************************************************************/
//Bit 48 onwords in the attribute field are the ones where we are allowed to
//store our AB attributes.
#define AB_FLAG_OFFSET (ATTRIBUTE_FLAG_OFFSET + 6)
#define GPT_DISK_INIT_MAGIC 0xABCD
#define AB_PARTITION_ATTR_SLOT_ACTIVE (0x1<<2)
#define AB_PARTITION_ATTR_BOOT_SUCCESSFUL (0x1<<6)
#define AB_PARTITION_ATTR_UNBOOTABLE (0x1<<7)
#define AB_SLOT_ACTIVE_VAL 0x3F
#define AB_SLOT_INACTIVE_VAL 0x0
#define AB_SLOT_ACTIVE 1
#define AB_SLOT_INACTIVE 0
#define AB_SLOT_A_SUFFIX "_a"
#define AB_SLOT_B_SUFFIX "_b"
#define PTN_XBL "xbl"
#define PTN_XBL_CFG "xbl_config"
#define PTN_MULTIIMGOEM "multiimgoem"
#define PTN_MULTIIMGQTI "multiimgqti"
#define PTN_APDP "apdp"
#define PTN_SWAP_LIST PTN_XBL, PTN_XBL_CFG, PTN_MULTIIMGOEM, PTN_MULTIIMGQTI, "sbl1", "rpm", "tz", "aboot", "abl", "hyp", "lksecapp", "keymaster", "cmnlib", "cmnlib32", "cmnlib64", "pmic", "apdp", "devcfg", "hosd", "keystore", "msadp", "mdtp", "mdtpsecapp", "dsp", "aop", "qupfw", "vbmeta", "dtbo", "imagefv", "ImageFv", "vm-bootsys", "shrm", "cpucp", "uefi", "aop_config", "uefisecapp", "featenabler", "vendor_boot", "recovery", "qweslicstore", "xbl_ramdump", "init_boot", "cpucp_dtb", "pvmfw", "spuservice", "soccp_debug", "soccp_dcd", "pdp", "pdp_cdb", "tz_kg", "hdm", "tziccc", "em", "vk", "storsec", "bksecapp", "apnhlos"
#define AB_PTN_LIST PTN_SWAP_LIST, "boot", "system", "vendor", "odm", "modem", "bluetooth"
#define BOOT_DEV_DIR "/dev/block/bootdevice/by-name"
/******************************************************************************
* HELPER MACROS
******************************************************************************/
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/******************************************************************************
* TYPES
******************************************************************************/
enum boot_update_stage {
UPDATE_MAIN = 1,
UPDATE_BACKUP,
UPDATE_FINALIZE
};
enum gpt_instance {
PRIMARY_GPT = 0,
SECONDARY_GPT
};
enum boot_chain {
NORMAL_BOOT = 0,
BACKUP_BOOT
};
struct gpt_disk {
//GPT primary header
uint8_t *hdr;
//primary header crc
uint32_t hdr_crc;
//GPT backup header
uint8_t *hdr_bak;
//backup header crc
uint32_t hdr_bak_crc;
//Partition entries array
uint8_t *pentry_arr;
//Partition entries array for backup table
uint8_t *pentry_arr_bak;
//Size of the pentry array
uint32_t pentry_arr_size;
//Size of each element in the pentry array
uint32_t pentry_size;
//CRC of the partition entry array
uint32_t pentry_arr_crc;
//CRC of the backup partition entry array
uint32_t pentry_arr_bak_crc;
//Path to block dev representing the disk
char devpath[PATH_MAX];
//Block size of disk
uint32_t block_size;
uint32_t is_initialized;
};
/******************************************************************************
* FUNCTION PROTOTYPES
******************************************************************************/
int prepare_boot_update(enum boot_update_stage stage);
//GPT disk methods
struct gpt_disk* gpt_disk_alloc();
//Free previously allocated gpt_disk struct
void gpt_disk_free(struct gpt_disk *disk);
//Get the details of the disk holding the partition whose name
//is passed in via dev
int gpt_disk_get_disk_info(const char *dev, struct gpt_disk *disk);
//Get pointer to partition entry from a allocated gpt_disk structure
uint8_t* gpt_disk_get_pentry(struct gpt_disk *disk,
const char *partname,
enum gpt_instance instance);
//Update the crc fields of the modified disk structure
int gpt_disk_update_crc(struct gpt_disk *disk);
//Write the contents of struct gpt_disk back to the actual disk
int gpt_disk_commit(struct gpt_disk *disk);
//Return if the current device is UFS based or not
int gpt_utils_is_ufs_device();
//Swtich betwieen using either the primary or the backup
//boot LUN for boot. This is required since UFS boot partitions
//cannot have a backup GPT which is what we use for failsafe
//updates of the other 'critical' partitions. This function will
//not be invoked for emmc targets and on UFS targets is only required
//to be invoked for XBL.
//
//The algorithm to do this is as follows:
//- Find the real block device(eg: /dev/block/sdb) that corresponds
// to the /dev/block/bootdevice/by-name/xbl(bak) symlink
//
//- Once we have the block device 'node' name(sdb in the above example)
// use this node to to locate the scsi generic device that represents
// it by checking the file /sys/block/sdb/device/scsi_generic/sgY
//
//- Once we locate sgY we call the query ioctl on /dev/sgy to switch
//the boot lun to either LUNA or LUNB
int gpt_utils_set_xbl_boot_partition(enum boot_chain chain);
//Given a vector of partition names as a input and a reference to a map,
//populate the map to indicate which physical disk each of the partitions
//sits on. The key in the map is the path to the block device where the
//partiton lies and the value is a vector of strings indicating which of
//the passed in partiton names sits on that device.
int gpt_utils_get_partition_map(std::vector<std::string>& partition_list,
std::map<std::string,std::vector<std::string>>& partition_map);
#ifdef __cplusplus
}
#endif
#endif /* __GPT_UTILS_H__ */

View File

@@ -0,0 +1,260 @@
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define LOG_TAG "recovery_ufs"
#include "recovery-ufs-bsg.h"
#ifndef _BSG_FRAMEWORK_KERNEL_HEADERS
#ifndef _GENERIC_KERNEL_HEADERS
#include <scsi/ufs/ioctl.h>
#include <scsi/ufs/ufs.h>
#endif
#endif
//Size of the buffer that needs to be passed to the UFS ioctl
#define UFS_ATTR_DATA_SIZE 32
#ifdef _BSG_FRAMEWORK_KERNEL_HEADERS
static int get_ufs_bsg_dev(void)
{
DIR *dir;
struct dirent *ent;
int ret = -ENODEV;
if ((dir = opendir ("/dev")) != NULL) {
/* read all the files and directories within directory */
while ((ent = readdir(dir)) != NULL) {
if (!strcmp(ent->d_name, "ufs-bsg") ||
!strcmp(ent->d_name, "ufs-bsg0")) {
snprintf(ufs_bsg_dev, FNAME_SZ, "/dev/%s", ent->d_name);
ret = 0;
break;
}
}
if (ret)
ALOGE("could not find the ufs-bsg dev\n");
closedir (dir);
} else {
/* could not open directory */
ALOGE("could not open /dev (error no: %d)\n", errno);
ret = -EINVAL;
}
return ret;
}
int ufs_bsg_dev_open(void)
{
int ret;
if (!fd_ufs_bsg) {
fd_ufs_bsg = open(ufs_bsg_dev, O_RDWR);
ret = errno;
if (fd_ufs_bsg < 0) {
ALOGE("Unable to open %s (error no: %d)",
ufs_bsg_dev, errno);
fd_ufs_bsg = 0;
return ret;
}
}
return 0;
}
void ufs_bsg_dev_close(void)
{
if (fd_ufs_bsg) {
close(fd_ufs_bsg);
fd_ufs_bsg = 0;
}
}
static int ufs_bsg_ioctl(int fd, struct ufs_bsg_request *req,
struct ufs_bsg_reply *rsp, __u8 *buf, __u32 buf_len,
enum bsg_ioctl_dir dir)
{
int ret;
struct sg_io_v4 sg_io;
memset(&sg_io, 0, sizeof(sg_io));
sg_io.guard = 'Q';
sg_io.protocol = BSG_PROTOCOL_SCSI;
sg_io.subprotocol = BSG_SUB_PROTOCOL_SCSI_TRANSPORT;
sg_io.request_len = sizeof(*req);
sg_io.request = (__u64)req;
sg_io.response = (__u64)rsp;
sg_io.max_response_len = sizeof(*rsp);
if (dir == BSG_IOCTL_DIR_FROM_DEV) {
sg_io.din_xfer_len = buf_len;
sg_io.din_xferp = (__u64)(buf);
} else {
sg_io.dout_xfer_len = buf_len;
sg_io.dout_xferp = (__u64)(buf);
}
ret = ioctl(fd, SG_IO, &sg_io);
if (ret)
ALOGE("%s: Error from sg_io ioctl (return value: %d, error no: %d, reply result from LLD: %d\n)",
__func__, ret, errno, rsp->result);
if (sg_io.info || rsp->result) {
ALOGE("%s: Error from sg_io info (check sg info: device_status: 0x%x, transport_status: 0x%x, driver_status: 0x%x, reply result from LLD: %d\n)",
__func__, sg_io.device_status, sg_io.transport_status,
sg_io.driver_status, rsp->result);
ret = -EAGAIN;
}
return ret;
}
static void compose_ufs_bsg_query_req(struct ufs_bsg_request *req, __u8 func,
__u8 opcode, __u8 idn, __u8 index, __u8 sel,
__u16 length)
{
struct utp_upiu_header *hdr = &req->upiu_req.header;
struct utp_upiu_query *qr = &req->upiu_req.qr;
req->msgcode = UTP_UPIU_QUERY_REQ;
hdr->dword_0 = DWORD(UTP_UPIU_QUERY_REQ, 0, 0, 0);
hdr->dword_1 = DWORD(0, func, 0, 0);
hdr->dword_2 = DWORD(0, 0, length >> 8, (__u8)length);
qr->opcode = opcode;
qr->idn = idn;
qr->index = index;
qr->selector = sel;
qr->length = htobe16(length);
}
static int ufs_query_attr(int fd, __u32 value,
__u8 func, __u8 opcode, __u8 idn,
__u8 index, __u8 sel)
{
struct ufs_bsg_request req;
memset(&req, 0, sizeof(req));
struct ufs_bsg_reply rsp;
memset(&rsp, 0, sizeof(rsp));
enum bsg_ioctl_dir dir = BSG_IOCTL_DIR_FROM_DEV;
int ret = 0;
if (opcode == QUERY_REQ_OP_WRITE_DESC || opcode == QUERY_REQ_OP_WRITE_ATTR)
dir = BSG_IOCTL_DIR_TO_DEV;
req.upiu_req.qr.value = htobe32(value);
compose_ufs_bsg_query_req(&req, func, opcode, idn, index, sel, 0);
ret = ufs_bsg_ioctl(fd, &req, &rsp, 0, 0, dir);
if (ret)
ALOGE("%s: Error from ufs_bsg_ioctl (return value: %d, error no: %d\n)",
__func__, ret, errno);
return ret;
}
int32_t set_boot_lun(char *sg_dev,uint8_t lun_id)
{
int32_t ret;
__u32 boot_lun_id = lun_id;
ret = get_ufs_bsg_dev();
if (ret)
return ret;
ALOGV("Found the ufs bsg dev: %s\n", ufs_bsg_dev);
ret = ufs_bsg_dev_open();
if (ret)
return ret;
ALOGV("Opened ufs bsg dev: %s\n", ufs_bsg_dev);
ret = ufs_query_attr(fd_ufs_bsg, boot_lun_id, QUERY_REQ_FUNC_STD_WRITE,
QUERY_REQ_OP_WRITE_ATTR, QUERY_ATTR_IDN_BOOT_LU_EN, 0, 0);
if (ret) {
ALOGE("Error requesting ufs attr idn %d via query ioctl (return value: %d, error no: %d)",
QUERY_ATTR_IDN_BOOT_LU_EN, ret, errno);
goto out;
}
out:
ufs_bsg_dev_close();
return ret;
}
#endif
#ifndef _BSG_FRAMEWORK_KERNEL_HEADERS
int32_t set_boot_lun(char *sg_dev, uint8_t boot_lun_id)
{
#ifndef _GENERIC_KERNEL_HEADERS
int fd = -1;
int rc;
struct ufs_ioctl_query_data *data = NULL;
size_t ioctl_data_size = sizeof(struct ufs_ioctl_query_data) + UFS_ATTR_DATA_SIZE;
data = (struct ufs_ioctl_query_data*)malloc(ioctl_data_size);
if (!data) {
fprintf(stderr, "%s: Failed to alloc query data struct\n",
__func__);
goto error;
}
memset(data, 0, ioctl_data_size);
data->opcode = UPIU_QUERY_OPCODE_WRITE_ATTR;
data->idn = QUERY_ATTR_IDN_BOOT_LU_EN;
data->buf_size = UFS_ATTR_DATA_SIZE;
data->buffer[0] = boot_lun_id;
fd = open(sg_dev, O_RDWR);
if (fd < 0) {
fprintf(stderr, "%s: Failed to open %s(%s)\n",
__func__,
sg_dev,
strerror(errno));
goto error;
}
rc = ioctl(fd, UFS_IOCTL_QUERY, data);
if (rc) {
fprintf(stderr, "%s: UFS query ioctl failed(%s)\n",
__func__,
strerror(errno));
goto error;
}
close(fd);
free(data);
return 0;
error:
if (fd >= 0)
close(fd);
if (data)
free(data);
return -1;
#else
return 0;
#endif
}
#endif

View File

@@ -0,0 +1,131 @@
#ifndef __RECOVERY_UFS_BSG_H__
#define __RECOVERY_UFS_BSG_H__
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/bsg.h>
#include <scsi/scsi_bsg_ufs.h>
#include <endian.h>
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#ifdef ANDROID
#include "cutils/log.h"
#endif
#ifdef OE
#include <syslog.h>
#define LOGI(...) syslog(LOG_NOTICE, "INFO:" __VA_ARGS__)
#define LOGV(...) syslog(LOG_NOTICE,"VERB:" __VA_ARGS__)
#define LOGD(...) syslog(LOG_DEBUG,"DBG:" __VA_ARGS__)
#define LOGE(...) syslog(LOG_ERR,"ERR:" __VA_ARGS__)
#define LOGW(...) syslog(LOG_WARNING,"WRN:" __VA_ARGS__)
#define strlcat(d,s,l) snprintf(d+strlen(d),l,"%s",s)
#endif
#define FNAME_SZ 64
#define SG_IO 0x2285
#define DWORD(b3, b2, b1, b0) htobe32((b3 << 24) | (b2 << 16) |\
(b1 << 8) | b0)
/* UFS BSG device nodes */
char ufs_bsg_dev[FNAME_SZ] = "/dev/ufs-bsg";
int fd_ufs_bsg;
int32_t set_ufs_lun(uint8_t lun_id);
#ifdef _BSG_FRAMEWORK_KERNEL_HEADERS
/* UPIU Transaction Codes */
enum {
UTP_UPIU_NOP_OUT = 0x00,
UTP_UPIU_COMMAND = 0x01,
UTP_UPIU_DATA_OUT = 0x02,
UTP_UPIU_TASK_REQ = 0x04,
UTP_UPIU_QUERY_REQ = 0x16,
};
/* UPIU Query Function field */
enum {
QUERY_REQ_FUNC_STD_READ = 0x01,
QUERY_REQ_FUNC_STD_WRITE = 0x81,
};
enum query_req_opcode {
QUERY_REQ_OP_READ_DESC = 0x1,
QUERY_REQ_OP_WRITE_DESC = 0x2,
QUERY_REQ_OP_READ_ATTR = 0x3,
QUERY_REQ_OP_WRITE_ATTR = 0x4,
QUERY_REQ_OP_READ_FLAG = 0x5,
QUERY_REQ_OP_SET_FLAG = 0x6,
QUERY_REQ_OP_CLEAR_FLAG = 0x7,
QUERY_REQ_OP_TOGGLE_FLAG = 0x8,
};
enum query_desc_idn {
QUERY_DESC_IDN_DEVICE = 0x0,
QUERY_DESC_IDN_UNIT = 0x2,
QUERY_DESC_IDN_GEOMETRY = 0x7,
};
enum query_desc_size {
QUERY_DESC_SIZE_DEVICE = 0x40,
QUERY_DESC_SIZE_GEOMETRY = 0x48,
QUERY_DESC_SIZE_UNIT = 0x23,
};
enum bsg_ioctl_dir {
BSG_IOCTL_DIR_TO_DEV,
BSG_IOCTL_DIR_FROM_DEV,
};
enum query_attr_idn {
QUERY_ATTR_IDN_BOOT_LU_EN = 0x00,
QUERY_ATTR_IDN_RESERVED = 0x01,
QUERY_ATTR_IDN_POWER_MODE = 0x02,
QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03,
};
#endif /* _BSG_FRAMEWORK_KERNEL_HEADERS */
#endif /* __RECOVERY_UFS_BSG_H__ */

View File

@@ -0,0 +1,364 @@
# Copyright (C) 2009 The Android Open Source Project
# Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Emit commands needed for QTI devices during OTA installation
(installing the radio image)."""
import common
import re
bootImages = {}
binImages = {}
fwImages = {}
# Parse filesmap file containing firmware residing places
def LoadFilesMap(zip, name="RADIO/filesmap"):
try:
data = zip.read(name)
except KeyError:
print "Warning: could not find %s in %s." % (name, zip)
data = ""
d = {}
for line in data.split("\n"):
line = line.strip()
if not line or line.startswith("#"):
continue
pieces = line.split()
if not (len(pieces) == 2):
raise ValueError("malformed filesmap line: \"%s\"" % (line,))
d[pieces[0]] = pieces[1]
return d
# Read firmware images from target files zip
def GetRadioFiles(z):
out = {}
for info in z.infolist():
f = info.filename
if f.startswith("RADIO/") and (f.__len__() > len("RADIO/")):
fn = f[6:]
if fn.startswith("filesmap"):
continue
data = z.read(f)
out[fn] = common.File(f, data)
# This is to include vbmeta,dtbo images from IMAGES/ folder.
if f.startswith("IMAGES/") and (f.__len__() > len("IMAGES/")):
if ("vbmeta" in f or "dtbo" in f):
fn = f[7:]
data = z.read(f)
out[fn] = common.File(f, data)
return out
# Get firmware residing place from filesmap
def GetFileDestination(fn, filesmap):
# if file is encoded disregard the .enc extention
if fn.endswith('.enc'):
fn = fn[:-4]
# get backup destination as well if present
backup = None
if fn + ".bak" in filesmap:
backup = filesmap[fn + ".bak"]
# If full filename is not specified in filesmap get only the name part
# and look for this token
if fn not in filesmap:
fn = fn.split(".")[0] + ".*"
if fn not in filesmap:
if ("vbmeta" in fn or "dtbo" in fn):
raise common.ExternalError("Filesmap entry for vbmeta or dtbo missing !!")
print "warning radio-update: '%s' not found in filesmap" % (fn)
return None, backup
return filesmap[fn], backup
# Separate image types as each type needs different handling
def SplitFwTypes(files):
boot = {}
bin = {}
fw = {}
for f in files:
extIdx = -1
dotSeparated = f.split(".")
while True:
if dotSeparated[extIdx] != 'p' and dotSeparated[extIdx] != 'enc':
break
extIdx -= 1
if dotSeparated[extIdx] == 'mbn' or dotSeparated[extIdx] == 'elf' or dotSeparated[extIdx] == 'img':
boot[f] = files[f]
elif dotSeparated[extIdx] == 'bin':
bin[f] = files[f]
else:
fw[f] = files[f]
return boot, bin, fw
# Prepare radio-update files and verify them
def OTA_VerifyEnd(info, api_version, target_zip, source_zip=None):
if api_version < 3:
print "warning radio-update: no support for api_version less than 3"
return False
print "Loading radio filesmap..."
filesmap = LoadFilesMap(target_zip)
if filesmap == {}:
print "warning radio-update: no or invalid filesmap file found"
return False
print "Loading radio target..."
tgt_files = GetRadioFiles(target_zip)
if tgt_files == {}:
print "warning radio-update: no radio images in input target_files"
return False
src_files = None
if source_zip is not None:
print "Loading radio source..."
src_files = GetRadioFiles(source_zip)
update_list = {}
largest_source_size = 0
print "Preparing radio-update files..."
for fn in tgt_files:
dest, destBak = GetFileDestination(fn, filesmap)
if dest is None:
continue
tf = tgt_files[fn]
sf = None
if src_files is not None:
sf = src_files.get(fn, None)
full = sf is None or fn.endswith('.enc')
if not full:
# no difference - skip this file
if tf.sha1 == sf.sha1:
continue
d = common.Difference(tf, sf)
_, _, d = d.ComputePatch()
# no difference - skip this file
if d is None:
continue
# if patch is almost as big as the file - don't bother patching
full = len(d) > tf.size * common.OPTIONS.patch_threshold
if not full:
f = "patch/firmware-update/" + fn + ".p"
common.ZipWriteStr(info.output_zip, f, d)
update_list[f] = (dest, destBak, tf, sf)
largest_source_size = max(largest_source_size, sf.size)
if full:
f = "firmware-update/" + fn
common.ZipWriteStr(info.output_zip, f, tf.data)
update_list[f] = (dest, destBak, None, None)
global bootImages
global binImages
global fwImages
bootImages, binImages, fwImages = SplitFwTypes(update_list)
# If there are incremental patches verify them
if largest_source_size != 0:
info.script.Comment("---- radio update verification ----")
info.script.Print("Verifying radio-update...")
for f in bootImages:
dest, destBak, tf, sf = bootImages[f]
# Not incremental
if sf is None:
continue
info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" %
(dest, sf.size, sf.sha1, tf.size, tf.sha1))
if destBak is not None:
info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" %
(destBak, sf.size, sf.sha1, tf.size, tf.sha1))
for f in binImages:
dest, destBak, tf, sf = binImages[f]
# Not incremental
if sf is None:
continue
info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" %
(dest, sf.size, sf.sha1, tf.size, tf.sha1))
last_mounted = ""
for f in fwImages:
dest, destBak, tf, sf = fwImages[f]
# Not incremental
if sf is None:
continue
# Get the filename without the path and the patch (.p) extention
f = f.split("/")[-1][:-2]
# Parse filesmap destination paths for "/dev/" pattern in the beginng.
# This would mean that the file must be written to block device -
# fs mount needed
if dest.startswith("/dev/"):
if last_mounted != dest:
info.script.AppendExtra('unmount("/firmware");')
info.script.AppendExtra('mount("vfat", "EMMC", "%s", "/firmware");' %
(dest))
last_mounted = dest
dest = "/firmware/image/" + f
else:
dest = dest + "/" + f
info.script.PatchCheck(dest, tf.sha1, sf.sha1)
info.script.CacheFreeSpaceCheck(largest_source_size)
return True
def FullOTA_Assertions(info):
#TODO: Implement device specific asserstions.
return
def IncrementalOTA_Assertions(info):
#TODO: Implement device specific asserstions.
return
def IncrementalOTA_VerifyEnd(info):
OTA_VerifyEnd(info, info.target_version, info.target_zip, info.source_zip)
return
# This function handles only non-HLOS whole partition images
def InstallRawImage(script, f, dest, tf, sf):
if f.endswith('.p'):
script.ApplyPatch("EMMC:%s:%d:%s:%d:%s" %
(dest, sf.size, sf.sha1, tf.size, tf.sha1),
"-", tf.size, tf.sha1, sf.sha1, f)
else:
script.AppendExtra('package_extract_file("%s", "%s");' % (f, dest))
return
# This function handles only non-HLOS boot images - files list must contain
# only such images (aboot, tz, etc)
def InstallBootImages(script, files):
bakExists = False
# update main partitions
script.AppendExtra('ifelse(msm.boot_update("main"), (')
for f in files:
dest, destBak, tf, sf = files[f]
if destBak is not None:
bakExists = True
InstallRawImage(script, f, dest, tf, sf)
script.AppendExtra('), "");')
# update backup partitions
if bakExists:
script.AppendExtra('ifelse(msm.boot_update("backup"), (')
for f in files:
dest, destBak, tf, sf = files[f]
if destBak is not None:
InstallRawImage(script, f, destBak, tf, sf)
script.AppendExtra('), "");')
# just finalize primary update stage
else:
script.AppendExtra('msm.boot_update("backup");')
# finalize partitions update
script.AppendExtra('msm.boot_update("finalize");')
return
# This function handles only non-HLOS bin images
def InstallBinImages(script, files):
for f in files:
dest, _, tf, sf = files[f]
InstallRawImage(script, f, dest, tf, sf)
return
# This function handles only non-HLOS firmware files that are not whole
# partition images (modem, dsp, etc)
def InstallFwImages(script, files):
last_mounted = ""
for f in files:
dest, _, tf, sf = files[f]
# Get the filename without the path
fn = f.split("/")[-1]
# Parse filesmap destination paths for "/dev/" pattern in the beginng.
# This would mean that the file must be written to block device -
# fs mount needed
if dest.startswith("/dev/"):
if last_mounted != dest:
script.AppendExtra('unmount("/firmware");')
script.AppendExtra('mount("vfat", "EMMC", "%s", "/firmware");' %
(dest))
last_mounted = dest
dest = "/firmware/image/" + fn
else:
dest = dest + "/" + fn
if f.endswith('.p'):
script.ApplyPatch(dest[:-2], "-", tf.size, tf.sha1, sf.sha1, f)
else:
script.AppendExtra('package_extract_file("%s", "%s");' % (f, dest))
if last_mounted != "":
script.AppendExtra('unmount("/firmware");')
return
def OTA_InstallEnd(info):
print "Applying radio-update script modifications..."
info.script.Comment("---- radio update tasks ----")
info.script.Print("Patching firmware images...")
if bootImages != {}:
InstallBootImages(info.script, bootImages)
if binImages != {}:
InstallBinImages(info.script, binImages)
if fwImages != {}:
InstallFwImages(info.script, fwImages)
return
def FullOTA_InstallEnd_MMC(info):
if OTA_VerifyEnd(info, info.input_version, info.input_zip):
OTA_InstallEnd(info)
return
def FullOTA_InstallEnd_MTD(info):
print "warning radio-update: radio update for NAND devices not supported"
return
def FullOTA_InstallEnd(info):
FullOTA_InstallEnd_MMC(info)
return
def IncrementalOTA_InstallEnd_MMC(info):
OTA_InstallEnd(info)
return
def IncrementalOTA_InstallEnd_MTD(info):
print "warning radio-update: radio update for NAND devices not supported"
return
def IncrementalOTA_InstallEnd(info):
IncrementalOTA_InstallEnd_MMC(info)
return