Skip to content

Commit c154945

Browse files
committed
feat: 支持eMMC烧录
1 parent 7688d86 commit c154945

File tree

5 files changed

+278
-2
lines changed

5 files changed

+278
-2
lines changed

cskburn/src/main.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ static struct option long_options[] = {
7878
{"nand-dat1", required_argument, NULL, 0},
7979
{"nand-dat2", required_argument, NULL, 0},
8080
{"nand-dat3", required_argument, NULL, 0},
81+
{"emmc", no_argument, NULL, 0},
8182
{"ram", no_argument, NULL, 'r'},
8283
{"jump", required_argument, NULL, 0},
8384
{"chip-id", no_argument, NULL, 0},
@@ -274,6 +275,8 @@ print_help(const char *progname)
274275
LOGI(" verify all partitions after burning");
275276
LOGI(" -n, --nand");
276277
LOGI(" burn to NAND flash (CSK6 only)");
278+
LOGI(" --emmc");
279+
LOGI(" burn to eMMC (arcs only)");
277280
LOGI(" --probe-timeout <ms>");
278281
LOGI(" timeout for probing device (default: %d ms)", DEFAULT_PROBE_TIMEOUT);
279282
LOGI(" --reset-attempts <n>");
@@ -521,6 +524,9 @@ main(int argc, char **argv)
521524
} else if (strcmp(name, "read-logs") == 0) {
522525
sscanf(optarg, "%d", &options.read_logs_baud);
523526
break;
527+
} else if (strcmp(name, "emmc") == 0) {
528+
options.target = TARGET_EMMC;
529+
break;
524530
} else {
525531
print_help(argv[0]);
526532
return 0;
@@ -903,6 +909,19 @@ serial_burn(cskburn_partition_t *parts, int parts_cnt)
903909
}
904910

905911
LOGI("Detected NAND size: %" PRIu64 " MB", flash_size >> 20);
912+
} else if (options.target == TARGET_EMMC) {
913+
card_info_t card_info;
914+
915+
if ((ret = cskburn_serial_get_emmc_info(dev, &card_info)) != 0) {
916+
LOGE_RET(ret, "ERROR: Failed get eMMC info");
917+
goto err_enter;
918+
}
919+
920+
LOGD("Detected eMMC info, sctcnts: 0x%x sctsize: 0x%x erasize: 0x%x cardtype: %u",
921+
card_info.sctcnts, card_info.sctsize, card_info.erasize, card_info.cardtype);
922+
923+
flash_size = (uint64_t)card_info.sctcnts * card_info.sctsize;
924+
LOGI("Detected eMMC size: %" PRIu64 " MB", flash_size >> 20);
906925
}
907926

