-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsharp_emmc_wp_clear.c
More file actions
95 lines (85 loc) · 3.54 KB
/
sharp_emmc_wp_clear.c
File metadata and controls
95 lines (85 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>
#include <errno.h>
#include <stdint.h> // For uint64_t
#include "linux/fs.h"
// ioctl.h から struct mmc_ioc_cmd と MMC_IOC_CMD を持ってくる
#include "linux/mmc/ioctl.h"
#define MMC_CLR_WRITE_PROT 29 // Opcode
#define IOCTL_FLAGS 0x49d
// Function to get partition size (example, needs implementation specific to Android)
uint64_t get_partition_size(const char *device) {
// On Linux, you might use ioctl(BLKGETSIZE64)
int fd = open(device, O_RDONLY);
if (fd < 0) {
perror("Failed to open device to get size");
return 0;
}
uint64_t size_bytes = 0;
// Note: BLKGETSIZE64 might require <linux/fs.h>
if (ioctl(fd, BLKGETSIZE64, &size_bytes) < 0) {
perror("ioctl(BLKGETSIZE64) failed");
close(fd);
return 0;
}
close(fd);
return size_bytes;
}
int main(int argc, char *argv[]) {
int fd;
struct mmc_ioc_cmd cmd;
int ret;
const char *target_device = "/dev/block/mmcblk0"; // Or a specific partition?
unsigned long wp_group_size_blocks = 16384; // From extcsd (8192 KiB / 512 B)
uint64_t total_size_bytes = 0;
unsigned long total_blocks = 0;
unsigned long current_block = 0;
// --- Get target size (optional, adjust as needed) ---
// If clearing protection for the whole device or a specific partition
// total_size_bytes = get_partition_size(target_device); // Implement this!
// Or, use a fixed large number if unsure (risky)
// Example: Clear first 1GB? (1 * 1024 * 1024 * 1024 / 512 = 2097152 blocks)
total_blocks = 2097152; // Example: Target first 1GB
printf("Targeting device: %s\n", target_device);
printf("Write Protect Group Size: %lu blocks\n", wp_group_size_blocks);
// printf("Total size: %llu bytes (%lu blocks)\n", total_size_bytes, total_blocks);
printf("Attempting to clear WP for first %lu blocks...\n", total_blocks);
// --- Open main device for ioctl ---
fd = open("/dev/block/mmcblk0", O_RDWR); // ioctl usually needs the main device
if (fd < 0) {
perror("Failed to open /dev/block/mmcblk0");
return 1;
}
// --- Loop to clear write protection ---
for (current_block = 0; current_block < total_blocks; current_block += wp_group_size_blocks) {
memset(&cmd, 0, sizeof(cmd));
cmd.write_flag = 1;
cmd.opcode = MMC_CLR_WRITE_PROT;
cmd.arg = (__u32)current_block; // Address is block number
cmd.flags = IOCTL_FLAGS;
// blksz, blocks, data_ptr are 0 for CMD29
// printf("Sending CLR_WRITE_PROT for block addr 0x%x\n", cmd.arg);
ret = ioctl(fd, MMC_IOC_CMD, &cmd);
if (ret < 0) {
fprintf(stderr, "ioctl(CLR_WRITE_PROT) failed for addr 0x%x: %s\n", cmd.arg, strerror(errno));
// Consider stopping on error?
// break;
} else {
// Optional: Check response? cmd.response[0] should contain R1 status.
// printf("Response: R1=0x%x\n", cmd.response[0]);
// Check for errors in R1 status if needed
// if (cmd.response[0] & 0xFFD98008) { // Check standard error bits
// fprintf(stderr, "Card returned error status: 0x%x for addr 0x%x\n", cmd.response[0], cmd.arg);
// }
}
// A small delay might be prudent, although R1b should handle busy signaling
usleep(1000); // 1ms delay
}
close(fd);
printf("Finished attempt to clear write protection.\n");
return 0;
}