2G GSM

3G UMTS/WCDMA


4G LTE

2G GSM

3G UMTS/WCDMA


4G LTE

跟C++的版本 , 操作系统, 编译器关系非常大
当字符串长度>16时
第1个 int64 保存着 buf的地址
对于电信2020年后发行的普通SIM卡和物联网卡,是没有CDMA所需要的CSIM文件的。早期的EC20为了适配当时的电信UIM卡,是做了特殊处理的,启动后会搜寻SIM卡中的CSIM文件,没有这些文件就不会注册到网络。
解决方法:
(1) 读取nv 配置
发送AT命令给EC20模块
AT+QNVFR="/nv/item_files/modem/mmode/operator_name"
读出来的结果应该是 01
(2) 将该配置改为 00
AT+QNVFW="/nv/item_files/modem/mmode/operator_name",00
(3) 插入 电信4G物联网卡,断电重启EC20
说明:
operator_name = 00 表示 OPERATE_NULL, 选网时采用默认设计,无特定运营商
operator_name = 01 表示 OPERATE_CT, 中国电信,选网时是考虑CDMA兼容,SRLTE(CDMA+LTE双在网)等需求
在一款 2017年出厂的EC20上实测成功, 版本为 EC20CEFAGR06A05M4G
Phone connects to Edge Packet Data Gateway (EPDG)
over WiFi
• Voice calls over WiFi
• Phone connects on low/no signal
• Also connects in Airplane mode + WiFi
Connection to EPDG uses IPsec
• Authenticates using Internet Key Exchange Protocol (IKEv2)
Internet Protocol Security
• Confidentiality, data integrity, access control, and data source
authentication
• Recovery from transmission errors: packet loss, packet replay, and
packet forgery
• Authentication
• Authentication Header (AH) – RFC 4302
• Confidentiality
• Encapsulating Security Payload (ESP) – RFC 4303
• Key management
• Internet Key Exchange v2 (IKEv2) – RFC7296
• Two modes
• Tunnel – used for connection to Gateway (EPDG)
• Transport
Internet Key Exchange (IKEv2)
• Initiates connection in two phases
• IKE_SA_INIT
• Negotiate cryptographic algorithms, exchange nonces, and do
a Diffie-Hellman exchange
• IKE_AUTH
• Authenticate the previous messages, exchange identities (e.g.
IMSI), and certificates, and establish the child Security
Association(s) (SA)
• IKE_AUTH uses EAP-AKA
• IMSI exchange not protected by a certificate
• Open to MitM attacks on identity (IMSI)
IPsec ESP keys are not compromised
• Call content still safe
小米firmware下载的cdn 限速了。
据说是因为一帮搞 pcdn的人,为了让自己的上行流量占比 小一点, 故意刷下行流量。 其中小米firmware的下载地址是很好获取的,所以被狂刷了很多流量。
其实没什么用,现在运营商不是看占比, 而是上行流量超过多少G,就停宽带。
默认的地址是 bigota.d.miui.com, 改成
cdn-ota.azureedge.net
cdnorg.d.miui.com
bn.d.miui.com
bkt-sgp-miui-ota-update-alisgp.oss-ap-southeast-1.aliyuncs.com
有时候可以提高下载速率
https://bn.d.miui.com/V12.5.15.0.RGGEUXM/begonia_eea_global_images_V12.5.15.0.RGGEUXM_20220826.0000.00_11.0_eea_b8c6b15c15.tgz
https://cdn-ota.azureedge.net/V12.5.15.0.RGGEUXM/begonia_eea_global_images_V12.5.15.0.RGGEUXM_20220826.0000.00_11.0_eea_b8c6b15c15.tgz
https://cdn-ota.azureedge.net/V13.0.8.0.SJHCNXM/atom_images_V13.0.8.0.SJHCNXM_20230630.0000.00_12.0_cn_acca549dfc.tgz
wget -c --referer="https://miui.com/" https://hugeota.d.miui.com/V12.5.6.0.RGGCNXM/begonia_images_V12.5.6.0.RGGCNXM_20220602.0000.00_11.0_cn_fbed701a77.tgz
2017年的时候有做过这样的一个定制化需求:写入一个文件数据,恢复出厂设置后该文件数据也要恢复。
第一步:nvram lib id定义
vendor/mediatek/proprietary/custom/project/cgen/inc/Custom_NvRam_LID.h
typedef enum
{
AP_CFG_RDCL_FILE_AUDIO_LID=AP_CFG_CUSTOM_BEGIN_LID, //AP_CFG_CUSTOM_BEGIN_LID: this lid must not be changed, it is reserved for system.
AP_CFG_RDCL_FILE_AUDIO_MAGI_CONFERENCE_LID,
AP_CFG_RDCL_FILE_AUDIO_HAC_PARAM_LID,
AP_CFG_CUSTOM_TEST_CUSTOM1_LID, //zrx add 定义lib id
AP_CFG_CUSTOM_FILE_MAX_LID,
} CUSTOM_CFG_FILE_LID;
//zrx add 添加LID版本信息
#define AP_CFG_CUSTOM_TEST_CUSTOM1_LID_VERNO "000"
第二步:nvram lib id的数据结构和版本号声明
vendor/mediatek/proprietary/custom/project/cgen/inc/Custom_NvRam_data_item.h
//zrx add
LID_BIT VER_LID(AP_CFG_CUSTOM_TEST_CUSTOM1_LID)
Test_Custom1_Struct *CFG_TEST_CUSTOM1_REC_TOTAL
{
};
第三步:nvram lib数据结构定义
vendor/mediatek/proprietary/custom/project/cgen/cfgfileinc/CFG_Custom1_File.h
//zrx add start
typedef struct
{
unsigned char Array[1024];
}Test_Custom1_Struct;
//zrx add end
//zrx add start
#define CFG_TEST_CUSTOM1_REC_SIZE sizeof(Test_Custom1_Struct)
#define CFG_TEST_CUSTOM1_REC_TOTAL 1
//zrx add end
第四步:nvram lib 默认值定义
vendor/mediatek/proprietary/custom/project/cgen/cfgdefault/CFG_Custom1_Default.h
Test_Custom1_Struct stCustom2Default =
{
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
};
第五步:nvram lib内容加入nvram数组中
vendor/mediatek/proprietary/custom/m107/cgen/inc/CFG_file_info_custom.h
#include "../cfgfileinc/CFG_Custom1_File.h"
#include "../cfgdefault/CFG_Custom1_Default.h"
const TCFG_FILE g_akCFG_File_Custom[]=
{
{ "/data/nvram/APCFG/APRDCL/Test_Custom1", VER(AP_CFG_CUSTOM_TEST_CUSTOM1_LID), CFG_TEST_CUSTOM1_REC_SIZE,
CFG_TEST_CUSTOM1_REC_TOTAL, SIGNLE_DEFUALT_REC , (char *)&stCustom2Default, DataReset , NULL
},
};
第六步:nvram lib id需要备份到BinRegion
vendor/mediatek/proprietary/external/nvram/libcustom_nvram/CFG_file_info.c
FileName aBackupToBinRegion[]=
{
{"CUSTOM_TEST",AP_CFG_CUSTOM_TEST_CUSTOM1_LID},
}
pfConvertFunc aNvRamConvertFuncTable[]=
{
NULL,//AP_CFG_CUSTOM_TEST_CUSTOM1_LID
}
const TABLE_FOR_SPECIAL_LID g_new_nvram_lid[] =
{
{ AP_CFG_CUSTOM_TEST_CUSTOM1_LID, 1024 * 1024, 1024 * 1024},
};
第七步:上层读写nvram数据接口
NvRAMAgent.java
package com.example.nvram_test;
import android.os.IBinder;
public interface NvRAMAgent extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements NvRAMAgent
{
private static final java.lang.String DESCRIPTOR = "NvRAMAgent";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an NvRAMAgent interface,
* generating a proxy if needed.
*/
public static NvRAMAgent asInterface(android.os.IBinder obj)
{
if ((obj == null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface) obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof NvRAMAgent))) {
return ((NvRAMAgent) iin);
}
return new NvRAMAgent.Stub.Proxy(obj);
}
public android.os.IBinder asBinder()
{
return this;
}
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_READFILE:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
byte[] _result = this.readFile(_arg0);
reply.writeNoException();
reply.writeByteArray(_result);
return true;
}
case TRANSACTION_WRITEFILE:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
byte[] _arg1;
_arg1 = data.createByteArray();
int _result = this.writeFile(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
default:
{
break;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements NvRAMAgent
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
public byte[] readFile(int file_lid) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
byte[] _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(file_lid);
mRemote.transact(Stub.TRANSACTION_READFILE, _data, _reply, 0);
_reply.readException();
_result = _reply.createByteArray();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public int writeFile(int file_lid, byte[] buff) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(file_lid);
_data.writeByteArray(buff);
mRemote.transact(Stub.TRANSACTION_WRITEFILE, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public byte[] readFileByName(String filename) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
byte[] _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(filename);
mRemote.transact(Stub.TRANSACTION_READFILEBYNAME, _data, _reply, 0);
_reply.readException();
_result = _reply.createByteArray();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public int writeFileByName(String filename, byte[] buff) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(filename);
_data.writeByteArray(buff);
mRemote.transact(Stub.TRANSACTION_WRITEFILEBYNAME, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_READFILE = (IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_WRITEFILE = (IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_READFILEBYNAME = (IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_WRITEFILEBYNAME = (IBinder.FIRST_CALL_TRANSACTION + 3);
}
public byte[] readFile(int file_lid) throws android.os.RemoteException;
public int writeFile(int file_lid, byte[] buff) throws android.os.RemoteException;
public byte[] readFileByName(String filepath) throws android.os.RemoteException;
public int writeFileByName(String filepath, byte[] buff) throws android.os.RemoteException;
}
第八步:读写数据帮助类
Utils.java
ackage com.example.nvram_test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import android.content.Context;
import android.os.IBinder;
import android.os.ServiceManager;
import android.util.Log;
import android.widget.Toast;
public class Utils {
final String TAG = "Utis";
byte[] buff;
Context mContext;
public Utils(Context mContext){
this.mContext=mContext;
}
/**
* 多个字节数组合并为一个字节数组
* @param a 字节数组
* @param b 字节数组
* @return byte[]
*/
public byte[] combineBytes(byte[] a, byte[] b) {
byte[] bytes = new byte[a.length + b.length];
System.arraycopy(a, 0, bytes, 0, a.length);
System.arraycopy(b, 0, bytes, a.length, b.length);
return bytes;
}
/**
* 写文件到app下
*/
public void writeOwnFile(String fileName,String message){
try {
FileOutputStream fout = mContext.openFileOutput(fileName,
mContext.MODE_PRIVATE);
byte[] bytes = message.getBytes();
fout.write(bytes);
fout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 从app下读文件
* @param fileName
* @return
*/
public String readOwnFile(String fileName){
try {
FileInputStream fis=mContext.openFileInput(fileName);
ByteArrayOutputStream bos=new ByteArrayOutputStream();
byte[] buffer=new byte[1024];
int len=0;
while((len=fis.read(buffer))!=-1){
bos.write(buff, 0, len);
}
byte[] content_byte = bos.toByteArray();
String content = new String(content_byte);
return content;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}
/**
* 写文件
* @param fileName 文件名
* @param bytes 字节数组
*/
public void writeFile(String fileName,byte[] bytes){
try {
FileOutputStream fout = new FileOutputStream(fileName);
fout.write(bytes);
fout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 读文件
* @param fileName 文件名
* @return byte[]
*/
public byte[] readFile(String fileName){
try {
FileInputStream fin = new FileInputStream(fileName);
int length = fin.available();
byte [] buffer = new byte[length];
fin.read(buffer);
fin.close();
return buffer;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return buff;
}
/**
* 写值到NvRam
* @param file_name NvRam路径
* @param bytes 字节数组
*/
public void writeData(String file_name, byte[] bytes) {
byte[] buff=new byte[1024];
if(bytes.length 0) {
Toast.makeText(mContext, "write Success", Toast.LENGTH_SHORT).show();
// Log.d(TAG, "zrx----write Success");
} else {
Toast.makeText(mContext, "write Failure", Toast.LENGTH_SHORT).show();
Log.d(TAG, "zrx---- write Failure");
}
}
}
/**
* 从NvRam读值
* @param file_name NvRam路径
* @param offset 开始位置
* @param byteCount 字节数
* @return
*/
public byte[] readData(String file_name,int offset,int byteCount) {
byte[] data=new byte[byteCount];
IBinder binder = ServiceManager.getService("NvRAMAgent");
NvRAMAgent agent = NvRAMAgent.Stub.asInterface(binder);
if (agent != null) {
try {
buff = agent.readFileByName(file_name);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
if (buff != null) {
try {
for(int i=0;i
第九步:验证
MainActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.example.nvram_test.R;
public class MainActivity extends Activity{
String TAG="MainActivity";
/**
* 文件名在vendor/mediatek/proprietary/custom/m107/cgen/inc/CFG_file_info_custom.h中有定义
*/
private static final String TEST_FILENAME = "/data/nvram/APCFG/APRDCL/Test_Custom1";
Button btn1;
Button btn2;
Button btn3;
Button btn4;
Utils utils;
/**
* 测试备份SecretKey文件的路径
*/
private static final String secret_filename="/storage/emulated/0/SecretKey";
/**
* 测试备份goc_database文件的路径
*/
private static final String goc_database="/storage/emulated/0/goc_database";
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
utils=new Utils(this);
btn1=(Button)findViewById(R.id.btn1);
btn2=(Button)findViewById(R.id.btn2);
btn3=(Button)findViewById(R.id.btn3);
btn4=(Button)findViewById(R.id.btn4);
/**
* 测试把SecretKey文件的字节备份到NvRam下
*/
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
byte[] a=utils.readFile(secret_filename); //读SecretKey文件
utils.writeData(TEST_FILENAME, a); //把SecretKey文件的字节备份到NvRam下
//byte[] b=utils.readData(TEST_FILENAME, 0, a.length);
/* if(!Arrays.equals(a, b)){
utils.writeData(TEST_FILENAME, a);
}else{
Toast.makeText(MainActivity.this, "SecretKey Data has existed, no need to backup!", Toast.LENGTH_SHORT).show();
}*/
}
});
/**
* 测试从NvRAM读SecretKey文件的字节
*/
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
byte[] bytes=utils.readData(TEST_FILENAME,0,27);//测试从NvRAM读SecretKey文件的字节
Toast.makeText(getApplicationContext(), "data = "+new String(bytes), Toast.LENGTH_LONG).show();
}
});
/**
* 测试写goc_database文件的字节到NvRAM
*/
btn3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
byte[] bytes=utils.readFile(goc_database); //goc_database文件的字节
byte[] a=utils.readData(TEST_FILENAME,0,27); //读NvRAM下SecretKey文件的字节
utils.writeData(TEST_FILENAME, utils.combineBytes(a, bytes));
}
});
/**
* 测试写到NvRAM下的goc_database文件字节是否与原文件goc_database是否一样。
*/
btn4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
byte[] bytes=utils.readFile(goc_database); //读goc_database文件
byte[] b=utils.readData(TEST_FILENAME, 27, bytes.length); //读NvRAM下的goc_database字节
utils.writeFile("/storage/emulated/0/goc_database2", b); //把NvRAM下的goc_database字节写到goc_database2文件, goc_database2文件与原文件goc_database比对,发现是相同的。
}
});
}
}
硬件
CPU: Onyx i.MX 6SoloLite [ro.hardware]: [freescale] ro.product.manufacturer]: [Onyx] [ro.build.fingerprint]: [Onyx/JDRead/JDRead:4.4.2/2018-06-29_16-28_r3_a9ff2db/371:user/dev-keys]
开启USB调试
(0)联网
开启JDRead1,连接WiFi
(1)设置密码为0423
设置-设备名称-密码设置:密码输入0423,手机号输入自己的手机号。
为什么设置密码为 0423, 请看 https://www.senventise.com/posts/jdread1-exploit/
(2)开启开发者权限
设置-设备名称-设备信息:连续点击系统版本,直到显示“已开启开发者权限”。
https://www.cnblogs.com/arbo/p/14619813.html
用kingroot进行root
jdread1小白教程及软件v2.2.zip
提醒: 不要替换 services.jar
型号: DP75SDI
属于 Kindel的 第七代 产品
2015 年 6 月 17 日,亚马逊上架了全新 Kindle Paperwhite(KPW3)电子书阅读器。像素 300 ppi, RAM增大了一倍,也就是说运行速度也会有较大提升,但Storage依然是 4GB。 这款新机在亚马逊中国上的预订价格为 958 元,2015 年 6 月 30 日正式发货。
Jailbreak
参考资料:
https://www.mobileread.com/forums/showthread.php?t=225030
https://bookfere.com/post/892.html
https://bookfere.com/post/311.html
https://bookfere.com/post/59.html
设备信息
序列号 G090 G1
固件版本 5.8.11
硬件 Hardware : Freescale i.MX 6SoloLite based Wario Board
步骤:
1. 通过序列号 确定型号
(G090G1 Kindle PaperWhite 3 (2015) WiFi PW3 型号)
可以root / jailbreak
2. 充满电
3. 关掉密码 , 关掉家长控制
4. 开启 飞行模式,关闭3G/WiFi
更新到 5.12.3 固件 https://s3.amazonaws.com/firmwaredownloads/update_kindle_all_new_paperwhite_5.12.3.bin
固件文件名:update_kindle_all_new_paperwhite_5.12.3.bin
MD5 校验码:e4d7ff60132c58448b0c1b31d5961b12
SHA1 校验码:ff8cf3a93ce37f6adf7c12b5166f73dc0ba929fe
6. 下载 kindle-jb-kindlebreak-1.0-r18327.tar.xz
下载 jb-kindlebreak.zip 并解压,得到下列四个文件,把它们全部拷贝到 Kindle 根目录(所谓根目录,就是那个目录下有一个叫documents的子目录)
kindlebreak.jxr
kindlebreak.html
jb.sh
jb
接着点击 Kindle 右上角的菜单按钮,进入“体验版网页浏览器(Experimental Browser)”。
请务必确保“浏览器设置”中的图片设置处于启用状态,也就是显示“禁用图片(Disable Images)”字样。如显示的是“启用图片(Enable Images)”字样,你需要点击启用,以确保浏览器能够正常解析图片。
最后输入如下所示的文件地址(注意 file:/// 是一个冒号三个斜杠):
file:///mnt/us/kindlebreak.html
如果一切正常,Kindle 会在数秒至数分钟后自动重启(时长取决于不同设备)。重启完毕越狱便告成功。之前放进去的文件会被自动清理,你会在 Kindle 根目录看到一个日志文件 kindlebreak_log.txt。
7. 安装热修复补丁 JailBreak-1.16.N-FW-5.x-hotfix.zip
Jailbreak Hotfix 的具体安装步骤如下:
(1)用 USB 数据线把 Kindle 连接到电脑,直到出现 Kindle 盘符;
(2)解压缩下载到的 ZIP 压缩包 JailBreak-x.xx.N-FW-5.x-hotfix.zip,得到一个名为 Update_jailbreak_hotfix_x.xx.N_install.bin 的文件;
(3)将此 bin 文件拷贝到 Kindle 磁盘根目录,然后从电脑弹出 Kindle;
(4) 依次在 Kindle 中点击【菜单 → 设置 → 菜单 → 更新您的 Kindle】,等待重启;
8. 安装 MobileRead Package Installer (MRPI)
(1)用 USB 数据线将 Kindle 连接到电脑上,直到出现 Kindle 磁盘;
(2) 解压缩下载到的 kual-mrinstaller-1.7.N-xxx.tar.xz 得到一个文件夹;
(3)把文件夹内的 extensions 和 mrpackages 拷贝到 Kindle 的根目录。
(4)从电脑上断开 Kindle磁盘,重启Kindel
注意,如果根目录已有 extensions 这个文件夹,可以只把解压得到的 extensions 文件夹中的内容拷贝到 Kindle 根目录原有的 extensions 文件夹内,以避免原文件夹内的其它文件被删除。
9. 安装 KUAL ( Kindle Unified Application Launcher)
(1) 用 USB 数据线将 Kindle 连接到电脑上,直到出现 Kindle 磁盘;
(2) 如果没有安装MRPI, 先按照第8步的方法安装 MobileRead Package Installer (MRPI);
(3) 然后解压缩下载到的 KUAL-v2.x.xx-xxxxxxxx-20xxxxxx.tar.xz 得到一个文件夹;
在文件夹中找到 Update_KUALBooklet_v2.x.xx_install.bin 文件,拷贝到 Kindle 根目录下的 mrpackages 文件夹,然后在 Kindle 搜索框中输入 ;log mrpi 点击回车;
这时会调用 mrpi 安装 KUAL,安装完成并等待 Kindle 重启完毕后即可使用 KUAL。
10. 安装 Koreader
首先确保安装了 MRPI 和 KUAL;
用 USB 数据线将 Kindle 连接到电脑上,直到出现 Kindle 磁盘;
解压缩下载到的 Koreader 压缩包,可得到 extensions 和 koreader 两个文件夹;
先把文件夹 extensions 中的内容拷贝到 Kindle 根目录下的 extensions 文件夹中;
然后把文件夹内的 koreader 文件夹拷贝到 kindle 根目录下;
通过 KUAL 菜单中启动 Koreader 并用它的文件浏览器打开并阅读电子书。
11. 安装 USBNetwork
(1)首先确保安装了 MRPI 和 KUAL;
(2)用 USB 数据线将 Kindle 连接到电脑上,直到出现 Kindle 磁盘;
(3) 解压缩下载到的 kindle-usbnet-0.xx.N-rxxxxx.tar.xz 压缩包,得到一个文件夹;
(4) 把文件夹内的 Update_usbnet_0.xx.N_install_pw2_and_up.bin 拷贝到 Kindle 里 mrpackages 文件夹中;
(5)弹出 Kindle 磁盘,进入 Kindle 界面,打开 KUAL,依次点击菜单【Helper → Install MR Packages】(或在搜索栏输入 ;log mrpi 并回车);
耐心等待 USBNetwork 安装,直到安装完成后 Kindle 重启完毕;
配置 USBNetwork
修改配置文件
重启完成后,可以在 Kindle 根目录可以看到 usbnet 文件夹。首先将此文件夹中的文件 DISABLED_auto 重命名为 auto。然后在此文件夹里的 etc 文件夹中找到配置文件 config,并用代码编辑器(如 Sublime Text)将其打开。找到 USE_WIFI 和 USE_WIFI_SSHD_ONLY 两个配置项,将两者的值从默认的 false 修改为 true(注意,两者都要改成 true),保存并关闭。
USE_WIFI="true" USE_WIFI_SSHD_ONLY="true"
如果不将USE_WIFI_SSHD_ONLY 改为true, 会导致 将kindel通过usb插入电脑时, 不识别 Kindle 磁盘
创建密钥
ssh-keygen -t rsa -f ~/Desktop/KindleKey
会在你的桌面上会出现 KindleKey 和 KindleKey.pub 两个文件,把其中的 KindleKey.pub 重命名为 authorized_keys,并拷贝到 usbnet 插件目录中的 etc 文件夹中。
ssh登陆到kindle
ssh -i KindleKey root@192.168.xxx.xxx
在 Kindle 搜索框中输入 ;711 可以看到 Kindel分配到IP地址
Redmi Note 10 Pro
天玑1100
CPU型号为 MT6891Z/CZA
( MT6885,天玑1000L, 联发科的首款5G芯片)
sysfs
/sys/kernel/ccci /sys/class/ccci_node/ccci_ccb_meta /sys/class/ccci_node/ccci_ccb_md_monitor /sys/class/ccci_node/ccci_raw_mdm /sys/class/ccci_node/ccci_mdl_monitor /sys/class/ccci_md_sta/ccci_md1_sta /sys/firmware/devicetree/base/mddriver/ccci,modem_info_v2
代码
drivers/misc/mediatek/ccci_util/ccci_util_lib_load_img.c
drivers/misc/mediatek/ccci_util/ccci_util_lib_sys.c
drivers/misc/mediatek/eccci/ccci_core.c
ccci_init(void)
drivers/misc/mediatek/eccci/mt6885/ccci_platform.c
ccci_plat_common_init
配置地址
drivers/misc/mediatek/eccci/ccci_modem.c
void ccci_md_config(struct ccci_modem *md)
{
phys_addr_t md_resv_mem_addr = 0,
md_resv_smem_addr = 0, md1_md3_smem_phy = 0;
unsigned int md_resv_mem_size = 0,
md_resv_smem_size = 0, md1_md3_smem_size = 0;
int amms_pos_size = 0;
phys_addr_t bank4_phy_addr;
......
......
/* Get memory info */
get_md_resv_mem_info(md->index, &md_resv_mem_addr,
&md_resv_mem_size, &md_resv_smem_addr, &md_resv_smem_size);
get_md1_md3_resv_smem_info(md->index, &md1_md3_smem_phy,
&md1_md3_smem_size);
/* setup memory layout */
/* MD image */
md->mem_layout.md_bank0.base_ap_view_phy = md_resv_mem_addr;
md->mem_layout.md_bank0.size = md_resv_mem_size;
/* do not remap whole region, consume too much vmalloc space */
md->mem_layout.md_bank0.base_ap_view_vir =
ccci_map_phy_addr(
md->mem_layout.md_bank0.base_ap_view_phy,
MD_IMG_DUMP_SIZE);
/* Share memory */
/*
* MD bank4 is remap to nearest 32M aligned address
* assume share memoy layout is:
* |---AP/MD1--| <--MD1 bank4 0x0 (non-cacheable)
* |--MD1/MD3--| <--MD3 bank4 0x0 (non-cacheable)
* |---AP/MD3--|
* |--non-used_-|
* |--cacheable--| <-- MD1 bank4 0x8000000 (for 6292)
* this should align with LK's remap setting
*/
eccci/modem_sys1.c
ccci_set_mem_access_protection_1st_stage(md);
eccci/fsm/ccci_fsm.c
ccci_set_mem_access_protection_second_stage
modem firmware的结构
代码位于 drivers/misc/mediatek/ccci_util/ccci_util_lib_load_img.c
#define IMG_MAGIC 0x58881688
#define EXT_MAGIC 0x58891689
#define IMG_NAME_SIZE 32
#define IMG_HDR_SIZE 512
union prt_img_hdr {
struct {
/* always IMG_MAGIC */
unsigned int magic;
/* image size, image header and padding are not included */
unsigned int dsize;
char name[IMG_NAME_SIZE];
/* image load address in RAM */
unsigned int maddr;
/* maddr is counted from the beginning or end of RAM */
unsigned int mode;
/* extension */
/* always EXT_MAGIC */
unsigned int ext_magic;
/* header size is 512 bytes currently,
* but may extend in the future
*/
unsigned int hdr_size;
/* see HDR_VERSION */
unsigned int hdr_version;
/* please refer to #define beginning with SEC_IMG_TYPE_ */
unsigned int img_type;
/* end of image list?
* 0: this image is followed by another image
* 1: end
*/
unsigned int img_list_end;
/* image size alignment setting in bytes,
* 16 by default for AES encryption
*/
unsigned int align_size;
/* high word of image size for 64 bit address support */
unsigned int dsize_extend;
/* high word of image load address in RAM
* for 64 bit address support
*/
unsigned int maddr_extend;
} info;
unsigned char data[IMG_HDR_SIZE];
};
OAI 5G NR SA tutorial with COTS UE
https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/NR_SA_Tutorial_COTS_UE.md