操作系统开发 - 一個改MBR裏分区表的bash腳本

一个改MBR里分区表的bash脚本, 它有两个用法:


1) 把分区表打出来


./utils/pt -l hd.img


2) 修改分区表


./utils/pt -c hd.img 3 status=80 chs=11,22,33 partitionType=5f lastchs=12,34,56 lba=a100 noOfSector=0


The above command line will modify the 4th partition table (first one is 0), change the status to 0x80, chs to 11,22,33 and etc.



#!/bin/bash

function printHelp(){
	echo "Usage : "
	echo "  ./pt <file name>"
	echo
	echo "  -l : list partition table"
	echo "  -l n : list n'th partition entry"
}

function writeByte(){
	echo -ne \\x$1 | dd conv=notrunc bs=1 count=1 of=$3 seek=$2 &> /dev/null
}


function writeInt(){
	echo -ne \\x00 | dd conv=notrunc bs=1 count=1 of=$3 seek=$2 &> /dev/null
	echo -ne \\x00 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+1)) &> /dev/null
	echo -ne \\x00 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+2)) &> /dev/null
	echo -ne \\x00 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+3)) &> /dev/null

	temp=$1
	while [ ${#temp} -lt 8 ]; do 
		temp="0"$temp
	done

	b1=`echo $temp| cut -c7-8`
	b2=`echo $temp| cut -c5-6`
	b3=`echo $temp| cut -c3-4`
	b4=`echo $temp| cut -c1-2`
	echo -ne \\x$b1 | dd conv=notrunc bs=1 count=1 of=$3 seek=$2 &> /dev/null
	echo -ne \\x$b2 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+1)) &> /dev/null
	echo -ne \\x$b3 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+2)) &> /dev/null
	echo -ne \\x$b4 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+3)) &> /dev/null
}

function getByte(){
	start=$(($2+1))
	let b=0x`cat $1 | head -c $start|tail -c 1|od -An -t x1 | tr -d '  '`
	echo $b
}

function getInt(){
	start=$(($2+4))
	let b=0x`cat $1 | head -c $start|tail -c 4|od -An -t x4 | tail -1 | tr -d ' '`
	echo $b
}

function dumpPartitionEntry(){
	printf "status\t\t: %x\n" $1
	printf "CHS\t\t: %x %x %x\n" $2 $3 $4
	printf "partition type\t: %x\n" $5
	printf "last CHS\t: %x %x %x\n" $6 $7 $8
	printf "lba\t\t: %x\n" $9
	printf "no of sectors\t: %d\n" ${10}
}

#Bad arguments
if [ $# -eq 0 ]; then
	printHelp
	exit 1
fi

ARGS=`getopt -o "l,c" -l "help" \
      -n "getopt.sh" -- "$@"`

while true;
do
	case "$1" in
		-l)
			if [ -z "$2" ]; then
				echo "parameter error"
				exit;
			fi
			if [ -z "$3" ]; then
				filename=$2
				offset=446
				for i in {1..4}
				do
				status1=`getByte "$filename" $((offset+0))`
				c1=`getByte "$filename" $((offset+1))`
				h1=`getByte "$filename" $((offset+2))`
				s1=`getByte "$filename" $((offset+3))`
				type1=`getByte "$filename" $((offset+4))`
				lastC1=`getByte "$filename" $((offset+5))`
				lastH1=`getByte "$filename" $((offset+6))`
				lastS1=`getByte "$filename" $((offset+7))`
				lba1=`getInt "$filename" $((offset+8))`
				noOfSector1=`getInt "$filename" $((offset+12))`
				dumpPartitionEntry $status1 $c1 $h1 $s1 $type1 $lastC1 $lastH1 $lastS1 $lba1 $noOfSector1
				echo
				offset=$(($offset+16))
				done
				exit;
			else
				echo "list "$2
			fi
			shift;;

		-c)
			if [ -z "$3" ]; then
				echo "parameter error"
				exit;
			fi
			if [ $3 -gt 3 ]; then
				echo "partition no cannot larger than 3"
				exit;
			fi
			filename=$2
			for temp in $4 $5 $6 $7 $8 $9
			do
				command=`echo $temp | cut -d= -f1`
				para=`echo $temp| cut -d= -f2`
				if [ $command = "status" ]; then
					offset=$((446+16*$3))
					writeByte $para $offset $filename
				elif [ $command = "chs" ]; then
					offset1=$((447+16*$3+0))
					offset2=$((447+16*$3+1))
					offset3=$((447+16*$3+2))
					c=`echo $para | cut -d, -f1`
					h=`echo $para | cut -d, -f2`
					s=`echo $para | cut -d, -f3`
					writeByte $c $offset1 $filename
					writeByte $h $offset2 $filename
					writeByte $s $offset3 $filename
					command=`echo $temp | cut -d= -f1`
				elif [ $command = "partitionType" ]; then
					offset=$((450+16*$3))
					writeByte $para $offset $filename
				elif [ $command = "lastchs" ]; then
					offset1=$((451+16*$3+0))
					offset2=$((451+16*$3+1))
					offset3=$((451+16*$3+2))
					c=`echo $para | cut -d, -f1`
					h=`echo $para | cut -d, -f2`
					s=`echo $para | cut -d, -f3`
					writeByte $c $offset1 $filename
					writeByte $h $offset2 $filename
					writeByte $s $offset3 $filename
				elif [ $command = "lba" ]; then
					offset=$((454+16*$3))
					writeInt $para $offset $filename
				elif [ $command = "noOfSector" ]; then
					offset=$((458+16*$3))
					writeInt $para $offset $filename
				else
					echo "you have specific wrong command after -c"
					exit;
				fi				
			done
			exit;
			shift;;

		--help)
			printHelp
			shift;;

		*)
			echo "wrong command : "
			shift
			break;;
			esac
done


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值