Shell 二进制转16进制(openwrt)

由于OpenWRT系统不支持bc、obase等命令,本文介绍了一种在该环境下手动将二进制数转换为十六进制数的方法,通过Shell脚本逐位解析二进制字符串并进行转换。

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

因为openwrt不支持bc,obase,$(2#0xff)等命令(系统被裁减等原因),所以需要手动去把2进制转换成16进制,shell code如下:

#!/bin/sh

a="00010010001101000101011001111000"
start=1
end=4
debug_level="0x"
for i in `seq 1 8`;do
  echo "***i:$i****"
  b=`echo $a|cut -c $start-$end`
  b1=`echo $b|cut -c 1`
  [ $b1 = 1 ] && v1=8 || v1=0
  b2=`echo $b|cut -c 2`
  [ $b2 = 1 ] && v2=4 || v2=0
  b3=`echo $b|cut -c 3`
  [ $b3 = 1 ] && v3=2 || v3=0
  b4=`echo $b|cut -c 4`
  [ $b4 = 1 ] && v4=1 || v4=0
  val=`printf %x $(($v1+$v2+$v3+$v4))`
  echo "**val:$val***********">/dev/console
  debug_level="$debug_level$val"
  echo "debug level:$debug_level"
  start=$((start+4))
  end=$((end+4))
 done

 

<think>我们首先将已修复的img镜像换为raw格式(实际上img已经是raw格式),然后创建对应的VMDK描述文件,使其指向这个raw文件(作为-flat.vmdk数据文件)。注意:ESXi要求数据文件必须命名为*-flat.vmdk,并且描述文件与数据文件在同一目录。 步骤: 1. 确保当前目录下有img文件(例如:openwrt-23.05.3-x86-64-generic-ext4-combined-efi.img) 2. 将img文件重命名为openwrt-flat.vmdk(这就是数据文件) 3. 创建一个VMDK描述文件(例如:openwrt.vmdk),描述文件将指向openwrt-flat.vmdk 但是,直接重命名img为-flat.vmdk并创建描述文件,ESXi可能不识别,因为img文件是原始磁盘镜像,而-flat.vmdk也是原始格式,所以我们需要创建正确的描述文件。 以下是具体步骤: 步骤1:重命名镜像文件 将 openwrt-23.05.3-x86-64-generic-ext4-combined-efi.img 重命名为 openwrt-flat.vmdk 步骤2:创建描述文件(openwrt.vmdk) 描述文件的内容需要根据实际磁盘大小和参数来写。 我们可以通过以下命令获取原始img文件的大小(字节数): stat -c %s openwrt-flat.vmdk 假设我们得到的大小为S字节,那么描述文件中的RW值应该是S/512(即扇区数)。因为每个扇区512字节。 但是,我们也可以使用vmkfstools工具来换,但这里我们手动创建描述文件。 描述文件模板如下(注意:createType为"monolithicFlat"): 注意:以下CID和UUID需要生成,但可以使用随机值。 手动创建描述文件示例: ``` # Disk DescriptorFile version=1 CID=fffffffd parentCID=ffffffff createType="monolithicFlat" # Extent description RW <sectors> FLAT "openwrt-flat.vmdk" 0 # The Disk Data Base ddb.adapterType = "lsilogic" ddb.geometry.cylinders = "16383" ddb.geometry.heads = "16" ddb.geometry.sectors = "63" ddb.virtualHWVersion = "15" ddb.uuid.image="<随机UUID>" ddb.uuid.parent="00000000-0000-0000-0000-000000000000" ``` 其中: - RW后面的<sectors>:用实际文件大小除以512得到(取整数)。 - CID:可以随机生成一个8位十六进制数(例如:`printf "%08x" $RANDOM`),但注意不要与现有冲突。 - ddb.uuid.image:使用uuidgen生成(如果没有,可以用随机值,但ESXi可能会在启动时重新生成)。 然而,更简单的方法是使用vmkfstools工具来修复,但这里我们手动创建。 步骤3:将这两个文件(openwrt.vmdk和openwrt-flat.vmdk)放在同一目录,然后在ESXi中创建虚拟机,选择已有磁盘,指向openwrt.vmdk。 但是,为了避免手动计算的麻烦,我们可以使用qemu-img换一次(虽然不必要),或者使用vmkfstools工具来换。 替代方案(推荐):使用vmkfstools换 实际上,我们可以跳过中间步骤,直接将img文件换为ESXi可用的VMDK(包含描述文件和-flat.vmdk数据文件)。但是,用户要求先raw(即img)再-flat.vmdk格式。 注意:img文件本身就是raw格式,所以我们不需要换,直接重命名即可作为-flat.vmdk数据文件。 因此,我们按照以下步骤: 1. 将img文件重命名为数据文件(openwrt-flat.vmdk) 2. 创建描述文件(openwrt.vmdk),内容如下(注意根据实际大小调整): 假设我们通过命令获取到文件大小: size=$(stat -c %s openwrt-flat.vmdk) sectors=$((size/512)) 然后,用这个sectors替换模板中的<sectors>。 同时,生成CID(8位十六进制)和UUID(32位十六进制,格式为8-4-4-4-12)。 示例脚本(在Linux环境下运行,生成描述文件): ```bash #!/bin/bash flat_file="openwrt-flat.vmdk" descriptor="openwrt.vmdk" # 获取文件大小(字节) size=$(stat -c %s "$flat_file") sectors=$((size/512)) # 生成随机的CID(8位十六进制) CID=$(printf "%08x" $RANDOM) # 生成随机的UUID(32位十六进制,格式为8-4-4-4-12) UUID=$(uuidgen) # 写入描述文件 cat > "$descriptor" <<EOF # Disk DescriptorFile version=1 CID=${CID} parentCID=ffffffff createType="monolithicFlat" # Extent description RW ${sectors} FLAT "${flat_file}" 0 # The Disk Data Base ddb.adapterType = "lsilogic" ddb.geometry.cylinders = "16383" ddb.geometry.heads = "16" ddb.geometry.sectors = "63" ddb.virtualHWVersion = "15" ddb.uuid.image="${UUID}" ddb.uuid.parent="00000000-0000-0000-0000-000000000000" EOF ``` 将上述脚本保存为create_descriptor.sh,与openwrt-flat.vmdk放在同一目录,然后运行即可生成描述文件openwrt.vmdk。 步骤4:在ESXi中创建虚拟机,使用现有磁盘,选择openwrt.vmdk。 注意:如果ESXi报告找不到文件,请确保两个文件在同一目录,并且权限正确(ESXi可读)。 另外,也可以使用vmkfstools工具来修复关联(如果ESXi不认): vmkfstools -r openwrt.vmdk 但是,如果严格按照上述步骤,应该可以正常使用。 重要:在ESXi中,虚拟机的硬件版本要匹配(这里我们写的是15,对应ESXi 6.7)。如果使用更高版本的ESXi,可能需要调整virtualHWVersion。 如果换后启动有问题,可能需要检查分区表是否真的修复,以及引导设置(BIOS/UEFI)是否正确。 因此,我们给出两种方法: 方法一:手动创建描述文件(如上) 方法二:使用vmkfstools换(但会复制数据,不是直接利用原文件) 方法二(使用vmkfstools)的步骤(如果不想手动创建描述文件,但会生成一个全新的-flat.vmdk,原img文件不会改变): 1. 将img文件上传到ESXi存储 2. 使用vmkfstools换: vmkfstools -i openwrt.img -d thin openwrt.vmdk 这样会生成两个文件:openwrt.vmdk(描述文件)和openwrt-flat.vmdk(数据文件) 但是用户要求“为raw格式,再为-flat.vmdk格式”,而img已经是raw,所以方法一更直接(不复制数据,直接重命名并创建描述文件)。 根据用户要求,我们使用方法一。 总结步骤: 1. 将img文件重命名为openwrt-flat.vmdk 2. 计算img文件大小(字节),除以512得到扇区数 3. 生成随机的CID和UUID 4. 创建描述文件openwrt.vmdk(内容如上模板) 5. 将两个文件放在同一目录,在ESXi中创建虚拟机时使用此描述文件。 注意:如果原始img文件是稀疏文件(sparse file),那么直接重命名可能导致ESXi无法识别(因为ESXi要求-flat.vmdk是实际占用空间的非稀疏文件)。所以,如果是稀疏文件,需要先换为非稀疏: dd if=openwrt.img of=openwrt-full.img bs=1M 然后使用openwrt-full.img 如何检查是否为稀疏文件:用`du -h openwrt.img`和`ls -lh openwrt.img`对比,如果du显示的大小远小于ls显示的大小,则是稀疏文件。 如果原始img文件是稀疏文件,那么我们需要先填充(用dd)成非稀疏文件,然后再重命名为-flat.vmdk。 因此,完整步骤包括检查稀疏性并处理。 考虑到用户已经修复了分区表,我们假设img文件是正常的非稀疏文件(因为官方提供的img通常是非稀疏的)。 所以,我们按照上述步骤执行即可。 最后,在ESXi中创建虚拟机时,注意选择与描述文件中一致的适配器类型(这里是lsilogic),以及硬件版本(15)。 如果启动时遇到问题,可以尝试更改适配器类型(如改为sata或ide)或检查引导方式(BIOS/UEFI)。 以上。</think>以下是完整的换流程,将修复后的 `openwrt-23.05.3-x86-64-generic-ext4-combined-efi.img` 换为 ESXi 可用的 `-flat.vmdk` 格式: ### 完整换步骤(基于已修复的IMG文件) #### 步骤1:验证并准备原始IMG文件 ```bash # 确认文件完整性 qemu-img info openwrt-23.05.3-x86-64-generic-ext4-combined-efi.img # 应显示:file format: raw # 检查分区表 fdisk -lu openwrt-23.05.3-x86-64-generic-ext4-combined-efi.img # 应显示两个分区:EFI系统分区 + Linux根分区 # 获取精确字节大小 IMG_SIZE=$(stat -c %s openwrt-23.05.3-x86-64-generic-ext4-combined-efi.img) ``` #### 步骤2:换为RAW格式(可选步骤) ```bash # 如果IMG不是raw格式才需要换(通常OpenWRT官方IMG已是raw) qemu-img convert -f raw -O raw \ openwrt-23.05.3-x86-64-generic-ext4-combined-efi.img \ openwrt.raw ``` #### 步骤3:创建ESXi兼容的VMDK结构 ```bash # 1. 创建-flat.vmdk数据文件(直接重命名) mv openwrt.raw openwrt-flat.vmdk # 2. 创建VMDK描述文件 cat <<EOF > openwrt.vmdk # Disk DescriptorFile version=1 CID=$(printf "%08x" $RANDOM) # 随机生成8位CID parentCID=ffffffff createType="monolithicFlat" # Extent description RW $((IMG_SIZE/512)) FLAT "openwrt-flat.vmdk" 0 # Disk Data Base ddb.adapterType = "lsilogic" ddb.geometry.cylinders = "16383" ddb.geometry.heads = "16" ddb.geometry.sectors = "63" ddb.virtualHWVersion = "15" ddb.uuid.image="$(uuidgen)" ddb.uuid.parent="00000000-0000-0000-0000-000000000000" EOF ``` #### 步骤4:上传到ESXi并验证 ```bash # 通过SCP上传两个文件到ESXi存储 scp openwrt.vmdk openwrt-flat.vmdk root@esxi_host:/vmfs/volumes/datastore1/OpenWRT/ # SSH登录ESXi验证 vmkfstools -e openwrt.vmdk # 应输出:Disk is a single extent disk # 修复权限 chmod 777 /vmfs/volumes/datastore1/OpenWRT/openwrt-flat.vmdk ``` #### 步骤5:创建虚拟机配置文件 ```bash # 创建VMX配置文件 cat <<EOF > OpenWRT.vmx .encoding = "UTF-8" config.version = "8" virtualHW.version = "15" displayName = "OpenWRT" firmware = "efi" memSize = "512" numvcpus = "1" # 磁盘配置 scsi0.present = "TRUE" scsi0.virtualDev = "lsilogic" scsi0:0.present = "TRUE" scsi0:0.fileName = "openwrt.vmdk" scsi0:0.deviceType = "scsi-hardDisk" # 网络配置 ethernet0.present = "TRUE" ethernet0.virtualDev = "vmxnet3" ethernet0.networkName = "VM Network" EOF # 注册虚拟机 vim-cmd solo/registervm /vmfs/volumes/datastore1/OpenWRT/OpenWRT.vmx ``` ### 关键参数说明 | 参数 | 值 | 说明 | |------|----|------| | `createType="monolithicFlat"` | 必需 | 声明单文件平面结构 | | `RW $((IMG_SIZE/512))` | 自动计算 | 扇区数=文件大小/512 | | `ddb.adapterType` | "lsilogic" | OpenWRT兼容性最好的控制器 | | `firmware = "efi"` | 必需 | 匹配EFI引导的官方镜像 | | `virtualDev = "vmxnet3"` | 推荐 | ESXi最佳性能网卡驱动 | ### 验证命令清单 ```bash # 1. 检查磁盘关联 grep "FLAT" openwrt.vmdk | awk '{print $4}' # 应输出: "openwrt-flat.vmdk" # 2. 验证分区表 hexdump -C -s 446 -n 64 openwrt-flat.vmdk # 应显示有效的分区表签名(55 AA) # 3. 启动测试 vim-cmd vmsvc/power.on $(vim-cmd vmsvc/getallvms | grep OpenWRT | awk '{print $1}') tail -f /var/log/vmware/hostd.log | grep 'OpenWRT' ``` ### 故障处理 **问题:启动时卡在EFI Shell** ```bash # 解决方案:重置NVRAM rm /vmfs/volumes/datastore1/OpenWRT/OpenWRT.nvram ``` **问题:显示"Invalid partition table"** ```bash # 重新修复分区表 gparted /vmfs/volumes/datastore1/OpenWRT/openwrt-flat.vmdk # 选择"Device" → "Create Partition Table" → "gpt" ``` **问题:ESXi报告"Invalid CID"** ```bash # 更新CID并重新注册 sed -i "s/CID=.*/CID=$(printf "%08x" $RANDOM)/" openwrt.vmdk vim-cmd solo/unregistervm /vmfs/volumes/datastore1/OpenWRT vim-cmd solo/registervm /vmfs/volumes/datastore1/OpenWRT/OpenWRT.vmx ``` > **性能提示**:首次启动后执行磁盘优化: > ```bash > ssh root@openwrt "fstrim -a" > vmkfstools --punchzero openwrt.vmdk > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值