概述

以EXYNOS加MDM9x25为例,连接示意图如下:

Exynos5433需要这几个GPIO以及HSIC,给MDM9x25上电,下载MDM9x25的binary,efs同步以及MDM9x25出错的时候的ramdump collection等工作。
下面按如下步骤来介绍每个部分所需的代码移植,修改以及流程。
- MDM9x25启动,控制GPIO配置
- MDM9x25代码下载以及efs同步过程
- MDM9x25代码下载以及efs同步过程
- MDM9x25的错误处理流程以及ramdump collect过程
- AP与MDM9x25的IPC通信相关模块

MDM9x25的启动,控制部分代码移植修改

KERNEL代码部分:

(1) device tree添加相关的设置

    mdm_pdata {compatible = "qcom,ext-mdm9x25";pinctrl-names = "default";pinctrl-0 = <&ap2mdm_errfatal &ap2mdm_soft_reset &ap2mdm_hostrdy &ap2mdm_status &ap2mdm_hsic_ready>;qcom,ramdump-delay-ms = <2000>;qcom,ramdump-timeout-ms = <120000>;qcom,sfr-query;qcom,sysmon-subsys-id = <20>;qcom,support-shutdown;qcom,mdm2ap-errfatal-gpio = <&gpa2 6 0xf>;qcom,ap2mdm-errfatal-gpio = <&gpr3 4 0x1>;qcom,mdm2ap-status-gpio   = <&gpa2 3 0xf>;qcom,ap2mdm-status-gpio   = <&gpf1 2 0x1>;qcom,ap2mdm-soft-reset-gpio = <&gpf5 1 0x1>;qcom,mdm2ap-pblrdy-gpio = <&gpa3 0 0xf>;qcom,ap2mdm-vddmin-gpio = <&gpf4 6 0x1>;qcom,mdm2ap-vddmin-gpio = <&gpa2 5 0x0>;qcom,ap2mdm-hsic-ready-gpio = <&gpg2 1 0x1>;};mdmpm_pdata {compatible = "qcom,mdm-hsic-pm";qcom,ap2mdm-hostrdy-gpio = <&gpf5 0 0x1>;qcom,mdm2ap-devicerdy-gpio = <&gpa1 2 0x0>;qcom,mdm2ap-hostwake-gpio = <&gpa3 1 0xf>;reg = <0x15510000 0x100>, /* EHCI */<0x15530000 0x100>, /* PHY */<0x105C0704 0xC>, /* PMU */<0x156E0204 0xC>; /* USB phy clk */};pinctrl@15690000{ap2mdm_errfatal: ap2mdm_errfatal {samsung,pins = "gpr3-4";samsung,pin-function = <0x1>;   /* OUT */samsung,pin-pud = <1>;          /* PULL DOWN */samsung,pin-drv = <0>;};};pinctrl@11090000{ap2mdm_soft_reset: ap2mdm_soft_reset {samsung,pins = "gpf5-1";samsung,pin-function = <0x1>;   /* OUT */samsung,pin-pud = <0>;          /* No PULL */samsung,pin-drv = <0>;};ap2mdm_hostrdy: ap2mdm_hostrdy {samsung,pins = "gpf5-0";samsung,pin-function = <0x1>;   /* OUT */samsung,pin-pud = <1>;          /* PULL DOWN */samsung,pin-drv = <0>;};ap2mdm_status: ap2mdm_status {samsung,pins = "gpf1-2";samsung,pin-function = <0x1>;   /* OUT */samsung,pin-pud = <0>;          /* No PULL */samsung,pin-drv = <0>;};};pinctrl@14CC0000{ap2mdm_hsic_ready: ap2mdm_hsic_ready {samsung,pins = "gpg2-1";samsung,pin-function = <0x1>;   /* OUT */samsung,pin-pud = <1>;          /* PULL DOWN */samsung,pin-drv = <0>;};};

(2) kernel/exynos54xx/drivers/esoc目录添加,并使能如下feature。

//以下是esoc文件夹下的Makefile文件,要使能的feature是
//CONFIG_ESOC,CONFIG_ESOC_DEV,CONFIG_ESOC_MDM_4x,CONFIG_ESOC_MDM_DRV,
//CONFIG_MDM_HSIC_PM这几个。
# generic  external soc control support
ccflags-$(CONFIG_ESOC_DEBUG)   := -DDEBUG
obj-$(CONFIG_ESOC) += esoc_bus.o
obj-$(CONFIG_ESOC_DEV) += esoc_dev.o
obj-$(CONFIG_ESOC_CLIENT)  += esoc_client.o
obj-$(CONFIG_ESOC_MDM_4x)  += esoc-mdm-4x.o
obj-$(CONFIG_ESOC_MDM_DRV) += esoc-mdm-drv.o
obj-$(CONFIG_MDM_HSIC_PM)  += mdm_hsic_pm.o

esoc-mdm-4x.c文件:
1) mdm_probe()->mdm9x25_setup_hw()初始化ap2mdm_errfatal,ap2mdm_hostrdy 等几个GPIO。这个过程比较简单不再赘述。
2) mdm9x25_setup_hw()->esoc_clink_register()创建/dev/esoc-0文件让mem_helper能够检查几个gpio状态,并初始化esoc_clink和mdm_ctrl结构。

int esoc_clink_register(){...dev->bus = &esoc_bus_type;dev->parent = &esoc_bus;dev_set_name(dev, "esoc%d", id);err = device_register(dev);...
}
esoc_bus为device类型,定义和注册如下,所以上面dev->parent = &esoc_bus的话,device_register(dev)之后会在/sys/devices/esoc-bus目录下生成dev的名字对应的节点。struct device esoc_bus = {.init_name = "esoc-bus"
};
device_register(&esoc_bus);看一下dev->bus = &esoc_bus_type;这句。这个其实会负责/dev/esoc-0 字符设备
然后设置相应的file_operation等的。然后还可以通过bus_find_device(),根据esoc_bus_type来找对应的dev。
struct bus_type esoc_bus_type = {.name = "esoc",.match = esoc_bus_match,.dev_attrs = esoc_clink_attrs,
};
bus_register(&esoc_bus_type);//注册esoc_bus_type之后,就会在/sys/bus/下生成esoc目录。
//之后在esoc_dev_init函数里边生成class,创建字符设备等,关键一步还是注册bus_register_notifier。这样以esoc_bus_type为dev->bus的设备注册的时候都会调用对应的函数。int __init esoc_dev_init(void){esoc_class = class_create(THIS_MODULE, "esoc-dev");//在sys/class下生成esoc-devesoc_major = register_chrdev(0, "esoc", &esoc_dev_fops);ret = bus_register_notifier(&esoc_bus_type, &esoc_dev_notifier);
}
static struct notifier_block esoc_dev_notifier = {.notifier_call = esoc_dev_notifier_call,
};
//添加设备的时候,查看bus,并调用相应的notifier函数的过程在:drivers/base/core.c文件中的
//device_add()函数中。
/*/* Notify clients of device addition.  This call must come* after dpm_sysfs_add() and before kobject_uevent().*/if (dev->bus)blocking_notifier_call_chain(&dev->bus->p->bus_notifier,BUS_NOTIFY_ADD_DEVICE, dev);
*///这样在esoc_clink_register()函数中注册dev的话,因为这个dev->bus是esoc_bus_type就会调用到下面的函数,生成/dev/esoc-0,相应的设备号创建和file_operation的定义也可以很容易看到。
//esoc_dev_notifier_call()->esoc_clink_add_device()
int esoc_clink_add_device(struct device *dev, void *dummy)
{struct esoc_udev *esoc_udev;struct esoc_clink *esoc_clink = to_esoc_clink(dev);esoc_udev = get_free_esoc_udev(esoc_clink);if (IS_ERR(esoc_udev))return PTR_ERR(esoc_udev);//下面创建/dev/esoc-0esoc_udev->dev = device_create(esoc_class, &esoc_clink->dev,MKDEV(esoc_major, esoc_clink->id),esoc_clink, "esoc-%d", esoc_clink->id);if (IS_ERR(esoc_udev->dev)) {pr_err("failed to create user device\n");goto dev_err;}return 0;
dev_err:return_esoc_udev(esoc_udev);return -ENODEV;
}
static const struct file_operations esoc_dev_fops = {.owner      = THIS_MODULE,.open       = esoc_dev_open,.unlocked_ioctl = esoc_dev_ioctl,.release    = esoc_dev_release,
};

