转载了linux和Ubuntu下连接Android 的unkonw问题

本文提供了解决Ubuntu系统中Android手机无法正确识别的问题,通过配置Linux下的ADB驱动,解决连接ADB进行Android程序调试时遇到的相关问题。详细介绍了配置步骤和常见错误处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

最近由于内置的合作商比较多,本人使用的Ubuntu系统好多厂商的Android手机都无法正确的识别,经过一番折腾,和查阅SDK,现把Linux下ADB驱动配置的方法和当中会遇到的相关问题的解决方法整理出来贡献给大家。

Linux下使用手机USB调试模式连接ADB进行Android程序的调试,配置驱动没有Windows来的直观。

具体步骤

首先确认手机连接上电脑,lsusb查看下设备记录。

matthew @matthew- 1230-laptop:~$lsusb
Bus 007 Device 009: ID 18d1:4e12
Bus 007 Device 001: ID 1d6b:0002 LinuxFoundation  2.0 roothub
Bus 006 Device 001: ID 1d6b:0001 LinuxFoundation  1.1 roothub
Bus 005 Device 001: ID 1d6b:0001 LinuxFoundation  1.1 roothub
Bus 003 Device 001: ID 1d6b:0002 LinuxFoundation  2.0 roothub
Bus 002 Device 001: ID 1d6b:0001 LinuxFoundation  1.1 roothub
Bus 001 Device 001: ID 1d6b:0001 LinuxFoundation  1.1 roothub
Bus 004 Device 004: ID 093a: 2510 PixartImaging, Inc.
Bus 004 Device 001: ID 1d6b:0001 LinuxFoundation  1.1 roothub

我这里是:

Bus 007 Device 009: ID 18d1:4e12

然后在/etc/udev/rules.d/下创建一个配置文件:51-android.rules

sudo vim /etc /udev /rules.d / 50-android.rules

文件里添加如下配置参数:

SUBSYSTEM== "usb",SYSFS { "HighTech Computer Corp." }== "0bb4"MODE= "0666"

保存,给配置文件设置下权限

sudo chmod a+rx  /etc /udev /rules.d / 50-android.rules

Restart

sudo /etc /init.d /udevrestart

最后再重启下adb服务,就可以了(没配置环境变量的请进入AndroidSDK tools目录执行sudo ./adb kill-server ./adb devices)

sudo adb kill-server
sudo adb devices
补充

SYSFS参数:

SYSFS { "idVendor" }= "xxx"

针对LinuxADB驱动配置文件里的SYSFS参数是指设备厂商。当初因为是HTC帮Google做的手机,所以官网一开始的用例上写的是”HighTech Computer Corp.”。但现在Moto, 索爱,三星等一批手机厂商的加入,Android生产厂商已不只HTC一家。而且且如果设备型号不是0bb4那该怎么办呢?

读sdk帮助文档的时候,发现sdk已经提供了说明:
(详见:docs/guide/developing/device.html)

If you’re developing on UbuntuLinux, you need to add a rules file that contains a USBconfiguration for each type of device you want to use fordevelopment. Each device manufacturer uses a different vendor ID.The example rules files below show how to add an entry for a singlevendor ID (the HTC vendor ID). In order to support more devices,you will need additional lines of the same format that provide adifferent value for the SYSFS{idVendor} property. For other IDs,see the table of USBVendor IDs, below.

1. Log in as root and create thisfile: /etc/udev/rules.d/51-android.rules.

For Gusty/Hardy, edit the file toread: [注:ubuntu 7.10及以后版本]
SUBSYSTEM==”usb”, SYSFS{idVendor}==”0bb4″, MODE=”0666″

For Dapper, edit the file to read:[注:ubuntu 6.06及以前版本]
SUBSYSTEM==”usb_device”, SYSFS{idVendor}==”0bb4″,MODE=”0666″
2. Now execute:
chmod a+r /etc/udev/rules.d/51-android.rules

只要按照说明把创建的51-android.rules文件中的0bb4修改为相应的USB供应商ID信息即可。
比如我的手机是motorola,idVender是22b8
那么这一行就是

SUBSYSTEM== "usb",SYSFS {idVendor }== "22b8"MODE= "0666"

不过,你可以写多行,以使用各种设备。比如我就写了所有的,如下:

#Acer 0502
SUBSYSTEM== "usb",SYSFS {idVendor }== "0502"MODE= "0666"
#Dell 413c
SUBSYSTEM== "usb",SYSFS {idVendor }== "413c"MODE= "0666"
#Foxconn 0489
SUBSYSTEM== "usb",SYSFS {idVendor }== "0489"MODE= "0666"
#Garmin-Asus 091E
SUBSYSTEM== "usb",SYSFS {idVendor }== "091e"MODE= "0666"
#HTC 0bb4
SUBSYSTEM== "usb",SYSFS {idVendor }== "0bb4"MODE= "0666"
#Huawei 12d1
SUBSYSTEM== "usb",SYSFS {idVendor }== "12d1"MODE= "0666"
#Kyocera 0482
SUBSYSTEM== "usb",SYSFS {idVendor }== "0482"MODE= "0666"
#LG 1004
SUBSYSTEM== "usb",SYSFS {idVendor }== "1004"MODE= "0666"
#Motorola 22b8
SUBSYSTEM== "usb",SYSFS {idVendor }== "22b8"MODE= "0666"
#Nvidia 0955
SUBSYSTEM== "usb",SYSFS {idVendor }== "0955"MODE= "0666"
#Pantech 10A9
SUBSYSTEM== "usb",SYSFS {idVendor }== "10A9"MODE= "0666"
#Samsung 04e8
SUBSYSTEM== "usb",SYSFS {idVendor }== "04e8"MODE= "0666"
#Sharp 04dd
SUBSYSTEM== "usb",SYSFS {idVendor }== "04dd"MODE= "0666"
#Sony Ericsson 0fce
SUBSYSTEM== "usb",SYSFS {idVendor }== "0fce"MODE= "0666"
#ZTE 19D2
SUBSYSTEM== "usb",SYSFS {idVendor }== "19D2"MODE= "0666"

但是这上面的ID,并不能包括所有,我手上就有一台设备的USBID就不在上述之列。
解决办法是你可以使用lsusb命令查看你的USB ID

matthew @matthew- 1230-laptop:~$lsusb
Bus 002 Device 003: ID 413c: 2003 DellComputer Corp. Keyboard
Bus 002 Device 002: ID 0461:4d22 Primax Electronics, Ltd
Bus 002 Device 001: ID 1d6b:0001 LinuxFoundation  1.1 roothub
Bus 001 Device 010: ID 18a1:0002
Bus 001 Device 001: ID 1d6b:0002 LinuxFoundation  2.0 roothub

找到上面的ID为18a1,在文件中添加设备就可以了。

SUBSYSTEM== "usb",SYSFS {idVendor }== "18a1"MODE= "0666"

修改/etc/udev/rules.d/51-android.rules不需要重启Linux机器,重新插拔一下设备就可以了。再次运行adbdevices就可以看到你的设备已经连接

matthew @matthew- 1230-laptop: /opt /android /android-sdk-linux_86 /tools$  sudo . /adbdevices
List of devices attached
0403502001011000 device

而在此之前,你可能看到的是

matthew @matthew- 1230-laptop: /opt /android /android-sdk-linux_86 /tools$  sudo . /adbdevices
List of devices attached
???????????? no permissions
参考资料

http://androidappdocs.appspot.com/guide/developing/device.html
http://androidappdocs.appspot.com/guide/developing/device.html#VendorIds

 

一点点补充

 

1.先下载 adb for linux

网址:http://developer.android.com/sdk

我使用的版本是:
Linux(i386)  android-sdk-linux_x86-1.5_r3.zip

