mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-20 03:48:33 +08:00
more..
This commit is contained in:
commit
f30511f1a2
15 changed files with 72 additions and 49 deletions
11
appveyor.yml
11
appveyor.yml
|
@ -376,13 +376,14 @@ test_script:
|
||||||
|
|
||||||
ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc"
|
ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc"
|
||||||
|
|
||||||
ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:"
|
|
||||||
|
|
||||||
ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "verified ok"
|
|
||||||
|
|
||||||
|
|
||||||
#proxmark crypto tests
|
#proxmark crypto tests
|
||||||
|
|
||||||
|
# Long tests:
|
||||||
|
# ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:"
|
||||||
|
# ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t l'"} "verified ok"
|
||||||
|
# ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i -l'"} "Test?s? ? OK"
|
||||||
|
# Short tests:
|
||||||
|
ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "OK!"
|
||||||
ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i'"} "Test?s? ? OK"
|
ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i'"} "Test?s? ? OK"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1977,11 +1977,6 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MifareCIdent() {
|
void MifareCIdent() {
|
||||||
#define GEN_1A 1
|
|
||||||
#define GEN_1B 2
|
|
||||||
#define GEN_2 4
|
|
||||||
#define GEN_UNFUSED 5
|
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
uint8_t isGen = 0;
|
uint8_t isGen = 0;
|
||||||
uint8_t rec[1] = {0x00};
|
uint8_t rec[1] = {0x00};
|
||||||
|
@ -1997,16 +1992,13 @@ void MifareCIdent() {
|
||||||
|
|
||||||
// Generation 1 test
|
// Generation 1 test
|
||||||
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
||||||
|
if (ReaderReceive(rec, recpar) && (rec[0] == 0x0a)) {
|
||||||
if (ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
|
|
||||||
|
|
||||||
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
||||||
|
|
||||||
if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
|
if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
|
||||||
isGen = GEN_1B;
|
isGen = MAGIC_GEN_1B;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
};
|
};
|
||||||
isGen = GEN_1A;
|
isGen = MAGIC_GEN_1A;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2017,20 +2009,19 @@ void MifareCIdent() {
|
||||||
|
|
||||||
int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
|
int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
|
||||||
if (res == 2) {
|
if (res == 2) {
|
||||||
Dbprintf("cident AA55C396 == %08X", cuid);
|
|
||||||
if (cuid == 0xAA55C396) {
|
if (cuid == 0xAA55C396) {
|
||||||
isGen = GEN_UNFUSED;
|
isGen = MAGIC_GEN_UNFUSED;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReaderTransmit(rats, sizeof(rats), NULL);
|
ReaderTransmit(rats, sizeof(rats), NULL);
|
||||||
res = ReaderReceive(buf, par);
|
res = ReaderReceive(buf, par);
|
||||||
if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) {
|
if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) {
|
||||||
isGen = GEN_2;
|
isGen = MAGIC_GEN_2;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
if (memcmp(buf, "\x0D\x78\x00\x71\x02\x88\x49\xA1\x30\x20\x15\x06\x08\x56\x3D", 15) == 0) {
|
if (memcmp(buf, "\x0D\x78\x00\x71\x02\x88\x49\xA1\x30\x20\x15\x06\x08\x56\x3D", 15) == 0) {
|
||||||
isGen = GEN_2;
|
isGen = MAGIC_GEN_2;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -229,10 +229,11 @@ static int usage_hf_iclass_sniff(void) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_hf_iclass_loclass(void) {
|
static int usage_hf_iclass_loclass(void) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [options]");
|
PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [h] [t [l]] [f <filename>]");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h Show this help");
|
PrintAndLogEx(NORMAL, " h Show this help");
|
||||||
PrintAndLogEx(NORMAL, " t Perform self-test");
|
PrintAndLogEx(NORMAL, " t Perform self-test");
|
||||||
|
PrintAndLogEx(NORMAL, " t l Perform self-test, including long ones");
|
||||||
PrintAndLogEx(NORMAL, " f <filename> Bruteforce iclass dumpfile");
|
PrintAndLogEx(NORMAL, " f <filename> Bruteforce iclass dumpfile");
|
||||||
PrintAndLogEx(NORMAL, " An iclass dumpfile is assumed to consist of an arbitrary number of");
|
PrintAndLogEx(NORMAL, " An iclass dumpfile is assumed to consist of an arbitrary number of");
|
||||||
PrintAndLogEx(NORMAL, " malicious CSNs, and their protocol responses");
|
PrintAndLogEx(NORMAL, " malicious CSNs, and their protocol responses");
|
||||||
|
@ -1831,10 +1832,11 @@ static int CmdHFiClass_loclass(const char *Cmd) {
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
} else if (opt == 't') {
|
} else if (opt == 't') {
|
||||||
|
char opt2 = tolower(param_getchar(Cmd, 1));
|
||||||
int errors = testCipherUtils();
|
int errors = testCipherUtils();
|
||||||
errors += testMAC();
|
errors += testMAC();
|
||||||
errors += doKeyTests(0);
|
errors += doKeyTests(0);
|
||||||
errors += testElite();
|
errors += testElite(opt2=='l');
|
||||||
if (errors) PrintAndLogEx(ERR, "There were errors!!!");
|
if (errors) PrintAndLogEx(ERR, "There were errors!!!");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1716,19 +1716,21 @@ static int CmdEMVList(const char *Cmd) {
|
||||||
static int CmdEMVTest(const char *Cmd) {
|
static int CmdEMVTest(const char *Cmd) {
|
||||||
CLIParserInit("emv test",
|
CLIParserInit("emv test",
|
||||||
"Executes tests\n",
|
"Executes tests\n",
|
||||||
"Usage:\n\temv test\n");
|
"Usage:\n\temv test [l]\n");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0("iI", "ignore", "ignore timing tests for VM"),
|
arg_lit0("iI", "ignore", "ignore timing tests for VM"),
|
||||||
|
arg_lit0("lL", "long", "run long tests too"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(Cmd, argtable, true);
|
CLIExecWithReturn(Cmd, argtable, true);
|
||||||
|
|
||||||
bool ignoreTimeTest = arg_get_lit(1);
|
bool ignoreTimeTest = arg_get_lit(1);
|
||||||
|
bool runSlowTests = arg_get_lit(2);
|
||||||
CLIParserFree();
|
CLIParserFree();
|
||||||
|
|
||||||
return ExecuteCryptoTests(true, ignoreTimeTest);
|
return ExecuteCryptoTests(true, ignoreTimeTest, runSlowTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdEMVRoca(const char *Cmd) {
|
static int CmdEMVRoca(const char *Cmd) {
|
||||||
|
|
|
@ -301,8 +301,9 @@ close_pub:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exec_crypto_test(bool verbose) {
|
int exec_crypto_test(bool verbose, bool include_slow_tests) {
|
||||||
unsigned int keylengths[] = {1024, 1152, 1408, 1984, 2048, 3072, 4096};
|
unsigned int keylengths[] = {1024, 2048};
|
||||||
|
unsigned int extra_keylengths[] = {1152, 1408, 1984, 3072, 4096};
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
|
@ -322,6 +323,15 @@ int exec_crypto_test(bool verbose) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (include_slow_tests) {
|
||||||
|
for (i = 0; i < ARRAYLEN(extra_keylengths); i++) {
|
||||||
|
unsigned int kl = extra_keylengths[i];
|
||||||
|
ret = test_genkey(kl, message, kl / 8, verbose);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "Crypto generate key[%u] test: failed\n", kl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,5 +17,5 @@
|
||||||
#define __CRYPTO_TEST_H
|
#define __CRYPTO_TEST_H
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
int exec_crypto_test(bool verbose);
|
int exec_crypto_test(bool verbose, bool include_slow_tests);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "crypto/libpcrypto.h"
|
#include "crypto/libpcrypto.h"
|
||||||
#include "emv/emv_roca.h"
|
#include "emv/emv_roca.h"
|
||||||
|
|
||||||
int ExecuteCryptoTests(bool verbose, bool ignore_time) {
|
int ExecuteCryptoTests(bool verbose, bool ignore_time, bool include_slow_tests) {
|
||||||
int res;
|
int res;
|
||||||
bool TestFail = false;
|
bool TestFail = false;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ int ExecuteCryptoTests(bool verbose, bool ignore_time) {
|
||||||
res = exec_cda_test(verbose);
|
res = exec_cda_test(verbose);
|
||||||
if (res) TestFail = true;
|
if (res) TestFail = true;
|
||||||
|
|
||||||
res = exec_crypto_test(verbose);
|
res = exec_crypto_test(verbose, include_slow_tests);
|
||||||
if (res) TestFail = true;
|
if (res) TestFail = true;
|
||||||
|
|
||||||
res = roca_self_test();
|
res = roca_self_test();
|
||||||
|
|
|
@ -12,5 +12,5 @@
|
||||||
#define __CRYPTOTEST_H
|
#define __CRYPTOTEST_H
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
int ExecuteCryptoTests(bool verbose, bool ignore_time);
|
int ExecuteCryptoTests(bool verbose, bool ignore_time, bool include_slow_tests);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -74,15 +74,15 @@ int fileExists(const char *filename) {
|
||||||
* @param filename
|
* @param filename
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int is_regular_file(const char *filename) {
|
bool is_regular_file(const char *filename) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
struct _stat st;
|
struct _stat st;
|
||||||
_stat(filename, &st);
|
_stat(filename, &st);
|
||||||
return S_ISREG(st.st_mode);
|
return S_ISREG(st.st_mode) != 0;
|
||||||
#else
|
#else
|
||||||
struct stat st;
|
struct stat st;
|
||||||
stat(filename, &st);
|
stat(filename, &st);
|
||||||
return S_ISREG(st.st_mode);
|
return S_ISREG(st.st_mode) != 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -90,15 +90,15 @@ int is_regular_file(const char *filename) {
|
||||||
* @param filename
|
* @param filename
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int is_directory(const char *filename) {
|
bool is_directory(const char *filename) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
struct _stat st;
|
struct _stat st;
|
||||||
_stat(filename, &st);
|
_stat(filename, &st);
|
||||||
return S_ISDIR(st.st_mode);
|
return S_ISDIR(st.st_mode) != 0;
|
||||||
#else
|
#else
|
||||||
struct stat st;
|
struct stat st;
|
||||||
stat(filename, &st);
|
stat(filename, &st);
|
||||||
return S_ISDIR(st.st_mode);
|
return S_ISDIR(st.st_mode) != 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,7 +1053,7 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con
|
||||||
if (searchname == NULL || strlen(searchname) == 0)
|
if (searchname == NULL || strlen(searchname) == 0)
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
|
||||||
if (is_directory(searchname) != 0)
|
if (is_directory(searchname))
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -637,7 +637,7 @@ static int _testHash1() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int testElite() {
|
int testElite(bool slowtests) {
|
||||||
PrintAndLogEx(INFO, "Testing iClass Elite functinality...");
|
PrintAndLogEx(INFO, "Testing iClass Elite functinality...");
|
||||||
PrintAndLogEx(INFO, "Testing hash2");
|
PrintAndLogEx(INFO, "Testing hash2");
|
||||||
uint8_t k_cus[8] = {0x5B, 0x7C, 0x62, 0xC4, 0x91, 0xC1, 0x1B, 0x39};
|
uint8_t k_cus[8] = {0x5B, 0x7C, 0x62, 0xC4, 0x91, 0xC1, 0x1B, 0x39};
|
||||||
|
@ -669,6 +669,7 @@ int testElite() {
|
||||||
errors += _testHash1();
|
errors += _testHash1();
|
||||||
PrintAndLogEx(INFO, "Testing key diversification ...");
|
PrintAndLogEx(INFO, "Testing key diversification ...");
|
||||||
errors += _test_iclass_key_permutation();
|
errors += _test_iclass_key_permutation();
|
||||||
|
if (slowtests)
|
||||||
errors += _testBruteforce();
|
errors += _testBruteforce();
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]);
|
||||||
* @brief Test function
|
* @brief Test function
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int testElite(void);
|
int testElite(bool slowtests);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Here are some pretty optimal values that can be used to recover necessary data in only
|
Here are some pretty optimal values that can be used to recover necessary data in only
|
||||||
|
|
|
@ -1033,16 +1033,16 @@ void detect_classic_magic(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (isGeneration) {
|
switch (isGeneration) {
|
||||||
case 1:
|
case MAGIC_GEN_1A:
|
||||||
PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1a): " _GREEN_("YES"));
|
PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1a): " _GREEN_("YES"));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case MAGIC_GEN_1B:
|
||||||
PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1b): " _GREEN_("YES"));
|
PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1b): " _GREEN_("YES"));
|
||||||
break;
|
break;
|
||||||
case 4:
|
case MAGIC_GEN_2:
|
||||||
PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2 / CUID): " _GREEN_("YES"));
|
PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2 / CUID): " _GREEN_("YES"));
|
||||||
break;
|
break;
|
||||||
case 5:
|
case MAGIC_GEN_UNFUSED:
|
||||||
PrintAndLogEx(SUCCESS, "Answers to magic commands (Write Once / FUID): " _GREEN_("YES"));
|
PrintAndLogEx(SUCCESS, "Answers to magic commands (Write Once / FUID): " _GREEN_("YES"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -205,6 +205,11 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
#define MAGIC_WIPE 0x40
|
#define MAGIC_WIPE 0x40
|
||||||
#define MAGIC_SINGLE (MAGIC_WUPC | MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E
|
#define MAGIC_SINGLE (MAGIC_WUPC | MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E
|
||||||
|
|
||||||
|
// by CMD_HF_MIFARE_CIDENT
|
||||||
|
#define MAGIC_GEN_1A 1
|
||||||
|
#define MAGIC_GEN_1B 2
|
||||||
|
#define MAGIC_GEN_2 4
|
||||||
|
#define MAGIC_GEN_UNFUSED 5
|
||||||
/**
|
/**
|
||||||
06 00 = INITIATE
|
06 00 = INITIATE
|
||||||
0E xx = SELECT ID (xx = Chip-ID)
|
0E xx = SELECT ID (xx = Chip-ID)
|
||||||
|
|
13
pm3test.sh
13
pm3test.sh
|
@ -3,6 +3,12 @@
|
||||||
PM3PATH=$(dirname "$0")
|
PM3PATH=$(dirname "$0")
|
||||||
cd "$PM3PATH" || exit 1
|
cd "$PM3PATH" || exit 1
|
||||||
|
|
||||||
|
if [ "$1" == "long" ]; then
|
||||||
|
SLOWTESTS=true
|
||||||
|
else
|
||||||
|
SLOWTESTS=false
|
||||||
|
fi
|
||||||
|
|
||||||
C_RED='\033[0;31m'
|
C_RED='\033[0;31m'
|
||||||
C_GREEN='\033[0;32m'
|
C_GREEN='\033[0;32m'
|
||||||
C_YELLOW='\033[0;33m'
|
C_YELLOW='\033[0;33m'
|
||||||
|
@ -95,9 +101,14 @@ while true; do
|
||||||
|
|
||||||
printf "\n${C_BLUE}Testing HF:${C_NC}\n"
|
printf "\n${C_BLUE}Testing HF:${C_NC}\n"
|
||||||
if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi
|
if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi
|
||||||
|
if $SLOWTESTS; then
|
||||||
if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi
|
if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi
|
||||||
if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "verified ok"; then break; fi
|
if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t l'" "verified ok"; then break; fi
|
||||||
|
if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test -l'" "Test(s) \[ OK"; then break; fi
|
||||||
|
else
|
||||||
|
if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "OK!"; then break; fi
|
||||||
if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi
|
if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi
|
||||||
|
fi
|
||||||
|
|
||||||
printf "\n${C_BLUE}Testing tools:${C_NC}\n"
|
printf "\n${C_BLUE}Testing tools:${C_NC}\n"
|
||||||
# Need a decent example for mfkey32...
|
# Need a decent example for mfkey32...
|
||||||
|
|
|
@ -17,7 +17,7 @@ interface bcm2835gpio
|
||||||
# This file is meant for recent versions of Raspberry Pi
|
# This file is meant for recent versions of Raspberry Pi
|
||||||
# You can check yours with:
|
# You can check yours with:
|
||||||
# dd if=/proc/device-tree/soc/ranges bs=4 skip=1 count=1 2>/dev/null|xxd -p
|
# dd if=/proc/device-tree/soc/ranges bs=4 skip=1 count=1 2>/dev/null|xxd -p
|
||||||
# if it returns 20000000, use interface-raspberrypi2.cfg
|
# if it returns 20000000, use interface-raspberrypi.cfg
|
||||||
# if it returns 3F000000, you're fine
|
# if it returns 3F000000, you're fine
|
||||||
bcm2835gpio_peripheral_base 0x3F000000
|
bcm2835gpio_peripheral_base 0x3F000000
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue