Remove Meizu M3/M6SL/M6SP and Samsung YP-S3 ports

These targets haven't seen any changes since 2008-09
have bitrotted to the point they don't compile anymore.
With only internal NAND flash for storage which doesn't
seem to have ever been accessible from Rockbox, they've
never been usable and there's probably not much point
keeping them around any more.

Change-Id: I2fc63da20682b439126672065ae013044cb2d1c4
This commit is contained in:
Aidan MacDonald 2026-02-03 16:16:36 +00:00
parent 19fe7a4915
commit 1a33d7990a
60 changed files with 38 additions and 5990 deletions

View file

@ -1,11 +0,0 @@
CFLAGS = -W -Wall
LDFLAGS = -lusb
all: meizu_dfu
meizu_dfu: meizu_dfu.c
.PHONY: clean
clean:
rm -f meizu_dfu

View file

@ -1,9 +0,0 @@
Meizu DFU tool for Linux
This tool can restore the firmware on M3, M6 SP, M6 TP and M6 SL.
It can also run a single provided file from RAM.
Notes:
1. SST39VF800.dfu is taken from the official dfu tool provided by Meizu.
2. updateNAND_BE_070831.dfu is taken from the unofficial dfu tool for M6 SL.
3. To compile, just run `make'.

View file

@ -1,441 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by William Poetra Yoga Hadisoeseno and Frank Gevaerts
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <libgen.h>
#include <arpa/inet.h>
#include <usb.h>
#define bswap_16(value) \
((((value) & 0xff) << 8) | ((value) >> 8))
#define bswap_32(value) \
(((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
(uint32_t)bswap_16((uint16_t)((value) >> 16)))
#define host_to_le32(_x) bswap_32(htonl(_x))
#define host_to_le16(_x) bswap_16(htons(_x))
void usage()
{
fprintf(stderr, "usage: meizu_dfu m3 [SST39VF800.dfu] <M3.EBN>\n");
fprintf(stderr, " meizu_dfu m6 [SST39VF800.dfu] <M6.EBN>\n");
fprintf(stderr, " meizu_dfu m6sl [updateNAND_BE_070831.dfu] <M6SL.EBN>\n");
exit(1);
}
uint32_t crc32(char *data, int len, uint32_t poly, uint32_t init)
{
uint32_t crc_table[256];
uint32_t crc, t;
int i, j;
// generate the table
for (i = 0; i < 256; ++i) {
t = i;
for (j = 0; j < 8; ++j)
if (t & 1)
t = (t >> 1) ^ poly;
else
t >>= 1;
crc_table[i] = t;
}
// calculate the crc
crc = init;
for (i = 0; i < len; ++i)
crc = (crc >> 8) ^ crc_table[(crc^data[i]) & 0xff];
return crc;
}
typedef struct {
char *name;
char *data;
int len;
} image_data_t;
typedef struct {
int delay;
int pre_off;
uint32_t pre_sig;
uint16_t suf_dev;
uint16_t suf_prod;
uint16_t suf_ven;
uint16_t suf_dfu;
char suf_sig[3];
uint8_t suf_len;
} image_attr_t;
#define BLOCK_SIZE 2048
#define DFU_TIMEOUT 0xa000
#define DFU_CRC_POLY 0xedb88320
#define DFU_INIT_CRC 0xffffffff
#define USB_VID_SAMSUNG 0x0419
#define USB_PID_M6SL 0x0145
#define USB_PID_M3_M6 0x0141
void init_img(image_data_t *img, const char *filename, image_attr_t *attr)
{
int fd, len, i, readlen;
struct stat statbuf;
char buf[BLOCK_SIZE];
uint32_t dfu_crc;
uint32_t le_len;
printf("Reading %s...", filename);
if (stat(filename, &statbuf) < 0) {
printf("\nCould not stat file, exiting.\n");
exit(1);
}
len = statbuf.st_size;
img->name = basename(strdup(filename));
img->data = malloc(len + 16);
img->len = len + 16;
fd = open(filename, O_RDONLY);
for (i = 0; i < len; i += BLOCK_SIZE) {
readlen = ((len - i) < BLOCK_SIZE) ? (len - i) : BLOCK_SIZE;
read(fd, buf, readlen);
memcpy(img->data + i, buf, readlen);
}
close(fd);
le_len = host_to_le32(img->len);
// patch the data size in after the signature
memcpy(img->data + attr->pre_off + 4, &le_len, 4);
/* convert to little endian */
attr->suf_dev = host_to_le16(attr->suf_dev);
attr->suf_prod = host_to_le16(attr->suf_prod);
attr->suf_ven = host_to_le16(attr->suf_ven);
attr->suf_dfu = host_to_le16(attr->suf_dfu);
// append the suffix (excluding the checksum)
memcpy(img->data + len, &attr->suf_dev, 2);
memcpy(img->data + len + 2, &attr->suf_prod, 2);
memcpy(img->data + len + 4, &attr->suf_ven, 2);
memcpy(img->data + len + 6, &attr->suf_dfu, 2);
memcpy(img->data + len + 8, &attr->suf_sig, 3);
memcpy(img->data + len + 11, &attr->suf_len, 1);
dfu_crc = host_to_le32(crc32(img->data, len + 12, DFU_CRC_POLY, DFU_INIT_CRC));
memcpy(img->data + len + 12, &dfu_crc, 4);
#if 0
FILE *f = fopen(img->name, "w");
fwrite(img->data, len + 16, 1, f);
fclose(f);
#endif
printf("OK\n");
}
usb_dev_handle *usb_dev_open(uint16_t dfu_vid, uint16_t dfu_pid)
{
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *device;
printf("USB initialization...");
usb_init();
usb_find_busses();
usb_find_devices();
for (bus = usb_get_busses(); bus != NULL; bus = bus->next)
for (dev = bus->devices; dev != NULL; dev = dev->next)
if (dev->descriptor.idVendor == dfu_vid
&& dev->descriptor.idProduct == dfu_pid)
goto found;
printf("\nNo device found, exiting.\n");
exit(1);
found:
printf(" Device found.\n");
device = usb_open(dev);
usb_claim_interface(device, 0);
return device;
}
void usb_mimic_windows(usb_dev_handle *device)
{
char data[1024];
usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0009, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x001b, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0040, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0009, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0303, 0x0409, data, 0x00ff, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x00ff, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0302, 0x0409, data, 0x00ff, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0302, 0x0409, data, 0x00ff, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, DFU_TIMEOUT);
usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0209, DFU_TIMEOUT);
}
void usb_dev_close(usb_dev_handle *device)
{
printf("Releasing interface...");
usb_release_interface(device, 0);
printf(" OK\n");
}
enum DFU_REQUEST {
DFU_DETACH = 0,
DFU_DOWNLOAD,
DFU_UPLOAD,
DFU_GETSTATUS,
DFU_CLRSTATUS,
DFU_GETSTATE,
DFU_ABORT
};
void get_cpu(usb_dev_handle *device)
{
char data[64];
int req_out_if = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
int len;
printf("GET CPU");
// check for "S5L8700 Rev.1"
len = usb_control_msg(device, req_out_if, 0xff, 0x0002, 0, data, 0x003f, DFU_TIMEOUT);
if (len < 0) {
printf("\nError trying to get CPU model, exiting.\n");
exit(1);
}
memset(data + len, 0, 64 - len);
printf(", got: %s\n", data);
}
void send_file(usb_dev_handle *device, image_data_t *img)
{
char dfu_ret[6];
char *data;
int req_out_if = USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
int req_in_if = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
int len, idx, writelen, i;
printf("Sending %s... ", img->name);
len = img->len;
data = img->data;
// loop for the file
for (i = 0, idx = 0; i < len; i += BLOCK_SIZE, ++idx) {
writelen = ((len - i) < BLOCK_SIZE) ? (len - i) : BLOCK_SIZE;
usb_control_msg(device, req_out_if, DFU_DOWNLOAD, idx, 0, data + i, writelen, DFU_TIMEOUT);
dfu_ret[4] = 0x00;
while (dfu_ret[4] != 0x05)
usb_control_msg(device, req_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, DFU_TIMEOUT);
printf("#");
}
usb_control_msg(device, req_out_if, DFU_DOWNLOAD, idx, 0, NULL, 0, DFU_TIMEOUT);
dfu_ret[4] = 0x00;
while (dfu_ret[4] != 0x07)
usb_control_msg(device, req_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, DFU_TIMEOUT);
printf(" OK\n");
}
void clear_status(usb_dev_handle *device)
{
char dfu_ret[6];
int usb_in_if = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
int usb_out_if = USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
printf("Clearing status...");
dfu_ret[4] = 0x00;
while (dfu_ret[4] != 0x08)
usb_control_msg(device, usb_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, DFU_TIMEOUT);
usb_control_msg(device, usb_out_if, DFU_CLRSTATUS, 0, 0, NULL, 0, DFU_TIMEOUT);
printf(" OK\n");
}
void dfu_detach(usb_dev_handle *device)
{
char usb_ret[4];
int usb_in_oth = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_OTHER;
int usb_out_oth = USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER;
printf("Detaching...");
usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
usb_control_msg(device, usb_out_oth, DFU_DOWNLOAD, 0x0010, 3, NULL, 0, DFU_TIMEOUT);
usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
printf(" OK\n");
}
void dfu_m3_m6(char *file1, char *file2)
{
image_data_t img1, img2;
image_attr_t attr1, attr2;
usb_dev_handle *device;
attr1.delay = 1000;
attr1.pre_off = 0x20;
attr1.pre_sig = 0x44465543;
attr1.suf_dev = 0x0100;
attr1.suf_prod = 0x0140;
attr1.suf_ven = 0x0419;
attr1.suf_dfu = 0x0100;
memcpy(attr1.suf_sig, "RON", 3);
attr1.suf_len = 0x10;
init_img(&img1, file1, &attr1);
if (file2) {
attr2.delay = 1000;
attr2.pre_off = 0x20;
attr2.pre_sig = 0x44465543;
attr2.suf_dev = 0x0100;
attr2.suf_prod = 0x0140;
attr2.suf_ven = 0x0419;
attr2.suf_dfu = 0x0100;
memcpy(attr2.suf_sig, "UFD", 3);
attr2.suf_len = 0x10;
init_img(&img2, file2, &attr2);
}
device = usb_dev_open(USB_VID_SAMSUNG, USB_PID_M3_M6);
// usb_mimic_windows();
get_cpu(device);
get_cpu(device);
send_file(device, &img1);
if (file2) {
printf("Wait a sec (literally)...");
sleep(1);
printf(" OK\n");
clear_status(device);
get_cpu(device);
send_file(device, &img2);
dfu_detach(device);
}
usb_dev_close(device);
}
void dfu_m6sl(char *file1, char *file2)
{
image_data_t img1, img2;
image_attr_t attr1, attr2;
usb_dev_handle *device;
attr1.delay = 1000;
attr1.pre_off = 0x20;
attr1.pre_sig = 0x44465543;
attr1.suf_dev = 0x0100;
attr1.suf_prod = 0x0140;
attr1.suf_ven = 0x0419;
attr1.suf_dfu = 0x0100;
memcpy(attr1.suf_sig, "UFD", 3);
attr1.suf_len = 0x10;
init_img(&img1, file1, &attr1);
if (file2) {
attr2.delay = 1000;
attr2.pre_off = 0x20;
attr2.pre_sig = 0x44465543;
attr2.suf_dev = 0x0100;
attr2.suf_prod = 0x0140;
attr2.suf_ven = 0x0419;
attr2.suf_dfu = 0x0100;
memcpy(attr2.suf_sig, "UFD", 3);
attr2.suf_len = 0x10;
init_img(&img2, file2, &attr2);
}
device = usb_dev_open(USB_VID_SAMSUNG, USB_PID_M6SL);
get_cpu(device);
get_cpu(device);
send_file(device, &img1);
if (file2) {
printf("Wait a sec (literally)...");
sleep(1);
printf(" OK\n");
usb_dev_close(device);
device = usb_dev_open(USB_VID_SAMSUNG, USB_PID_M6SL);
get_cpu(device);
get_cpu(device);
send_file(device, &img2);
dfu_detach(device);
}
usb_dev_close(device);
}
int main(int argc, char **argv)
{
if (argc < 3 || argc > 4)
usage();
setvbuf(stdout, NULL, _IONBF, 0);
char *second_file = (argc == 4) ? argv[3] : NULL;
if (!strcmp(argv[1], "m3"))
dfu_m3_m6(argv[2], second_file);
else if (!strcmp(argv[1], "m6"))
dfu_m3_m6(argv[2], second_file);
else if (!strcmp(argv[1], "m6sl"))
dfu_m6sl(argv[2], second_file);
else
usage();
return 0;
}

View file

@ -589,33 +589,6 @@ lyreproto1
record : no
}
meizum3
{
name : Meizu M3
screen : 176 x 132 @ rgb
remote : no
fm : yes
record : no
}
meizum6sl
{
name : Meizu M6SL
screen : 320 x 240 @ rgb
remote : no
fm : yes
record : no
}
meizum6sp
{
name : Meizu M6SP
screen : 240 x 320 @ rgb
remote : no
fm : yes
record : no
}
mini2440
{
name : Mini 2440
@ -688,15 +661,6 @@ samsungypr0
record : no
}
samsungyps3
{
name : Samsung YP-S3
screen : 176 x 220 @ rgb
remote : no
fm : yes
record : no
}
sansac100
{
name : SanDisk Sansa c100