2.解压:
-------------
$ unzip android-sdk-linux_x86-1.5_r3.zip
-------------

3.改名:
-------------
$ mv android-sdk-linux_x86-1.5_r3 adb
-------------

2.配置环境变量:
-------------------
$ gedit ~/.bashrc
-------------------
后里面添加

----------------------------
#Android PATH
export PATH=$PATH:$HOME/adb/tools
----------------------------

注意:
是在文本后面添加,
$HOME是指用户目录
adb是刚刚改名的开发包路径。

3.创建USB驱动文件
进入超管添加设备文件(在window下可以理解为驱动)
-------------------
$su -
#gedit /etc/udev/rules.d/51-android.rules
-------------------

添加下面代码进去
--------------------
SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
--------------------

4.重启电脑
-------------
# reboot
-------------
5.重起过后测试命令,
连接上USB线。
出现#号的就OK啦。
如果出现err,
只有两种情况,
一是USB没连接好,
二是设备文件写错。

-------------------
$ adb shell
* daemon not running. starting it now *
* daemon started successfully *
#

 

PS:如果找不到下载的地方可以百度娘。


<think>我们正在解决用户在使用objdump反汇编vmlinux时遇到的两个错误: 1. "File format not recognized" 2. "don't know how to handle section .relr.dyn" 根据经验,这些错误通常与以下原因有关: - 使用了不匹配的objdump工具(例如,用x86的objdump反汇编ARM架构的内核) - objdump版本过旧,不支持新的ELF节区(如.relr.dyn) 解决方案如下: ### 1. 确保使用正确的交叉编译工具链 vmlinux是特定架构的ELF文件,必须使用对应架构的objdump。 **步骤**: 1. 确定vmlinux的架构编译时使用的工具链 - 使用`file`命令检查vmlinux的架构: ```bash file vmlinux ``` 输出示例: ``` vmlinux: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, BuildID[sha1]=..., with debug_info, not stripped ``` 这里显示是aarch64架构。 2. 选择匹配的交叉编译objdump - 对于aarch64架构,应使用`aarch64-linux-gnu-objdump`或类似前缀的工具 - 安装对应的工具链(如果尚未安装): - Ubuntu/Debian: ```bash sudo apt install binutils-aarch64-linux-gnu ``` - CentOS/RHEL: ```bash sudo yum install binutils-aarch64-linux-gnu ``` 3. 使用交叉编译objdump反汇编: ```bash aarch64-linux-gnu-objdump -D vmlinux > vmlinux.dump ``` ### 2. 更新objdump版本以支持.relr.dyn节区 错误“don't know how to handle section .relr.dyn”表明objdump版本过旧,无法处理新的ELF节区[^1]。 **解决方案**: 1. **升级binutils**:安装最新版本的binutils工具包(包含objdump)。 - 下载源码编译(推荐): ```bash wget https://ftp.gnu.org/gnu/binutils/binutils-2.40.tar.gz tar xvf binutils-2.40.tar.gz cd binutils-2.40 ./configure --prefix=/usr/local make -j$(nproc) sudo make install ``` 然后使用新安装的objdump(路径可能是`/usr/local/bin/objdump`)。 2. **使用交叉编译工具链中的新版objdump**:某些工具链(如Android NDK)可能包含更新版本的objdump。 - 例如,Android NDK中的aarch64-linux-android-objdump: ```bash # 设置NDK路径 export NDK=/path/to/your/ndk $NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -D vmlinux > vmlinux.dump ``` ### 3. 替代方案:使用llvm-objdump(如果可用) LLVM的objdump通常对新特性的支持更好。 **步骤**: 1. 安装LLVM(如果未安装): ```bash # Ubuntu/Debian sudo apt install llvm # CentOS/RHEL sudo yum install llvm ``` 2. 使用llvm-objdump: ```bash llvm-objdump -D vmlinux > vmlinux.dump ``` ### 4. 忽略.relr.dyn节区(不推荐,仅作临时方案) 如果无法升级,可以尝试跳过该节区(但可能导致反汇编不完整): ```bash objdump -D --ignore-relr vmlinux > vmlinux.dump ``` 注意:此选项仅在较新的objdump中可用。 ### 验证解决 执行反汇编命令后,检查输出文件开头部分是否正常(如包含正确的架构指令)且没有错误。 ### 相关问题 1. 如何确定vmlinux的准确架构信息? 2. 除了objdump,还有哪些工具可以反汇编内核? 3. 如何从内核崩溃地址定位到具体的代码行? 4. 编译内核时如何确保生成完整的调试信息? 5. 如何解决反汇编输出文件过大的问题? [^1]: 关于.relr.dyn节区的讨论:https://sourceware.org/bugzilla/show_bug.cgi?id=22923</think>### 解决 objdump 反汇编 vmlinux 的常见错误 #### 错误分析 1. **"File format not recognized"** - 通常表示 objdump 无法识别 vmlinux 的 ELF 文件格式 - 根本原因:**工具链架构不匹配**(如用 x86 工具链反汇编 ARM 内核) 2. **"don't know how to handle section .relr.dyn"** - 表示 objdump 版本过旧,不支持新的 ELF 节区 `.relr.dyn` - 该节区用于优化重定位(RELative Relocations),常见于较新内核[^1] --- #### 解决方案 ##### 步骤 1:验证文件格式 ```bash file vmlinux ``` 正常应显示类似: `ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked...` 若显示 `data` 或 `不可执行`,说明文件损坏或非标准 ELF 格式。 ##### 步骤 2:使用正确的交叉编译工具链 **关键:必须匹配内核编译时使用的工具链** ```bash # 查找内核编译时使用的工具链前缀 grep "CROSS_COMPILE" .config # 示例输出:CROSS_COMPILE=aarch64-linux-gnu- # 则使用: aarch64-linux-gnu-objdump -D vmlinux > dump.s ``` ##### 步骤 3:升级 binutils 解决 .relr.dyn 错误 `.relr.dyn` 需要 binutils ≥ 2.36(2021 年后版本): ```bash # 检查当前版本 objdump --version | head -1 # 升级方案(Ubuntu/Debian) sudo apt install binutils-source cd /usr/src/binutils sudo ./configure --prefix=/usr/local sudo make -j$(nproc) sudo make install # 验证新版本 /usr/local/bin/objdump --version ``` ##### 步骤 4:使用 LLVM 替代方案 ```bash # 安装 LLVM 工具链 sudo apt install llvm # 使用 llvm-objdump(对新节区支持更好) llvm-objdump -D --section=.text vmlinux > dump.txt ``` ##### 步骤 5:临时规避 .relr.dyn(不推荐) 移除问题节区(会丢失重定位信息): ```bash # 复制并修改 ELF 文件 objcopy --remove-section=.relr.dyn vmlinux vmlinux.mod objdump -D vmlinux.mod > dump.txt ``` --- #### 验证成功反汇编 检查输出文件开头: ```bash head -n 20 dump.txt ``` 正常应显示: ``` vmlinux: file format elf64-littleaarch64 Disassembly of section .text: ffff000010080000 <_text>: ffff000010080000: d53800a0 mrs x0, mpidr_el1 ffff000010080004: 92400400 and x0, x0, #0xff ... ``` --- #### 相关问题 1. 如何确定内核编译时使用的确切工具链版本? 2. 升级 binutils 后仍报错 `.relr.dyn` 该如何处理? 3. 使用 `llvm-objdump` 反汇编时如何保留调试符号? 4. 如何从反汇编结果中定位特定内核函数的地址? 5. 反汇编 ARM 内核时遇到 "unknown relocation type" 错误如何解决? [^1]: ELF .relr.dyn 节区规范说明 (binutils 2.36+) [^2]: Linux 内核 ELF 文件格式特殊性分析 [^3]: 交叉编译工具链匹配原则
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值