esoc-mdm-drv.c文件:

int __init esoc_ssr_init(void)
{pr_err("[MIF] %s", __func__);
#if defined(CONFIG_MACH_TRLTE_LDU) || defined(CONFIG_MACH_TBLTE_LDU)pr_err("%s LDU doesn't have modem, skip esoc drv register", __func__);return 0;
#endifreturn esoc_drv_register(&esoc_ssr_drv);
}
//在注册driver的过程中,bus和probe需要被赋值。这样在driver_register的过程中,会调用到bus->match函数,也就是esoc_bus_match()函数来和dev进行匹配(过程是driver_register()->bus_add_driver()->driver_attach()->__driver_attach()->driver_match_device(),因为drv->bus->p->drivers_autoprobe默认是1,所以如果不改动的话,就会调用的相应bus的match函数,如果匹配成功的话,就会调用driver_probe_device()函数等,调用自己的probe函数)。int esoc_drv_register(struct esoc_drv *driver)
{int ret;driver->driver.bus = &esoc_bus_type;driver->driver.probe = esoc_bus_probe; //bus->match函数匹配成功就会调用这个probe函数ret = driver_register(&driver->driver); //if (ret)return ret;return 0;
}
struct bus_type esoc_bus_type = {.name = "esoc",.match = esoc_bus_match, //这个match比较compat_table里边的名字和esoc_link.name。由于esoc_link.name定义成了//MDM9x25_LABEL也就是MDM9x25,所以下面的drv也必须匹配才能调用probe函数.dev_attrs = esoc_clink_attrs,
};static struct esoc_drv esoc_ssr_drv = {.owner = THIS_MODULE,.probe = esoc_ssr_probe,.compat_table = compat_table,.compat_entries = ARRAY_SIZE(compat_table),.driver = {.name = "mdm-4x",},
};static struct esoc_compat compat_table[] = {{   .name = "MDM9x25",.data = NULL,},{.name = "MDM9x35",.data = NULL,},
};
struct bus_type esoc_bus_type = {.name = "esoc",.match = esoc_bus_match,.dev_attrs = esoc_clink_attrs,
};struct bus_type esoc_bus_type = {.name = "esoc",.match = esoc_bus_match,.dev_attrs = esoc_clink_attrs,
};

上面的执行完之后,就会生成/sys/bus/esoc/drivers/mdm-4x

root@royceltectc:/sys/bus/esoc/drivers/mdm-4x # ls -l
ls -l
--w------- root root 4096 2015-01-13 16:35 bind
lrwxrwxrwx root root 2015-01-13 16:35 esoc0 -> ../../../../devices/qcom,mdm1.50/esoc0
--w------- root root 4096 2015-01-13 16:35 uevent
--w------- root root 4096 2015-01-13 16:35 unbind
int esoc_ssr_probe(struct esoc_clink *esoc_clink)
{int ret;struct mdm_drv *mdm_drv;struct esoc_eng *esoc_eng;pr_info("[MIF] %s\n", __func__);mdm_drv = devm_kzalloc(&esoc_clink->dev, sizeof(*mdm_drv), GFP_KERNEL);if (IS_ERR(mdm_drv))return PTR_ERR(mdm_drv);esoc_eng = &mdm_drv->cmd_eng;esoc_eng->handle_clink_evt = mdm_handle_clink_evt;ret = esoc_clink_register_cmd_eng(esoc_clink, esoc_eng);if (ret) {dev_err(&esoc_clink->dev, "failed to register cmd engine\n");return ret;}//设置subsystem restart的函数,具体看下面函数体。ret = mdm_register_ssr(esoc_clink);if (ret)goto ssr_err;mdm_drv->mdm_queue = alloc_workqueue("mdm_drv_queue", 0, 0);if (!mdm_drv->mdm_queue) {dev_err(&esoc_clink->dev, "could not create mdm_queue\n");goto queue_err;}//设置drv_data为mdm_drv,然后初始化mdm_drv。esoc_set_drv_data(esoc_clink, mdm_drv);init_completion(&mdm_drv->boot_done);init_completion(&mdm_drv->req_eng_wait);INIT_WORK(&mdm_drv->ssr_work, mdm_ssr_fn);mdm_drv->esoc_clink = esoc_clink;mdm_drv->mode = PWR_OFF;mdm_drv->boot_fail = false;//设置重启通知函数mdm_drv->esoc_restart.notifier_call = esoc_msm_restart_handler;ret = register_reboot_notifier(&mdm_drv->esoc_restart);if (ret)dev_err(&esoc_clink->dev, "register for reboot failed\n");return 0;
queue_err:esoc_clink_unregister_ssr(esoc_clink);
ssr_err:esoc_clink_unregister_cmd_eng(esoc_clink, esoc_eng);return ret;
}/
mdm_register_ssr()->esoc_clink_register_ssr()->subsys_register()
struct subsys_device *subsys_register(struct subsys_desc *desc)
{struct subsys_device *subsys;int ret;subsys = kzalloc(sizeof(*subsys), GFP_KERNEL);if (!subsys)return ERR_PTR(-ENOMEM);subsys->desc = desc;subsys->owner = desc->owner;subsys->dev.parent = desc->dev;subsys->dev.bus = &subsys_bus_type;subsys->dev.release = subsys_device_release;subsys->notify = subsys_notif_add_subsys(desc->name);snprintf(subsys->wlname, sizeof(subsys->wlname), "ssr(%s)", desc->name);wake_lock_init(&subsys->wake_lock, WAKE_LOCK_SUSPEND, subsys->wlname);INIT_WORK(&subsys->work, subsystem_restart_wq_func);spin_lock_init(&subsys->track.s_lock);subsys->id = ida_simple_get(&subsys_ida, 0, 0, GFP_KERNEL);if (subsys->id < 0) {ret = subsys->id;goto err_ida;}dev_set_name(&subsys->dev, "subsys%d", subsys->id);mutex_init(&subsys->track.lock);ret = subsys_debugfs_add(subsys);if (ret)goto err_debugfs;//生成/sys/devices/qcom,mdm1.50/esoc0/subsys0 ,link到//sys/bus/msm_subsys/devices/sybsys0ret = device_register(&subsys->dev);if (ret) {device_unregister(&subsys->dev);goto err_register;}//生成/dev/subsys_esoc0,并设置file_operations。ret = subsys_misc_device_add(subsys);if (ret) {put_device(&subsys->dev);goto err_register;}return subsys;err_register:subsys_debugfs_remove(subsys);
err_debugfs:mutex_destroy(&subsys->track.lock);ida_simple_remove(&subsys_ida, subsys->id);
err_ida:wake_lock_destroy(&subsys->wake_lock);kfree(subsys);return ERR_PTR(ret);
}