908927
for (int i = 0; i < options.read_count; i++) {

libcskburn_serial/include/cskburn_serial.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ typedef struct {
3535
uint8_t _reserved;
3636
} nand_config_t;
3737
#pragma pack()
38+
39+
#pragma pack(1)
40+
typedef struct {
41+
uint32_t sctcnts;
42+
uint32_t sctsize;
43+
uint32_t erasize;
44+
uint32_t cardtype;
45+
} card_info_t;
46+
#pragma pack()
47+
3848
typedef enum {
3949
CHIP_TYPE_3 = 3,
4050
CHIP_TYPE_4 = 4,
@@ -47,6 +57,7 @@ typedef enum {
4757
TARGET_FLASH = 0,
4858
TARGET_NAND = 1,
4959
TARGET_RAM = 2,
60+
TARGET_EMMC = 3,
5061
} cskburn_serial_target_t;
5162

5263
/**
@@ -59,8 +70,8 @@ typedef enum {
5970
* @retval 0 if successful
6071
* @retval -errno on other errors from serial device
6172
*/
62-
int cskburn_serial_open(
63-
cskburn_serial_device_t **dev, const char *path, cskburn_serial_chip_t chip, int32_t timeout);
73+
int cskburn_serial_open(cskburn_serial_device_t **dev, const char *path, cskburn_serial_chip_t chip,
74+
int32_t timeout);
6475

6576
/**
6677
* @brief Close CSK device
@@ -126,4 +137,5 @@ int cskburn_serial_reset(cskburn_serial_device_t *dev, uint32_t reset_delay);
126137

127138
void cskburn_serial_read_logs(cskburn_serial_device_t *dev, uint32_t baud);
128139

140+
int cskburn_serial_get_emmc_info(cskburn_serial_device_t *dev, card_info_t *info);
129141
#endif // __LIB_CSKBURN_SERIAL__

libcskburn_serial/src/cmd.c

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@
3535
#define CMD_NAND_DATA 0x22
3636
#define CMD_NAND_END 0x23
3737
#define CMD_NAND_MD5 0x24
38+
39+
#define CMD_EMMC_READ_CARD_INFO 0x41
40+
#define CMD_EMMC_BEGIN 0x42
41+
#define CMD_EMMC_DATA 0x43
42+
#define CMD_EMMC_END 0x44
43+
#define CMD_EMMC_MD5 0x45
44+
#define CMD_EMMC_READ_DATA 0x46
45+
#define CMD_EMMC_ERASE_DATA 0x47
46+
3847
#define CMD_FLASH_ERASE_CHIP 0xD0
3948
#define CMD_FLASH_ERASE_REGION 0xD1
4049
#define CMD_READ_FLASH_ID 0xF3
@@ -648,3 +657,163 @@ cmd_change_baud(cskburn_serial_device_t *dev, uint32_t baud, uint32_t old_baud)
648657

649658
return 0;
650659
}
660+
661+
int
662+
cmd_emmc_get_info(cskburn_serial_device_t *dev, card_info_t *info)
663+
{
664+
uint8_t ret_buf[STATUS_BYTES_LEN + sizeof(card_info_t)];
665+
uint16_t ret_len = 0;
666+
667+
int ret = command(dev, CMD_EMMC_READ_CARD_INFO, 0, CHECKSUM_NONE, NULL, ret_buf, &ret_len,
668+
sizeof(ret_buf), TIMEOUT_DEFAULT);
669+
670+
if (ret != 0) {
671+
return ret;
672+
}
673+
674+
if (ret_len < STATUS_BYTES_LEN) {
675+
LOGD("DEBUG: Interrupted serial read");
676+
return -EIO;
677+
}
678+
679+
if (ret_buf[0] != 0) {
680+
LOGD("DEBUG: Unexpected device response: 0x%02X", ret_buf[1]);
681+
return ret_buf[1];
682+
}
683+
684+
memcpy(info, ret_buf + STATUS_BYTES_LEN, sizeof(card_info_t));
685+
686+
return 0;
687+
}
688+
689+
int
690+
cmd_emmc_begin(cskburn_serial_device_t *dev, uint32_t size, uint32_t blocks, uint32_t block_size,
691+
uint32_t offset)
692+
{
693+
cmd_flash_begin_t *cmd = (cmd_flash_begin_t *)dev->req_cmd;
694+
memset(cmd, 0, sizeof(cmd_flash_begin_t));
695+
cmd->size = size;
696+
cmd->blocks = blocks;
697+
cmd->block_size = block_size;
698+
cmd->offset = offset;
699+
700+
return check_command(
701+
dev, CMD_EMMC_BEGIN, sizeof(cmd_flash_begin_t), CHECKSUM_NONE, NULL, TIMEOUT_DEFAULT);
702+
}
703+
704+
int
705+
cmd_emmc_block(cskburn_serial_device_t *dev, uint8_t *data, uint32_t data_len, uint32_t seq)
706+
{
707+
cmd_flash_block_t *cmd = (cmd_flash_block_t *)dev->req_cmd;
708+
memset(cmd, 0, sizeof(cmd_flash_block_t));
709+
cmd->size = data_len;
710+
cmd->seq = seq;
711+
cmd->rev1 = 0;
712+
cmd->rev2 = 0;
713+
714+
uint8_t *req_data = (uint8_t *)dev->req_cmd + sizeof(cmd_flash_block_t);
715+
memcpy(req_data, data, data_len);
716+
717+
uint32_t in_len = sizeof(cmd_flash_block_t) + data_len;
718+
719+
int ret = check_command(
720+
dev, CMD_EMMC_DATA, in_len, checksum(data, data_len), NULL, TIMEOUT_FLASH_DATA);
721+
722+
if (ret != 0) {
723+
LOGD("DEBUG: Failed writing block %d", seq);
724+
}
725+
726+
if (ret == 0x0A) {
727+
msleep(250);
728+
}
729+
730+
return ret;
731+
}
732+
733+
int
734+
cmd_emmc_finish(cskburn_serial_device_t *dev)
735+
{
736+
cmd_flash_finish_t *cmd = (cmd_flash_finish_t *)dev->req_cmd;
737+
memset(cmd, 0, sizeof(cmd_flash_finish_t));
738+
739+
return check_command(
740+
dev, CMD_EMMC_END, sizeof(uint32_t), CHECKSUM_NONE, NULL, TIMEOUT_FLASH_END);
741+
}
742+
743+
int
744+
cmd_emmc_erase_region(cskburn_serial_device_t *dev, uint32_t address, uint32_t size)
745+
{
746+
cmd_flash_erase_t *cmd = (cmd_flash_erase_t *)dev->req_cmd;
747+
memset(cmd, 0, sizeof(cmd_flash_erase_t));
748+
cmd->address = address;
749+
cmd->size = size;
750+
751+
return check_command(dev, CMD_EMMC_ERASE_DATA, sizeof(cmd_flash_erase_t), CHECKSUM_NONE, NULL,
752+
calc_timeout(size, TIMEOUT_FLASH_ERASE_PER_MB));
753+
}
754+
755+
int
756+
cmd_emmc_md5(cskburn_serial_device_t *dev, uint32_t address, uint32_t size, uint8_t *md5)
757+
{
758+
uint8_t ret_buf[STATUS_BYTES_LEN + 16];
759+
uint16_t ret_len = 0;
760+
761+
cmd_flash_md5_t *cmd = (cmd_flash_md5_t *)dev->req_cmd;
762+
memset(cmd, 0, sizeof(cmd_flash_md5_t));
763+
cmd->address = address;
764+
cmd->size = size;
765+
766+
int ret = command(dev, CMD_EMMC_MD5, sizeof(cmd_flash_md5_t), CHECKSUM_NONE, NULL, ret_buf,
767+
&ret_len, sizeof(ret_buf), calc_timeout(size, TIMEOUT_FLASH_MD5SUM_PER_MB));
768+
if (ret != 0) {
769+
return ret;
770+
}
771+
772+
if (ret_len < STATUS_BYTES_LEN) {
773+
LOGD("DEBUG: Interrupted serial read");
774+
return -EIO;
775+
}
776+
777+
if (ret_buf[0] != 0) {
778+
LOGD("DEBUG: Unexpected device response: 0x%02X", ret_buf[1]);
779+
return ret_buf[1];
780+
}
781+
782+
memcpy(md5, ret_buf + 2, 16);
783+
784+
return 0;
785+
}
786+
787+
int
788+
cmd_read_emmc(cskburn_serial_device_t *dev, uint32_t address, uint32_t size, uint8_t *data,
789+
uint32_t *data_len)
790+
{
791+
static uint8_t ret_buf[STATUS_BYTES_LEN + FLASH_READ_SIZE];
792+
uint16_t ret_len = 0;
793+
794+
cmd_read_flash_t *cmd = (cmd_read_flash_t *)dev->req_cmd;
795+
memset(cmd, 0, sizeof(cmd_read_flash_t));
796+
cmd->address = address;
797+
cmd->size = size;
798+
799+
int ret = command(dev, CMD_EMMC_READ_DATA, sizeof(cmd_read_flash_t), CHECKSUM_NONE, NULL,
800+
ret_buf, &ret_len, sizeof(ret_buf), TIMEOUT_FLASH_DATA);
801+
if (ret != 0) {
802+
return ret;
803+
}
804+
805+
if (ret_len < STATUS_BYTES_LEN) {
806+
LOGD("DEBUG: Interrupted serial read");
807+
return -EIO;
808+
}
809+
810+
if (ret_buf[0] != 0) {
811+
LOGD("DEBUG: Unexpected device response: 0x%02X", ret_buf[1]);
812+
return ret_buf[1];
813+
}
814+
815+
*data_len = ret_len - STATUS_BYTES_LEN;
816+
memcpy(data, ret_buf + STATUS_BYTES_LEN, *data_len);
817+
818+
return 0;
819+
}

libcskburn_serial/src/cmd.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,14 @@ int cmd_read_flash(cskburn_serial_device_t *dev, uint32_t address, uint32_t size
7979

8080
int cmd_change_baud(cskburn_serial_device_t *dev, uint32_t baud, uint32_t old_baud);
8181

82+
int cmd_emmc_get_info(cskburn_serial_device_t *dev, card_info_t *info);
83+
int cmd_emmc_begin(cskburn_serial_device_t *dev, uint32_t size, uint32_t blocks,
84+
uint32_t block_size, uint32_t offset);
85+
int cmd_emmc_block(cskburn_serial_device_t *dev, uint8_t *data, uint32_t data_len, uint32_t seq);
86+
int cmd_emmc_finish(cskburn_serial_device_t *dev);
87+
int cmd_emmc_erase_region(cskburn_serial_device_t *dev, uint32_t address, uint32_t size);
88+
int cmd_emmc_md5(cskburn_serial_device_t *dev, uint32_t address, uint32_t size, uint8_t *md5);
89+
int cmd_read_emmc(cskburn_serial_device_t *dev, uint32_t address, uint32_t size, uint8_t *data,
90+
uint32_t *data_len);
91+
8292
#endif // __LIB_CSKBURN_SERIAL_CMD__

libcskburn_serial/src/core.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@ cskburn_serial_write(cskburn_serial_device_t *dev, cskburn_serial_target_t targe
337337
if ((ret = cmd_mem_begin(dev, reader->size, blocks, FLASH_BLOCK_SIZE, addr) != 0)) {
338338
return ret;
339339
}
340+
} else if (target == TARGET_EMMC) {
341+
if ((ret = cmd_emmc_begin(dev, reader->size, blocks, FLASH_BLOCK_SIZE, addr) != 0)) {
342+
return ret;
343+
}
340344
} else {
341345
LOGE("ERROR: Unsupported target: %d", target);
342346
return -EINVAL;
@@ -369,6 +373,10 @@ cskburn_serial_write(cskburn_serial_device_t *dev, cskburn_serial_target_t targe
369373
if ((ret = cmd_mem_block(dev, buffer, length, i)) != 0) {
370374
return ret;
371375
}
376+
} else if (target == TARGET_EMMC) {
377+
if ((ret = cmd_emmc_block(dev, buffer, length, i)) != 0) {
378+
return ret;
379+
}
372380
}
373381

374382
i++;
@@ -390,6 +398,10 @@ cskburn_serial_write(cskburn_serial_device_t *dev, cskburn_serial_target_t targe
390398
if ((ret = cmd_mem_finish(dev, jump ? OPTION_JUMP : OPTION_RUN, jump)) != 0) {
391399
return ret;
392400
}
401+
} else if (target == TARGET_EMMC) {
402+
if ((ret = cmd_emmc_finish(dev)) != 0) {
403+
return ret;
404+
}
393405
}
394406

395407
uint64_t t2 = time_monotonic();
@@ -437,6 +449,26 @@ cskburn_serial_read(cskburn_serial_device_t *dev, cskburn_serial_target_t target
437449

438450
offset += to_write;
439451

452+
if (on_progress != NULL) {
453+
on_progress(offset, size);
454+
}
455+
} else if (target == TARGET_EMMC) {
456+
if ((ret = cmd_read_emmc(dev, addr + offset, max_read_size, buffer, &read_size)) != 0) {
457+
return ret;
458+
}
459+
460+
if (offset + read_size > size) {
461+
to_write = size - offset;
462+
} else {
463+
to_write = read_size;
464+
}
465+
466+
if (writer->write(writer, buffer, to_write) != to_write) {
467+
return -EIO;
468+
}
469+
470+
offset += to_write;
471+
440472
if (on_progress != NULL) {
441473
on_progress(offset, size);
442474
}
@@ -494,6 +526,17 @@ cskburn_serial_erase(
494526
} else if (target == TARGET_NAND) {
495527
LOGE("ERROR: Erasing is not supported for NAND yet");
496528
return -ENOTSUP;
529+
} else if (target == TARGET_EMMC) {
530+
uint64_t t1 = time_monotonic();
531+
532+
if ((ret = cmd_emmc_erase_region(dev, addr, size)) != 0) {
533+
return ret;
534+
}
535+
536+
uint64_t t2 = time_monotonic();
537+
print_time_spent_with_speed("Erasing", t1, t2, size);
538+
539+
return 0;
497540
}
498541

499542
LOGE("ERROR: Unsupported target: %d", target);
@@ -527,6 +570,17 @@ cskburn_serial_verify(cskburn_serial_device_t *dev, cskburn_serial_target_t targ
527570
uint64_t t2 = time_monotonic();
528571
print_time_spent_with_speed("Verifying", t1, t2, size);
529572

573+
return 0;
574+
} else if (target == TARGET_EMMC) {
575+
uint64_t t1 = time_monotonic();
576+
577+
if ((ret = cmd_emmc_md5(dev, addr, size, md5)) != 0) {
578+
return ret;
579+
}
580+
581+
uint64_t t2 = time_monotonic();
582+
print_time_spent_with_speed("Verifying", t1, t2, size);
583+
530584
return 0;
531585
}
532586

@@ -609,3 +663,15 @@ cskburn_serial_read_logs(cskburn_serial_device_t *dev, uint32_t baud)
609663
fflush(stdout);
610664
}
611665
}
666+
667+
int
668+
cskburn_serial_get_emmc_info(cskburn_serial_device_t *dev, card_info_t *info)
669+
{
670+
int ret;
671+
672+
if ((ret = cmd_emmc_get_info(dev, info)) != 0) {
673+
return ret;
674+
}
675+
676+
return 0;
677+
}

0 commit comments

Comments
 (0)