(2) arch/arm/mach-xx/subsystem_restart.c文件:

前面已经讲过在esoc_clink_register_ssr()的时候,创建/dev/subsys_esoc0。
subsys_register()->subsys_misc_device_add()对应的file_operation是:
static const struct file_operations subsys_device_fops = {.owner = THIS_MODULE,.open = subsys_device_open,.release = subsys_device_close,
};
//subsys_device_open()这个是用来做subsystem power up的。
//subsys_device_open()->subsystem_get()->subsys_start()->subsys->desc->powerup()
//由于
static int mdm_register_ssr(struct esoc_clink *esoc_clink)
{esoc_clink->subsys.shutdown = mdm_subsys_shutdown;esoc_clink->subsys.ramdump = mdm_subsys_ramdumps;esoc_clink->subsys.powerup = mdm_subsys_powerup;esoc_clink->subsys.crash_shutdown = mdm_crash_shutdown;return esoc_clink_register_ssr(esoc_clink);
}
所以subsys_device_open()最用调用mdm_subsys_powerup()去给mdm上电。

(3) kernel/exynos54xx/drivers/usb/misc/ks_bridge.c文件修改,识别hsic的device id并创建/dev/ks_bridge节点,用来下载binary, 下载modem ramdump以及做efs sync操作。

ksb_init()->usb_register(&ksb_usb_driver);
//usb驱动定义
static struct usb_driver ksb_usb_driver = {.name =     "ks_bridge",.probe =    ksb_usb_probe,.disconnect =   ksb_usb_disconnect,.suspend =  ksb_usb_suspend,.resume =   ksb_usb_resume,.reset_resume = ksb_usb_resume,.id_table = ksb_usb_ids,.supports_autosuspend = 1,
};
static const struct usb_device_id ksb_usb_ids[] = {{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9008, 0), //0x9008 ks_hsic_bridge设备号.driver_info = (unsigned long)&ksb_fboot_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 2),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904C, 2),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9075, 2),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9079, 2),.driver_info = (unsigned long)&ksb_efs_usb_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x908A, 2),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x908E, 3),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x909C, 2),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x909D, 2),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x909E, 3),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x909F, 2),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x90A0, 2),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x90A4, 3),.driver_info = (unsigned long)&ksb_efs_hsic_dev, },{} /* terminating entry */
};static struct ksb_dev_info ksb_fboot_dev[] = {{.name = "ks_hsic_bridge", //用来下载binary,接收modem ramdump的/dev/ks_hsic_bridge},{.name = "ks_usb_bridge",},
};static struct ksb_dev_info ksb_efs_hsic_dev = {.name = "efs_hsic_bridge", // /dev/efs_hsic_bridge做efs同步的
};

Bootloader部分代码修改:

    需要在cmdline里边添加“androidboot.baseband=mdm”来选择合适的MDM。
//在esoc-mdm-4x.c文件里边查看如下部分
static struct of_device_id mdm_dt_match[] = {{ .compatible = "qcom,ext-mdm9x25",.data = &mdm9x25_ops, },{},
};
MODULE_DEVICE_TABLE(of, mdm_dt_match);static int __init get_baseband(char *str)
{if(!strncasecmp(str, "mdm2", 4)) {strcpy(mdm_dt_match->compatible, "qcom,ext-mdm9x35");mdm_dt_match->data = &mdm9x35_ops;} else if(!strncasecmp(str, "mdm", 3)) {strcpy(mdm_dt_match->compatible, "qcom,ext-mdm9x25");mdm_dt_match->data = &mdm9x25_ops;}pr_emerg("%s: %s\n", __func__, mdm_dt_match->compatible);return 0;
}
__setup("androidboot.baseband=", get_baseband);

Framework层代码:

(1) vendor/qcom/proprietary/mdm_helper目录添加
(2) vendor/qcom/proprietary/ks目录添加
(3) android/device/samsung/trelte_common/init.trelte.rc添加如下代码,启动mdm_helper和mdm_helper_proxy和设置下载目录等:

//init.xx.rc
on fsmkdir /data/tombstones 0771 system system
#MDM requirementmkdir /dev/block/modemsymlink /dev/block/platform/15540000.dwmmc0/by-name/m9kefs1 /dev/block/modem/m9kefs1symlink /dev/block/platform/15540000.dwmmc0/by-name/m9kefs2 /dev/block/modem/m9kefs2symlink /dev/block/platform/15540000.dwmmc0/by-name/m9kefs3 /dev/block/modem/m9kefs3symlink /dev/block/platform/15540000.dwmmc0/by-name/ /dev/block/modem/dump_pathchown system radio /dev/block/modem/m9kefs1chmod 0775 /dev/block/modem/m9kefs1chown system radio /dev/block/modem/m9kefs2chmod 0775 /dev/block/modem/m9kefs2chown system radio /dev/block/modem/m9kefs3chmod 0775 /dev/block/modem/m9kefs3chown system radio /dev/block/modem/dump_pathchmod 0775 /dev/block/modem/dump_pathmkdir /firmware 0771 system systemmount vfat /dev/block/mmcblk0p13 /firmware ro shortname=lower fmask=0133,dmask=0022chown system system /tombstoneschmod 0775 /tombstonesmkdir /tombstones/modem 0775 system systemmkdir /tombstones/lpass 0775 system systemmkdir /tombstones/wcnss 0775 system systemmkdir /tombstones/dsps 0775 system systemrmdir /tombstones/qcksmkdir /tombstones/qcks 771 system systemrmdir /tombstones/efsmkdir /tombstones/efs 771 system systemrmdir /tombstones/mdmmkdir /tombstones/mdm 0771 system systemchown system radio /dev/block/platform/15540000.dw_mmc0/by-namechmod 0775 /dev/block/platform/15540000.dw_mmc0/by-namewrite /sys/module/rmnet_usb/parameters/mux_enabled 1write /sys/module/rmnet_usb/parameters/no_fwd_rmnet_links 8write /sys/module/rmnet_usb/parameters/no_rmnet_insts_per_dev 17write /sys/module/rmnet_usb/parameters/rmnet_data_init 1# Allow QMUX daemon to assign port open wait timechown radio radio /sys/devices/virtual/hsicctl/hsicctl0/modem_waitwrite /sys/module/rmnet_usb/parameters/mux_enabled 1write /sys/module/rmnet_usb/parameters/no_fwd_rmnet_links 8write /sys/module/rmnet_usb/parameters/no_rmnet_insts_per_dev 17write /sys/module/rmnet_usb/parameters/rmnet_data_init 1# Allow QMUX daemon to assign port open wait timechown radio radio /sys/devices/virtual/hsicctl/hsicctl0/modem_waiton early-initsymlink /data/tombstones /tombstonesservice mdm_helper /system/bin/mdm_helperclass coreonrestart setprop ro.service.mdm_helper_restarted "true"
#    disabledservice mdm_helper_proxy /system/bin/mdm_helper_proxyclass coredisabledon property:ro.mdm_helper_proxy_req=truestart mdm_helper_proxy

MDM9x25 HSIC bringup:上电流程

(1) mdm上电:

//vendor/qcom/proprietary/mdm_helper的代码,会启动如下两个service
service mdm_helper /system/bin/mdm_helperclass coreonrestart setprop ro.service.mdm_helper_restarted "true"disabled
service mdm_helper_proxy /system/bin/mdm_helper_proxyclass coredisabled/**********************************
mdm_helper service和mdm_helper_proxy会用waitqueue方式做一个同步。
因为下载binary和其他的操作都是mdm_helper流程做,如果mdm_helper服务先启动,就必须等到mdm_helper_proxy实际给mdm上电之后mdm_helper服务才能进行下载binary和其他操作。
***********************************/
1) mdm_helper_proxy是通过打开/dev/subsys_esoc0实际给mdm上电的,这个在上面的subsystem_restart.c文件中已经讲过。
modem_proxy_routine()->打开/dev/subsys_esoc0之后就每0.5秒醒来一次,继续睡眠:
static void* modem_proxy_routine(void *arg)
{struct mdm_device *dev = (struct mdm_device*)arg;char powerup_node[MAX_PATH_LEN];int fd;snprintf(powerup_node, sizeof(powerup_node),"/dev/subsys_%s",dev->esoc_node);fd = open(powerup_node, O_RDONLY);if (fd < 0) {ALOGE("%s: Proxy thread failed to open esoc node: %s",dev->mdm_name,powerup_node);}do {sleep(50000);} while(1);return NULL;
}2) mdm_helper在哪里等待mdm上电完成并继续做接下来的事情呢?
modem_state_machine()->dev->ops.power_up()->mdm9k_powerup():
int mdm9k_powerup(struct mdm_device *dev){.....if (ioctl(dev->device_descriptor, //打开的是/dev/esoc-0ESOC_WAIT_FOR_REQ, &request) < 0) {ALOGE("%s: REQ_ENG: ESOC_WAIT_FOR_REQ ioctl failed",dev->mdm_name);return RET_FAILED;}.....
}
根据打开的节点和cmd,会跑到esoc_dev_ioctl里边
static long esoc_dev_ioctl(struct file *file, unsigned int cmd,unsigned long arg)
{.....case ESOC_WAIT_FOR_REQ:if (esoc_clink->req_eng != &uhandle->eng)return -EACCES;pr_err("esoc REQ enginer waiting on request\n");err = wait_event_interruptible(esoc_udev->req_wait,//这里就是等待mdm上电的地方!kfifo_is_empty(&esoc_udev->req_fifo));pr_err("esoc REQ engine released from wait\n");if (!err) {pr_err("esoc REQ engine reading from req fifo\n");err = kfifo_out_spinlocked(&esoc_udev->req_fifo, &req,sizeof(req),&esoc_udev->req_fifo_lock);if (err != sizeof(req)) {pr_err("read from clink %s req q failed\n",esoc_clink->name);return -EIO;}pr_err("esoc REQ engine processing request\n");put_user(req, (unsigned long __user *)uarg);}return err;break;....
}

mdm_helper_proxy在上电成功之后,mdm会拉高pbl管脚,因为之前已经设置了中断,会跑到中断函数mdm_pblrdy_change()。调用顺序是mdm_pblrdy_change()->esoc_clink_queue_request()->esoc_udev_handle_clink_req()->wake_up_interruptible(&esoc_udev->req_wait) 这个应该就是唤醒mdm_helper服务的地方。

<4>[    9.766662]  [4:     mdm_helper: 3137] <3>@BATAUTERR@esoc REQ enginer waiting on request
//打印完esoc REQ enginer waiting on request之后mdm_helper进入睡眠
//在mdm_helper_proxy给mdm上电,检测到pbl之
<6>[   10.186900]  [6:mdm_helper_prox: 3257] ext-mdm qcom,mdm1.50: Powering on modem for the first time
<6>[   10.186918]  [6:mdm_helper_prox: 3257] ext-mdm qcom,mdm1.50: mdm_toggle_soft_reset
<6>[   10.207415]  [0:irq/570-mdm pbl: 1767] ext-mdm qcom,mdm1.50: pbl ready 1:
//这里就是检测到pbl变高的时候中断函数打印的
<3>[   10.207438]  [0:irq/570-mdm pbl: 1767] ext-mdm qcom,mdm1.50: Signaling request engine for images
<4>[   10.207455]  [0:irq/570-mdm pbl: 1767] <3>@BATAUTERR@releasing esoc REQ enginer from wait
//后面mdm_helper等待的waitqueue被唤醒,继续执行下载代码或者接受ramdump的操作
<4>[   10.207508]  [4:     mdm_helper: 3137] <3>@BATAUTERR@esoc REQ engine released from wait
<4>[   10.207534]  [4:     mdm_helper: 3137] <3>@BATAUTERR@esoc REQ engine reading from req fifo
<4>[   10.207556]  [4:     mdm_helper: 3137] <3>@BATAUTERR@esoc REQ engine processing request
<12>[   10.207988]  [4:     mdm_helper: 3137] [ALOG] MDM9x35: Setting up HSIC boot link
<12>[   10.208157]  [4:     mdm_helper: 3137] [ALOG] MDM9x35: configure_flashless_boot_dev: Initiating HSIC unbind
<6>[   10.208539]  [4:     mdm_helper: 3137] s5p-ehci 15510000.usb: remove, state 1
<7>[   10.208571]  [4:     mdm_helper: 3137] s5p-ehci 15510000.usb: roothub graceful disconnect
<6>[   10.208605]  [4:     mdm_helper: 3137] usb usb1: USB disconnect, device number 1
<6>[   10.208626]  [4:     mdm_helper: 3137] usb 1-2: USB disconnect, device number 2
<7>[   10.208651]  [4:     mdm_helper: 3137] usb 1-2: unregistering device
<7>[   10.208672]  [4:     mdm_helper: 3137] usb 1-2: unregistering interface 1-2:1.0
<7>[   10.210592]  [1:     mdm_helper: 3137] usb 1-2: usb_disable_device nuking all URBs
<7>[   10.211908]  [3:     mdm_helper: 3137] usb usb1: unregistering device
<7>[   10.211925]  [3:     mdm_helper: 3137] usb usb1: unregistering interface 1-0:1.0
<7>[   10.212353]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: shutdown urb ffffffc0b77ccb40 ep1in-intr
<7>[   10.213146]  [3:     mdm_helper: 3137] usb usb1: usb_disable_device nuking all URBs
<6>[   10.214606]  [0:         mc_log: 3126] MobiCore mcd: 501|SCRYPTO DRV [INFO]: FIPS ECDSA selftest passed.
<6>[   10.255958]  [6:mdm_helper_prox: 3257] ext-mdm qcom,mdm1.50: pblrdy i:0
<6>[   10.255984]  [6:mdm_helper_prox: 3257] ext-mdm qcom,mdm1.50: Set qcom,ap2mdm-hostrdy-gpio to 1 //给mdm上电之后还要拉高ap2mdm-hostrdy-gpio这个gpio。这个管脚一般也表示成AP2MDM_STATUS

MDM9x25 HSIC初始化以及binary下载或者ramdump collect

modem crash触发mdm_errfatal()中断处理函数,然后就是mdm_handle_clink_evt()->mdm_ssr_fn()->subsystem_restart_dev()然后在dev->restart_leve=RESET_SUBSYS_COUPLED的时候,就会再跑到subsystem_restart_wq_func()->mdm_subsys_ramdumps()->mdm_cmd_exe()的ESOC_EXE_DEBUG里,
mdm->debug = 1 后重启cp,等在ramdump collection弄完。
cp重启的时候,会拉高PBL端口,触发mdm_pblrdy_change中断函数,在函数里边检查mdm->debug。等于1的话,就会跑到esoc_clink_queue_request(ESOC_REQ_DEBUG, esoc)->esoc_udev_handle_clink_req()中设置req_fifo的值,并wake_up_interruptible(&esoc_udev->req_wait)。这会唤醒esoc_dev_ioctl中case ESOC_WAIT_FOR_REQ的wait_event_interruptible。并返回req_fifod的值(ESOC_REQ_DEBUG)给应用层。由于modem_state_machine()在开机后会停留在MDM_HELPER_STATE_POST_POWERUP state,每隔一段时间会跑进mdm9k_monitor()函数,用ESOC_WAIT_FOR_REQ读返回值。上面说了重启之后,就会返回ESOC_REQ_DEBUG。所以会赋值dev->required_action = MDM_REQUIRED_ACTION_RAMDUMPS,跑到modem_state_machine()函数的MDM_HELPER_STATE_RAMDUMP状态里边,开始collect_ramdumps。

if (ioctl(dev->device_descriptor,ESOC_WAIT_FOR_REQ, &request) < 0) 

之后mdm9k_powerup()会跑到configure_flashless_boot_dev(),函数如下:

static int configure_flashless_boot_dev(struct mdm_device *dev, int mode)
{struct mdm_private_data *pdata = NULL;int cmd = ESOC_IMG_XFER_RETRY;int req = 0;int rcode, fd;int i;if (!dev) {ALOGE("Device structure passed in as NULL");return RET_FAILED;}pdata = (struct mdm_private_data*)dev->private_data;if(!pdata) {ALOGE("%s: %s: Private data is null",dev->mdm_name, __func__);return RET_FAILED;}if(!strncmp(dev->mdm_link, LINK_HSIC, 5)) {if (mode == MODE_BOOT || mode == MODE_RAMDUMP) { //boot或者modem crash需要下载ramdump的时候ALOGI("%s: Setting up %s boot link",dev->mdm_name,dev->mdm_link);for (i = 0; i < NUM_LINK_RETRIES; ++i) {if (pdata->peripheral_cmd) {ALOGI("%s: %s: Initiating HSIC unbind",dev->mdm_name,__func__);pdata->peripheral_cmd(dev,PERIPHERAL_CMD_UNBIND);}if (ioctl(dev->device_descriptor, ESOC_NOTIFY,&cmd) < 0) {ALOGE("%s: :%s: Failed to reset mdm",dev->mdm_name,__func__);return RET_FAILED;}if (ioctl(dev->device_descriptor,ESOC_WAIT_FOR_REQ,&req) < 0) {ALOGE("%s: %s:wait for image xfer fail",dev->mdm_name,__func__);return RET_FAILED;}if (req != ESOC_REQ_IMG &&(mode != MODE_RAMDUMP)) {ALOGE("%s: %s: Unnexpected request: %d",dev->mdm_name,__func__,req);continue;}usleep(500000);if (pdata->peripheral_cmd) {ALOGI("%s: %s: Initiating HSIC bind",dev->mdm_name,__func__);pdata->peripheral_cmd(dev,PERIPHERAL_CMD_BIND);}rcode = WaitForCOMport(pdata->flashless_boot_device,5, 0);if (rcode == RET_SUCCESS)break;}if (rcode != RET_SUCCESS) {ALOGE("%s: %s: Failed to setup HSIC link",dev->mdm_name,__func__);return RET_FAILED;}} else if (mode == MODE_RUNTIME) {//系统启动之后做efs sync等ALOGI("%s: Setting up %s link for efs_sync",dev->mdm_name,dev->mdm_link);peripheral_reset(dev);ALOGI("%s: Sending boot status notification to HSIC",dev->mdm_name);
#if 1if (ioctl(dev->device_descriptor,ESOC_SET_HSIC_READY) < 0) {ALOGE("%s: %s:hsic_ready failed", dev->mdm_name,__func__);return RET_FAILED;}
#elsefor (i = 0; i < MAX_HSIC_NOTIFICATION_RETRIES; i++) {fd = open(HSIC_NOTIFICATION_NODE, O_WRONLY);if (fd < 0){if (i >= MAX_HSIC_NOTIFICATION_RETRIES \-1) {ALOGE("%s: node open fail: %s",dev->mdm_name,strerror(errno));return RET_FAILED;}usleep(100000);} else {rcode = write(fd, "1", sizeof(char));close(fd);if (rcode < 0) {ALOGE("%s:node write err: %s",dev->mdm_name,strerror(errno));return RET_FAILED;} else {ALOGI("%s: Notification sent",dev->mdm_name);break;}}}
#endif}} else {ALOGE("%s: Link %s not supported by mdm-helper",dev->mdm_name,dev->mdm_link);return RET_FAILED;}return RET_SUCCESS;
}

configure_flashless_boot_dev()函数负责检查建立hsic通道,这个函数中如果是boot或者ramdump状态,会走如下步骤:
(1) hsic unbind:

    pdata->peripheral_cmd(dev,PERIPHERAL_CMD_UNBIND);//这个会跑到mdm_hsic_peripheral_cmd()里边执行如下操作:case PERIPHERAL_CMD_UNBIND://transport_unbind_node = "/sys/bus/platform/drivers/s5p-ehci/unbind"//transport_unbind_command = "15510000.usb"fd = open(pdata->transport_unbind_node, O_WRONLY);if (fd < 0) {ALOGE("Failed to open bind node : %s", strerror(errno));goto error;}if(write(fd, pdata->transport_unbind_command,strlen(pdata->transport_unbind_command)) < 0) {ALOGE("Failed to write to bind node: %s",strerror(errno));goto error;}break;

一般输出如下log

<12>[10.208157]  [4:mdm_helper: 3137] [ALOG] MDM9x35: configure_flashless_boot_dev: Initiating HSIC unbind
<6>[10.208539]  [4:mdm_helper: 3137] s5p-ehci 15510000.usb: remove, state 1
<7>[10.208571]  [4:mdm_helper: 3137] s5p-ehci 15510000.usb: roothub graceful disconnect
<6>[10.208605]  [4:mdm_helper: 3137] usb usb1: USB disconnect, device number 1
<6>[10.208626]  [4:mdm_helper: 3137] usb 1-2: USB disconnect, device number 2
<7>[10.208651]  [4:mdm_helper: 3137] usb 1-2: unregistering device
<7>[10.208672]  [4:mdm_helper: 3137] usb 1-2: unregistering interface 1-2:1.0
<7>[10.210592]  [1:mdm_helper: 3137] usb 1-2: usb_disable_device nuking all URBs
<7>[10.211908]  [3:mdm_helper: 3137] usb usb1: unregistering device
<7>[10.211925]  [3:mdm_helper: 3137] usb usb1: unregistering interface 1-0:1.0
<7>[10.212353]  [3:mdm_helper: 3137] s5p-ehci 15510000.usb: shutdown urb ffffffc0b77ccb40 ep1in-intr
<7>[10.213146]  [3:mdm_helper: 3137] usb usb1: usb_disable_device nuking all URBs

(2) ioctl(dev->device_descriptor, ESOC_NOTIFY, &cmd) 这里cmd是ESOC_IMG_XFER_RETRY,所以看mdm_notify函数中的case ESOC_IMG_XFER_RETRY,是在重启mdm。当然后面紧跟的
ioctl(dev->device_descriptor,ESOC_WAIT_FOR_REQ,&req) < 0)跟上面说的一样,在等待mdm重启完毕,modem的pbl被拉高。
跟上面重启的时候一样,也是输入如下log

<6>[10.255958]  [6:mdm_helper_prox:3257] ext-mdm qcom,mdm1.50: pblrdy i:0
<6>[10.255984]  [6:mdm_helper_prox:3257] ext-mdm qcom,mdm1.50: Set qcom,ap2mdm-hostrdy-gpio to 1
...
<7>[10.306512]  [3:mdm_helper: 3137] s5p-ehci 15510000.usb: stop
<7>[10.307539]  [3:mdm_helper: 3137] s5p-ehci 15510000.usb: reset command 0010b06  park=3 ithresh=1 period=512 Reset HALT
<7>[10.307761]  [3:mdm_helper: 3137] s5p-ehci 15510000.usb: irq normal 9 err 0 iaa 4 (lost 0)
<7>[10.307776]  [3:mdm_helper: 3137] s5p-ehci 15510000.usb: complete 9 unlink 0
<7>[10.307791]  [3mdm_helper: 3137] s5p-ehci 15510000.usb: ehci_stop completed status 1000 Halt
<6>[10.307902]  [3:mdm_helper: 3137] s5p-ehci 15510000.usb: USB bus 1 deregistered
<7>[10.307981]  [3:mdm_helper: 3137] samsung-usb2phy 15530000.usb2phy: samsung_usb2phy_shutdown: End of setting for shutdown
<6>[10.308455]  [3:mdm_helper: 3137] ext-mdm qcom,mdm1.50: mdm_toggle_soft_reset
<4>[10.317728]  [3:mdm_helper: 3137] <3>@BATAUTERR@esoc REQ enginer waiting on request
...
<4>[10.329003]  [3:mdm_helper: 3137] <3>@BATAUTERR@esoc REQ engine released from wait
<4>[10.329013]  [3:mdm_helper: 3137] <3>@BATAUTERR@esoc REQ engine reading from req fifo
<4>[10.329023]  [3:mdm_helper: 3137] <3>@BATAUTERR@esoc REQ engine processing request

(3) hsic bind操作:
和上面unbind差不多: pdata->peripheral_cmd(dev, PERIPHERAL_CMD_BIND)
unbind hsic -> mdm重启成功 -> hsic bind之后,就可以找检测到modem hsic,并根据其idVendor和idProduct初始化usb设备。像如下Log,由于modem已经准备进入下载模式或者ramdump collection模式,所以检测到的usb设备号需要和ks_bridge.c文件中的设备号一样才能创建ks_hsic_bridge节点。

static struct ksb_dev_info ksb_fboot_dev[] = {{.name = "ks_hsic_bridge",},{.name = "ks_usb_bridge",},
};static const struct usb_device_id ksb_usb_ids[] = {{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9008, 0),.driver_info = (unsigned long)&ksb_fboot_dev, },...
}

以下可以看到bind之后检测到usb设备号的过程

<12>[   10.829278]  [3:     mdm_helper: 3137] [ALOG] MDM9x35: configure_flashless_boot_dev: Initiating HSIC bind
<3>[   10.829789]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: s5p_ehci_probe
<7>[   10.829817]  [3:     mdm_helper: 3137] of_get_named_gpio_flags: can't parse gpios property
<3>[   10.829989]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb:  can not find l2-retention value
<6>[   10.830115]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: IP clock gating is N/A
<7>[   10.831096]  [3:     mdm_helper: 3137] samsung-usb2phy 15530000.usb2phy: Can't configure specified phy mode
<7>[   10.831145]  [3:     mdm_helper: 3137] samsung-usb2phy 15530000.usb2phy: end of samsung_usb2phy_init
<6>[   10.831174]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: EHCI Host Controller
<6>[   10.831255]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: new USB bus registered, assigned bus number 1
<7>[   10.831312]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: reset hcs_params 0x1212 dbg=0 cc=1 pcc=2 ordered ports=2
<7>[   10.831341]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: reset hcc_params a026 thresh 2 uframes 256/512/1024 park
<7>[   10.831617]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: park 3
<7>[   10.831659]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: reset command 0080b02  park=3 ithresh=8 period=1024 Reset HALT
<6>[   10.831750]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: irq 254, io mem 0x15510000
<7>[   10.831786]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: init command 0010b05  park=3 ithresh=1 period=512 RUN
<6>[   10.845956]  [3:     mdm_helper: 3137] s5p-ehci 15510000.usb: USB 2.0 started, EHCI 1.00
<7>[   10.846591]  [3:     mdm_helper: 3137] usb usb1: default language 0x0409
<7>[   10.846774]  [3:     mdm_helper: 3137] usb usb1: udev 1, busnum 1, minor = 0
<6>[   10.846797]  [3:     mdm_helper: 3137] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
<6>[   10.846820]  [3:     mdm_helper: 3137] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
<6>[   10.846843]  [3:     mdm_helper: 3137] usb usb1: Product: EHCI Host Controller
<6>[   10.846864]  [3:     mdm_helper: 3137] usb usb1: Manufacturer: Linux 3.10.61-5726939-eng ehci_hcd
<6>[   10.846885]  [3:     mdm_helper: 3137] usb usb1: SerialNumber: 15510000.usb
<7>[   10.848957]  [3:     mdm_helper: 3137] usb usb1: usb_probe_device
<7>[   10.848992]  [3:     mdm_helper: 3137] usb usb1: configuration #1 chosen from 1 choice
<7>[   10.849108]  [3:     mdm_helper: 3137] usb usb1: adding 1-0:1.0 (config #1, interface 0)
<7>[   10.849929]  [3:     mdm_helper: 3137] hub 1-0:1.0: usb_probe_interface
<7>[   10.849965]  [3:     mdm_helper: 3137] hub 1-0:1.0: usb_probe_interface - got id
<6>[   10.850005]  [3:     mdm_helper: 3137] hub 1-0:1.0: USB hub found
<6>[   10.850102]  [3:     mdm_helper: 3137] hub 1-0:1.0: 2 ports detected
<7>[   10.850133]  [3:     mdm_helper: 3137] hub 1-0:1.0: standalone hub
<7>[   10.850155]  [3:     mdm_helper: 3137] hub 1-0:1.0: individual port power switching
<7>[   10.850176]  [3:     mdm_helper: 3137] hub 1-0:1.0: individual port over-current protection
<7>[   10.850198]  [3:     mdm_helper: 3137] hub 1-0:1.0: power on to power good time: 20ms
<7>[   10.850302]  [3:     mdm_helper: 3137] hub 1-0:1.0: local power source is good
<7>[   10.850730]  [3:     mdm_helper: 3137] hub 1-0:1.0: enabling power on all ports
<12>[   10.851554]  [3:     mdm_helper: 3137] [ALOG] Testing if port "/dev/ks_hsic_bridge" exists
<12>[   10.851813]  [3:     mdm_helper: 3137] [ALOG] Couldn't find "/dev/ks_hsic_bridge", 1 of 5
...
<7>[   10.976052]  [1:          khubd:  686] hub 1-0:1.0: state 7 ports 2 chg 0004 evt 0000
<6>[   10.976151]  [1:          khubd:  686] hub 1-0:1.0: port 2, status 0501, change 0000, 480 Mb/s
<7>[   11.036044]  [1:          khubd:  686] s5p-ehci 15510000.usb: port 2 reset complete, port enabled
<7>[ 11.036083]  [1:          khubd:  686] s5p-ehci 15510000.usb: GetStatus port:2 status 001005 0  ACK POWER sig=se0 PE CONNECT
<7>[ 11.037397]  [4:           main: 3171] SELinux: initialized (dev tmpfs, type tmpfs), uses transition SIDs
<6>[ 11.096075]  [1:          khubd:  686] usb 1-2: new high-speed USB device number 2 using s5p-ehci
<7>[ 11.127606]  [0: khubd:  686] usb 1-2: default language 0x0409
<7>[ 11.128296]  [1: khubd:  686] usb 1-2: udev 2, busnum 1, minor = 1
//以下就是到的modem的hsic设备号。
<6>[ 11.128323]  [1: khubd:  686] usb 1-2: New USB device found, idVendor=05c6, idProduct=9008
<6>[ 11.128346]  [1: khubd:  686] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
<6>[   11.128367]  [1:          khubd:  686] usb 1-2: Product: QHSUSB__BULK
<6>[   11.128390]  [1:          khubd:  686] usb 1-2: Manufacturer: Qualcomm CDMA Technologies MSM
<7>[   11.129616]  [1:          khubd:  686] usb 1-2: usb_probe_device
<7>[   11.129651]  [1:          khubd:  686] usb 1-2: configuration #1 chosen from 1 choice
<7>[   11.130061]  [1:          khubd:  686] usb 1-2: adding 1-2:1.0 (config #1, interface 0)
<7>[   11.130791]  [1:          khubd:  686] ks_bridge 1-2:1.0: usb_probe_interface
<7>[   11.130824]  [1:          khubd:  686] ks_bridge 1-2:1.0: usb_probe_interface - got id
<6>[   11.132053]  [2:          khubd:  686] usb 1-2: usb dev connected
...

(4) loadSahara()
走下载binary或者下载ramdump的流程,流程都是按照sahara协议走的。
下载binary的流程:

传一个binary的log,和上图的流程一样
01-01 23:45:52.880  3357  3357 I kickstart: EVENT: !@ STATE <-- SAHARA_WAIT_HELLO
01-01 23:45:52.880  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_HELLO
01-01 23:45:52.880  3357  3357 I kickstart: EVENT: !@ SENDING --> SAHARA_HELLO_RESPONSE
01-01 23:45:52.880  3357  3357 E kickstart: Wrote to /sys/power/wake_lock
01-01 23:45:52.880  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.880  3357  3357 E kickstart: !@ Requested ID 25, file: "/firmware/image/tz.mbn"
01-01 23:45:52.880  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.880  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.890  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.900  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.910  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.910  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.940  3470  3470 W System.err: remove failed: ENOENT (No such file or directory) : /data/system/users/userlist.xml.bak
01-01 23:45:52.960  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.960  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.960  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.960  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_READ_DATA
01-01 23:45:52.970  3357  3357 I kickstart: EVENT: !@ RECEIVED <-- SAHARA_END_IMAGE_TX
01-01 23:45:52.970  3357  3357 I kickstart: EVENT: !@ SENDING --> SAHARA_DONE
01-01 23:45:52.970  3357  3357 E kickstart: !@ 275556 bytes transferred in 0.084783 seconds
01-01 23:45:52.970  3357  3357 I kickstart: EVENT: !@ STATE <-- SAHARA_WAIT_DONE_RESP
01-01 23:45:52.970  3357  3357 E kickstart: Wrote to /sys/power/wake_unlock
01-01 23:45:52.970  3357  3357 I kickstart: EVENT: !@ STATE <-- SAHARA_WAIT_HELLO

Memory dump的流程:


下载ramdump的时候log如下,可以看到和上图的流程一样

01-01 23:45:52.850  3357  3357 I kickstart: WARNING: function: sahara_start:602 !@ Successfully wrote to disk
01-01 23:45:52.850  3357  3357 E kickstart: !@ Received file 'LPM.BIN'
01-01 23:45:52.850  3357  3357 E kickstart: !@ 16384 bytes transferred in 0.003022 seconds
01-01 23:45:52.850  3357  3357 E kickstart: Opening file '/cpdump/MSGRAM.BIN' for writing
01-01 23:45:52.850  3357  3357 I kickstart: EVENT: !@ SENDING --> SAHARA_MEMORY_READ
01-01 23:45:52.850  3357  3357 I kickstart: EVENT: !@ Sent SAHARA_MEMORY_READ, address 0xFC428000, length 0x4000
01-01 23:45:52.860  3357  3357 I kickstart: WARNING: function: sahara_start:588 !@ Received: 16384 bytes
01-01 23:45:52.860  3357  3357 I kickstart: WARNING: function: sahara_start:593 !@ Writing to disk
01-01 23:45:52.860  3357  3357 I kickstart: WARNING: function: sahara_start:602 !@ Successfully wrote to disk
01-01 23:45:52.860  3357  3357 E kickstart: !@ Received file 'MSGRAM.BIN'
01-01 23:45:52.860  3357  3357 E kickstart: !@ 16384 bytes transferred in 0.002020 seconds
01-01 23:45:52.860  3357  3357 E kickstart: Opening file '/cpdump/DATARAM.BIN' for writing
01-01 23:45:52.860  3357  3357 I kickstart: EVENT: !@ SENDING --> SAHARA_MEMORY_READ
01-01 23:45:52.860  3357  3357 I kickstart: EVENT: !@ Sent SAHARA_MEMORY_READ, address 0xFC190000, length 0x10000
01-01 23:45:52.860  3357  3357 I kickstart: WARNING: function: sahara_start:588 !@ Received: 65536 bytes
01-01 23:45:52.860  3357  3357 I kickstart: WARNING: function: sahara_start:593 !@ Writing to disk
01-01 23:45:52.860  3357  3357 I kickstart: WARNING: function: sahara_start:602 !@ Successfully wrote to disk
01-01 23:45:52.860  3357  3357 E kickstart: !@ Received file 'DATARAM.BIN'
01-01 23:45:52.860  3357  3357 E kickstart: !@ 65536 bytes transferred in 0.002780 seconds
01-01 23:45:52.860  3357  3357 E kickstart: Opening file '/cpdump/CODERAM.BIN' for writing
01-01 23:45:52.860  3357  3357 I kickstart: EVENT: !@ SENDING --> SAHARA_MEMORY_READ
01-01 23:45:52.860  3357  3357 I kickstart: EVENT: !@ Sent SAHARA_MEMORY_READ, address 0xFC100000, length 0x20000
01-01 23:45:52.860  3357  3357 I kickstart: WARNING: function: sahara_start:588 !@ Received: 131072 bytes
01-01 23:45:52.860  3357  3357 I kickstart: WARNING: function: sahara_start:593 !@ Writing to disk
01-01 23:45:52.860  3357  3357 I kickstart: WARNING: function: sahara_start:602 !@ Successfully wrote to disk
01-01 23:45:52.860  3357  3357 E kickstart: !@ Received file 'CODERAM.BIN'
01-01 23:45:52.860  3357  3357 E kickstart: !@ 131072 bytes transferred in 0.004864 seconds
01-01 23:45:52.860  3357  3357 E kickstart: Opening file '/cpdump/OCIMEM.BIN' for writing
01-01 23:45:52.860  3357  3357 I kickstart: EVENT: !@ SENDING --> SAHARA_MEMORY_READ
01-01 23:45:52.860  3357  3357 I kickstart: EVENT: !@ Sent SAHARA_MEMORY_READ, address 0xFE800000, length 0x8800
01-01 23:45:52.870  3357  3357 I kickstart: WARNING: function: sahara_start:588 !@ Received: 34816 bytes
01-01 23:45:52.870  3357  3357 I kickstart: WARNING: function: sahara_start:593 !@ Writing to disk
01-01 23:45:52.870  3357  3357 I kickstart: WARNING: function: sahara_start:602 !@ Successfully wrote to disk
01-01 23:45:52.870  3357  3357 E kickstart: !@ Received file 'OCIMEM.BIN'
01-01 23:45:52.870  3357  3357 E kickstart: !@ 34816 bytes transferred in 0.001515 seconds
01-01 23:45:52.870  3357  3357 E kickstart: !@ Successfully downloaded files from target
01-01 23:45:52.880  3357  3357 E kickstart: Wrote to /sys/power/wake_unlock

MDM代码下载,efs同步过程

代码添加及修改:

  • KERNEL代码: kernel/drivers/usb/misc/ks_bridge.c
  • APP层代码: android/vendor/qcom/proprietary/ks目录

用户层及内核代码,功能流程:
AP,CP通过HSIC连接的方式,一个特点是CP本身没有Flash等固态存储媒介来保存本身的Binary。
所以在每次启动的时候AP都需要通过HSIC来发送MDM的Binary过去。所以通过hsic建立usb连接,并完成下载。efs同步也需要通过hsic建立usb连接。

MDM代码模块

MDM9x25 Flashless bootIPC over HSIC相关推荐

  1. HSIC简介:一个有意思的判断相关性的思路

    作者丨苏剑林 单位丨追一科技 研究方向丨NLP,神经网络 个人主页丨kexue.fm 前段时间在机器之心看到这样的一个推送彻底解决梯度爆炸问题,新方法不用反向传播也能训练 ResNet,当然,媒体的标 ...

  2. HSIC and MMD

    1. HSIC 博客链接:HSIC简介:一个有意思的判断相关性的思路 前几天,在机器之心看到这样的一个推送<彻底解决梯度爆炸问题,新方法不用反向传播也能训练ResNet>,当然,媒体的标题 ...

  3. HSIC转USB国产芯片 宸芯科技模块调试案例分享

    宸芯科技在我国行业通信终端SoC芯片专业领域,掌握3G/4G移动通信技术 .产品应用于轨交通信.电力物联网.工业互联网,车联网等多个场景. 因宸芯模块只有一组HSIC高速接口(480MHz 速率) H ...

  4. 读文献 THE HSIC BOTTLENECK: DEEP LEARNING WITHOUT BACK-PROPAGATION 阅读心得

    题目:THE HSIC BOTTLENECK: DEEP LEARNING WITHOUT BACK-PROPAGATION Abstract 这篇文章介绍了深度学习训练中的HSIC瓶颈(希尔伯特-施 ...

  5. USB High Speed Inter-Chip (HSIC) IP: What is it? And why should I use it?

    来源: https://www.synopsys.com/dw/dwtb.php?a=hsic_usb2_device What is HSIC? HSIC (High-Speed Inter-Chi ...

  6. 不用反向传播的HSIC Bottleneck到底讲了啥,及其keras实现

    机器之心上周介绍了一篇论文,说是不用BP也能训练神经网络,论文叫做<The HSIC Bottleneck: Deep Learning without Back-Propagation> ...

  7. HSIC——USB High Speed Inter-Chip

    最近在看原理图的过程中看到了 HSIC 这个东西,不知道这是什么,所以查了一下资料,下面是网址: DWTB: USB High Speed Inter-Chip (HSIC) IP: What is ...

  8. HSIC转USB国产芯片,HSIC接口,HSIC HUB 扩展

    HSIC介绍:全称:High-Speed Inter-Chip 一种芯片间互连标准 USB协会在2007年发布 High-Speed Inter-Chip USB Electrical规范 2信号(频 ...

  9. HSIC Bottleneck的C++程序实现

    论文[The HSIC Bottleneck: Deep Learning without Back-Propagation]中HSIC方法的C++实现程序: #include #include // ...

最新文章

  1. C# 的三种序列化方法
  2. Installshield建立IE快捷方式的方法
  3. 我是一个机箱 《转载》
  4. PHP怎么修改链接,phpcms导航链接怎么修改
  5. OpenJudge:熄灯问题
  6. FinalTest 基于web的登录口令修改设计
  7. html5触摸指定区域,HTML5/CSS3系列教程:HTML5 区域(Sectioning)的重要性
  8. 值类型和引用类型的区别?
  9. Bash之正则表达式
  10. Mybatis的简单介绍,什么是Mybatis框架
  11. 中华文字改革第一人——仓颉
  12. 谈谈eXeScope这款exe修改器
  13. STM32控制AD7124采集调试流程
  14. 利用python编写一个猜数游戏程序。由系统随机产成一个0~100之间的整数,玩家可以进行5次竞猜。如果猜对了,则提示“恭喜你,猜对了“,并结束游戏;如果猜错了,提示玩家一个方向提示,告诉玩家大了小了
  15. 服务器有些系统更新不能卸载,微软 Win10 更新 KB4577586 发布:永久删除 Adobe Flash Player,补丁无法卸载...
  16. TP-LINK路由器手动设置网关、DNS、开启DHCP并指定地址池IP范围
  17. vue 图片剪裁插件
  18. 人工智能学习——神经网络(matlab+python实现)
  19. BZOJ 1695 [Usaco2007 Demo]Walk the Talk 链表+数学
  20. POI和POI-TL操作Word

热门文章

  1. 执法办案系统UWB应用功能
  2. CentOS7中文语言乱码问题解决
  3. [CTSC1997] 选课
  4. 头条巨量快手广点通等平台APPAPI回传事件注册激活-转化联调-API对接原理代码分析和功能实现
  5. 烟卷配送库房温湿度监控系统中应用的温湿度传感器
  6. 解决Simscape Results Explorer显示模拟信息不完全问题
  7. 黑马python基础班---day04
  8. 三星笔记本,win10系统,触摸板操作开启
  9. PB窗口使用技巧之使用窗口属性编程
  10. 重庆体制内计算机老师,重庆教师资格证网(算不算体制内的)