Merge remote-tracking branch 'mntm/dev' into js-app-internal

This commit is contained in:
Willy-JL
2024-12-10 05:19:23 +00:00
16 changed files with 826 additions and 511 deletions
+10 -1
View File
@@ -2,6 +2,8 @@
- Apps:
- Games: Pinball0 (by @rdefeo)
- NFC: Metroflip (by @luu176)
- UL: Sub-GHz: Jolly Motors support with add manually (by @pkooiman & @xMasterX)
- OFW: Add VCP break support (by @gsurkov)
### Updated:
- Apps:
@@ -20,10 +22,17 @@
- WebCrawler: Improved progress display, added connectivity check on startup (by @jamisonderek)
- UL: NFC Magic: Added possibility to write 7b MFC to Gen1 tags (by @mishamyte)
- UL: Fixed apps for firmware USB CDC callback changes (by @xMasterX)
- NFC:
- OFW: Replace mf_classic_dict.nfc with Proxmark3 version (by @onovy)
- OFW: More station IDs for Clipper plugin (by @ted-logan)
- OFW: Infrared: Add IR command for NAD DR2 D7050 D3020 (by @nikos9742)
### Fixed:
- Desktop: Fixed Wardriving animation design (by @Davim09)
- OFW: GPIO: Merged gsurkov/vcp_break_support branch for usb uart bridge (WIP!!!)
- OFW: GPIO: Fix USB UART Bridge Crash by increasing system stack size (by @Astrrra)
- NFC:
- OFW: Plantain parser Last payment amount fix (by @mxcdoam)
- OFW: Fix typo for mf_classic_key_cahce_get_next_key() function (by @luu176)
### Removed:
- Nothing
@@ -5810,3 +5810,16 @@ type: parsed
protocol: NECext
address: 7F 01 00 00
command: 69 96 00 00
#
name: Next
type: parsed
protocol: NECext
address: 87 7C 00 00
command: 1A E5 00 00
#
name: Prev
type: parsed
protocol: NECext
address: 87 7C 00 00
command: 1D E2 00 00
#
@@ -166,7 +166,7 @@ void mf_classic_key_cache_load_from_data(MfClassicKeyCache* instance, const MfCl
}
}
bool mf_classic_key_cahce_get_next_key(
bool mf_classic_key_cache_get_next_key(
MfClassicKeyCache* instance,
uint8_t* sector_num,
MfClassicKey* key,
@@ -16,7 +16,7 @@ bool mf_classic_key_cache_load(MfClassicKeyCache* instance, const uint8_t* uid,
void mf_classic_key_cache_load_from_data(MfClassicKeyCache* instance, const MfClassicData* data);
bool mf_classic_key_cahce_get_next_key(
bool mf_classic_key_cache_get_next_key(
MfClassicKeyCache* instance,
uint8_t* sector_num,
MfClassicKey* key,
@@ -72,7 +72,7 @@ static NfcCommand nfc_scene_read_poller_callback_mf_classic(NfcGenericEvent even
uint8_t sector_num = 0;
MfClassicKey key = {};
MfClassicKeyType key_type = MfClassicKeyTypeA;
if(mf_classic_key_cahce_get_next_key(
if(mf_classic_key_cache_get_next_key(
instance->mfc_key_cache, &sector_num, &key, &key_type)) {
mfc_event->data->read_sector_request_data.sector_num = sector_num;
mfc_event->data->read_sector_request_data.key = key;
@@ -102,7 +102,8 @@ static const IdMapping bart_zones[] = {
{.id = 0x001d, .name = "Lake Merrit"},
{.id = 0x001e, .name = "Fruitvale"},
{.id = 0x001f, .name = "Coliseum"},
{.id = 0x0021, .name = "San Leandro"},
{.id = 0x0020, .name = "San Leandro"},
{.id = 0x0021, .name = "Bay Fair"},
{.id = 0x0022, .name = "Hayward"},
{.id = 0x0023, .name = "South Hayward"},
{.id = 0x0024, .name = "Union City"},
@@ -132,6 +133,9 @@ static const IdMapping muni_zones[] = {
{.id = 0x000b, .name = "Castro"},
{.id = 0x000c, .name = "Forest Hill"}, // Guessed
{.id = 0x000d, .name = "West Portal"},
{.id = 0x0019, .name = "Union Square/Market Street"},
{.id = 0x001a, .name = "Chinatown - Rose Pak"},
{.id = 0x001b, .name = "Yerba Buena/Moscone"},
};
static const size_t kNumMUNIZones = COUNT(muni_zones);
@@ -310,9 +310,11 @@ static bool plantain_parse(const NfcDevice* device, FuriString* parsed_data) {
last_payment_date.year,
last_payment_date.hour,
last_payment_date.minute);
//payment amount. This needs to be investigated more, currently it shows incorrect amount on some cards.
uint16_t last_payment = (data->block[18].data[9] << 8) | data->block[18].data[8];
furi_string_cat_printf(parsed_data, "Amount: %d rub", last_payment / 100);
//Last payment amount.
uint16_t last_payment = ((data->block[18].data[10] << 16) |
(data->block[18].data[9] << 8) | (data->block[18].data[8])) /
100;
furi_string_cat_printf(parsed_data, "Amount: %d rub", last_payment);
furi_string_free(card_number_s);
furi_string_free(tmp_s);
//This is for 4K Plantains.
@@ -369,9 +371,11 @@ static bool plantain_parse(const NfcDevice* device, FuriString* parsed_data) {
last_payment_date.year,
last_payment_date.hour,
last_payment_date.minute);
//payment amount
uint16_t last_payment = (data->block[18].data[9] << 8) | data->block[18].data[8];
furi_string_cat_printf(parsed_data, "Amount: %d rub", last_payment / 100);
//Last payment amount
uint16_t last_payment = ((data->block[18].data[10] << 16) |
(data->block[18].data[9] << 8) | (data->block[18].data[8])) /
100;
furi_string_cat_printf(parsed_data, "Amount: %d rub", last_payment);
furi_string_free(card_number_s);
furi_string_free(tmp_s);
}
File diff suppressed because it is too large Load Diff
@@ -34,7 +34,7 @@ NfcCommand nfc_mf_classic_update_initial_worker_callback(NfcGenericEvent event,
uint8_t sector_num = 0;
MfClassicKey key = {};
MfClassicKeyType key_type = MfClassicKeyTypeA;
if(mf_classic_key_cahce_get_next_key(
if(mf_classic_key_cache_get_next_key(
instance->mfc_key_cache, &sector_num, &key, &key_type)) {
mfc_event->data->read_sector_request_data.sector_num = sector_num;
mfc_event->data->read_sector_request_data.key = key;
@@ -90,6 +90,7 @@ typedef enum {
SetTypeAllmatic868,
SetTypeCenturion433,
SetTypeMonarch433,
SetTypeJollyMotors433,
SetTypeSommer_FM_434,
SetTypeSommer_FM_868,
SetTypeSommer_FM238_434,
@@ -1,61 +1,62 @@
Filetype: Flipper SubGhz Keystore File
Version: 0
Encryption: 1
IV: 46 75 72 72 79 20 63 68 65 63 6B 20 3F 3F 21 21
3FF98B52C38558ECDB26C3E86D118FAC9AF22EDDDE7649CB53726855CEBCCF9E
06B901C6E36E381B4A83554ED972288977F999C232106D337C3BE4A9A44608F8
8153E6CAF4B272BA0EA168B9F0F29CF02CEB33E4ABBD4D5C858D1ADBFF474A25
F61216CE3A7E500E0C9B2173F91C2E7B1BB7D7AA65D4150EAC28169116647DDD
A3ABC262415035A190447EC9C15CFD1AB1720560AB7C82D7447215342305299732776A9A6DEA4D359C52A23BFCE6B015
5784D0E77A55E1361F47A1F6CFFBFAF715CFCAD2BD502ED266AA86DC47F98541
E082BF64C75023F23FB333C53F2590F408FD932EB71DF4ED4D0E0EAF2AEBD488
EFF328889D57D9F4B9111918F9C9BC641645104223009842FFF7B6F73E24E5B7
BDCD1DBCBCA789C5A5C3623C0A287D791F1CACCBBD7D144E2EF1F92DA5513D90
6310362BE6ED7CB5E3F4CA84D3093DF620BABD2C9D419A2BA5AA05F241EE7592
4C6F97C553276D5403103A6BA6C4DBBE017A9E4159E6E5AC4C28ACD645DB1E8D4551CDC228A0457BEEF49179A081E1FD
861ECA071AEEF3854005FEC9BF22C7DB76D07B7930968314FFAC70995E28680E473F8A1A7E56E8776EDD1C6E2DD6DD26
55ADDFBE97BCB0FB43EDEB9CAFF9F32DD788A6306D3702BC2923DA5C69F5F0A5
AB838DA2B25547AA43DEB7FB40B15E289B9209057BE564E7CB78F0D5DCFC65FD
21BACE924E522AD0E97F0AAF64A9DB6A5F7BA09B3A1759AAFD4016F3ADD4353D
4B37D449E44BAE7F377EE5CE52E94882E42617417F77ECE9803D9435892167F2
E63BA93D98BB3EEEAD34B38C5F271FB777AEABD9E6A05597AE09815E578AA811900AE9F144FBEC7DBFDDEC87D1ED368B
7DF24DCB7D73F1638FFD22325463B23C101653EE770F086D323BE90868A7E267
18E533990C408061309323675116429652B3F4D228F00D704310E7AB26F6BAF4
26042EC21D73490D9E7F968EDCC4CECF3989E6E982427DEB7012478E214CED8797A9BEBC481C81E9646214809A409B4A
AC4169C26E402720F1E2A0AD690AE2CF708CE203898BC7102178A738C70F361718E794F0D0CB1A2F1938EF35CCA11887
6962CADB9BD1B86B779DF7F4D7E06E92EB42474C7FD9EA23879F9982D7127357
23AEC0F6F9FF529DDDCD1CDAA77F7B136CE2CCD3AC8B949954D5D3B2ECFA8CBC
C6A3A849BC4A8DB438065255BD387DCD77AD7E7FEB3B0E11B6D3A43279AB9087
CCB71F8BDC8B31F36D6141B3B57BF31B7EDF72B87593B7497871F5738A0B7E00
345FE0FAD3F60C017D9793406981878EA2226072D624208AC33682793B415C41
78AF1FCFDB780744708DBB547F7C3F095BA5FAFB34FA83BF4323B32829836ED1
C2F19F077E71E710D39F5F11C1FE55C2A3CD6F33384CD8603288765F266F1BDF
084B1A9565AFC88900D0FF25413E659E17AAB649DB2B7A9F0381CB0DF6D2B8E5
568CECD994676CF3D6B225DEF21D40787DCB41C101F52B0C5AA43ED66709D158
0742E0AAB6504AC63A9C59FBDD980BD4C4760EFF3E556C8A6241442CDDD23A74
37BB60EE11BEC7D25A607DE9B0B6D3EAD23321AFEB94995FAB42184A95D1CADA
42FD71B98A3BEE9CF372B03E158D51181BFAA9CF54F7300A93FE7665402B3D1F
9346B7D12346E264E84F91145EBF86C53DD0061E0FA6556FAE5F6FBB8CEB799E
430B0D7FC09C09051AEB667A370E6D9D9BDF0C0C553AD2791682D43CE5DC48B7
5BBB5129797BC07CDC1D25A8A919A637B9FFF2F920BD42D1721018ABF8D34959AF877AFF450AD91548184E1A0D991CC8
0BC8D3E1C2D9A8FB445FC55564471007A28C09C9CE602203176F1BFF02AC6328
1C4CA912791BCD9CB231C64AB479AF240D02EC9F431D7C479B9A172E5B97F5CD
15A9CDF17E72255DE0942C09E67CD251C3D465246845F9C0B97A7EFEE4AF9110
F95543395BFF39B0A093AC80D0EF1BEFA218A3769D074250414D1357105A4D34
138D433824E691C6B67A08CF1DDE55FBCA2D65AC0B7D9320EA1FDCB1742B11BF
3BE3A385F1C0B8922C4E23EFF6912748DF715A4546CECB5E8972C1D1E47D0D3A
9ECA2554ED36700326F2E5140C434ADA8DFF55A53382F19541E9AAE45DA5CBF2
5C75D528678AF199E191C49F310913F401014F97EEA5FA507C7310B48A98FDE3297EA398B08959951FF99EDDB64C5E0D
22A9C66645B3944925A496D9F2312429CC787B6314948B482EAD9360124F59DA
DA3A8571664DBBFC1DE97B53E7C141554A2FBCEBA980696D32409CC5ADB7FC41
20A52AABC518FCC2FC75AE3F5CC7C4838AA4973111DA696B890D884A18098D91
EBB7163F580A1A5D26F12FBE650A227791193BA9AFCE277584B171F2FE1C77CF
86369EE5277CB81B9417B6232F8D994FAEAB34D0D5363B143257C62B10CACAFD
2E2EAB32891E172A3C31D434703480E69793435BB198E6AA06AA066EE8234D85
745FC576D77C41BAEFF15A822E6B4058A485A2CAA0A3B283928D17AC02299AD9
1FF8D49F2F7D785D64B6FE365CD9C2BD958E9527F66BB8A85C9AEBC73ECFE064
3CFB77F3E274C1EB2772CDFA7B5B17255C2554198BE60C058A3405AEC644FABC5AAECC8F9C7F4A4E5B2D5252E8C62628
AE514C44B55A1A4744E1106FD226C587D1B71CA7B5DCF010265D769E22012866
2B2D787A4B0F30CAB9CD3DBC7686165637F091B31745CAB53B369A804F76F9EE
EA4279C80F0B4AC0B32AB9E8B8CFB9C25FF81840BEE65B2160F85E56FA576C48
E41D853750D68643E929F94F46BCDC050040935883E9A0C45BB238CDE06340DD745BDA7D6C16AE2B028E073EDDC0FC49
IV: 46 75 72 69 20 63 68 65 63 6B 20 4F 77 4F 21 3F
796353C129CC2B688FE158D36E82001F7450D58DD763BCF4D6FA1CE6C3D598EA
1E7DDEB3B54A42B8993C32AF209CBCC9A1137CE334449F016B993D673EB15C69
F9CB2DDC4E3D45694292C7DE45F1DC0BD74235B36F624AF39E8C3D211A713408
538F46EF4250801434FEA469EE07E8C8BF71C6179442718A05455BB501D797C4
F2BF384DBF7F828E025F020E47D1D637B497FB470444F0C6F9DC67C6830EDDE8A26A6EE89A321D3924D9099895AB2EA1
2CA8A8A4866D5C2B715B520F641B41355A81BA73170842233806D8AA3E3F3D62
80CF5DEF931CF902EE602319F7CD506D42E5FBC06ABBF9F05D474C8E8A2AAC4E
15CB465F7A646226C987BB4928E92A61F350ADCDDE355B717730ADDD1B738950
86B7597ED3EDF6826124ABD7AE419197DC4A93FA064179ACAD853EC670F93995
28263A286F1ADA0E851E8A27AFD7706CF3513D8A24D41CF7E24A925FE3D86305
AF29A08AB877F12681706D71B82B8E2447DA18EBF9731EF3CE91FA5ECAC4E98F8FDC817E0F67C3D7348DD2AF128F1E62
A675C5BB6AC41336B5F5A27FC062FBF30DC39B1E5C498F0FD823261C3177FA58416C5402554742370CB0DAFD2895F6F8
0073790C26BD0224F5560161A4D4C4F8E05498E995FD2BF12EA9926A5127E9A5
235ADFE253B51260DCF5C66F9CB9602B91A0C57BE14D1BE1E11EB309643B29DB
F9C2E3A926AAA108F474075F0B4EDFF3135492B1529EAB150CF78E748BF36E17
50F442CC9D90B9FF8C786245EC442B911A28A04D829D0E45D7D2D4C5A3F5B864
9EA00CD21C0BE1BB15A0CAD31097A44CAF42868F259E8ED25F361986C26161514FA85D78F3889B4185D2A1484C1DA88C
52DFE7D9052F29071922876723C30CF6FE6247D6439590C5C7C0493120ACA096
D5AF176D59779A92F6EFB34F271D76D60780C3EA83306326E0119CD3B0417687
C4CC4E589CCCEC609B4DE39F926F83CCFFCC966871B9A998514910A3F59E86FB56C476DFFB4181E3D22E86A760C4C137
50A64FEDA64B61A5C123906426EF726D98AC70C15F38245A931B5649F0944930679513D9862091275F10A804EBB610DE
E7938C4F32E571582D73F855ACC40FF0153EFBAB6D184F2DBE8EAC63C4276D92
7667993F35F1363C0A3AEB5222F07F91904B3F6FA375BF062B269B09706764CB
9DF764EE4A70D331BA8870F4D27C3E90E811A5E306BC72701A99A0377AC7B189
324D0FBC096A489983C45E82B2745A83A3725A87D2D2CA676A521075065D5047
8EA1A30AE08CEBD03A52EB2512C7C69CB824E0B9BE900E25F15FAB17ADBB1188
CE379182103FC4E0442745F6F202AB6ED8EBC051B5F5537916938D9DB8FCD6BE
752BD22AA37D030C60E48CB57309AF631682AC4A0D67C3A7D1130EB056717FB6
9ECFE7D24BF25BD543E1EAE8116D95C110BD4514EE279BCA71234865EB9166BD
14B3FA8704BA3B284C65F1A6FD114E53B883E12EAFB24B574F84585BD20157DA
D026E1E2CA70E33291482EEFCE11123540BBF591D400C92CEBB8CAF99A9DE882
88E618EF5E76D1F5A60926D48D3D58FF67B4A92DE6EECA271EDAFC2419AE787B
74E14AD8ADE2BC575048325D1B3990669CDB35D840169B913043DAC938862AE4
BEB5388B6A7D5C9EF65BDD7577D1DD654B7FAECE5A4CF0937BB7D0C0C5494CD0
761356D494E3C947CBDCA887A30071A675FE1BE6E77FC9016DB9B5659B7FF9E7
7503725DFC7212F5F719AFC9DF29F07321511BE4896E12D1D10C68BB07C6483A2CE5FFDFD074CFC279E42E6DD860C496
BD03D78399DE44449AEE9F00EBCABBF419EDEA1701B9979A97D57AECB5139D1E
E80EB84DF9DA2E34B78F50D6488A30F8EFD11E7C6DBEB7CFEDE83BE5CA86B6DF
9332A130138F2AC11A12030CF43EFF77E7CABE761EDE14748112E13267496CE9
E657F3C95EEF0AF92A5C49F66BD9C053A82493C7D6267F1E7C038473AE488116
6F37491FFE130F90B77D7E5EA4AA75A1DB0CA3644F68B6502DFC302DDB80367B
3B37C5CCDD510873628D92B352907FEFF0AC2B38C751C2E46C3B97C3E365972B
A4C845187BEC75669234EE07B839DCFF618678D2EAA5596350F0936A400099A5
2C961EF4F2454771B2646ECBAA1D0B7DAA2FD8ECC7228037A36E24FE30C43ABAA446C1B5968C0E2DD141C55557A4CCB8
C4E0D43E9670C2B91F6AF03D60F216625CC19C697331BC443194D2BB88E042DF
3DC5584F43061AF79907D6342DF3344435B5AA6277B33D7DC56C429D1EB81BC4
D9186791E907CBB9EF26EDDAEA9F0DBC8D24E213E55942ED5E1790B5A55F8758
2B54CB727BBFD8567543448D2D24B3865329F89936D3B035ED2185BA88F1DF2E
A08F0D881AF001E52FF2CF9D232A9A566EB1900B351AFEEFEE666BEC40588F64
46A11CA89BA1998A247275EEDF504DAFC5F97B41DFF4943F531A9F8F43DF19C5
EF70A3858E84B13DF606317381B2E9DFFC346E96AF7C1DF0001586B8BF35808F
38EAF18DB8096C7427EBD36CBC5B0E945A3286278CC0227EB056F7ACB9E450D4
28278D1DAA263E9A45ED17F67F6B6B0CF00F8C0F58F86C8161F8D4266FE556CB
0B0C79FDD7C9EA31FAA4AA829EDDD2A3453C05A74F5B53BBEAE83E1F4913FD1C18BD235D14D06D9E567DDB273E4C1F2A
7D663A93AE1B9A2E00E944B92838DED3376E09C5179C8F3037B2EAE9E7326C2A
D64EC2C7BD8CFA152368DF6BB75D66EF24EAA9C864A1386184B793C0585D82BC
51D8EB188E833891CCD15919FAC8FE56ACAB1007699F4FDCB53A6DDAB02E5CAA
650866D34DECD1D1F3559EFD8D2A4C1DB51C005F5932608CB6062B384D7A1F59C8E3FBF2C0A5AEFFB631D7B88A630AAB
@@ -29,6 +29,7 @@ static const char* submenu_names[SetTypeMAX] = {
[SetTypeAllmatic868] = "KL: Allmatic 868MHz",
[SetTypeCenturion433] = "KL: Centurion 433MHz",
[SetTypeMonarch433] = "KL: Monarch 433MHz",
[SetTypeJollyMotors433] = "KL: Jolly Mot. 433MHz",
[SetTypeSommer_FM_434] = "KL: Sommer 434MHz",
[SetTypeSommer_FM_868] = "KL: Sommer 868MHz",
[SetTypeSommer_FM238_434] = "KL: Sommer fm2 434Mhz",
@@ -428,6 +429,16 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
.keeloq.cnt = 0x03,
.keeloq.manuf = "Monarch"};
break;
case SetTypeJollyMotors433:
gen_info = (GenInfo){
.type = GenKeeloq,
.mod = "AM650",
.freq = 433920000,
.keeloq.serial = (key & 0x000FFFFF),
.keeloq.btn = 0x02,
.keeloq.cnt = 0x03,
.keeloq.manuf = "Jolly_Motors"};
break;
case SetTypeElmesElectronic:
gen_info = (GenInfo){
.type = GenKeeloq,
+1
View File
@@ -1042,6 +1042,7 @@ EXCLUDE = $(DOXY_SRC_ROOT)/lib/mlib \
$(DOXY_SRC_ROOT)/applications/plugins/dap_link/lib/free-dap \
$(DOXY_SRC_ROOT)/applications/debug \
$(DOXY_SRC_ROOT)/applications/main \
$(DOXY_SRC_ROOT)/applications/system/js_app/packages \
$(DOXY_SRC_ROOT)/applications/settings \
$(DOXY_SRC_ROOT)/lib/micro-ecc \
$(DOXY_SRC_ROOT)/lib/ReadMe.md \
+15 -17
View File
@@ -2,33 +2,31 @@
import pathlib
import string
KEY_LENGTH = 12
file = (
pathlib.Path(__file__).parent
/ "../applications/main/nfc/resources/nfc/assets/mf_classic_dict.nfc"
)
try:
lines = file.read_text(encoding="ascii").splitlines()
except UnicodeDecodeError:
print(
"Fix non-ASCII characters: https://pteo.paranoiaworks.mobi/diacriticsremover/"
)
exit()
lines = file.read_text().split("\n")
total = 0
for i, line in enumerate(lines):
lines[i] = line = line.strip()
for i, line in reversed(list(enumerate(lines))):
if line.startswith("#"):
continue
lines[i] = line = line.upper()
if not line:
continue
if len(line) != 12 or any(char not in string.hexdigits for char in line):
key = line[:KEY_LENGTH]
if len(key) != KEY_LENGTH or any(char not in string.hexdigits for char in key):
print(f"Line {i + 1} is not correct: {line}")
else:
total = total + 1
for j in reversed(range(i + 1, len(lines))):
if lines[j].upper().strip() == line:
del lines[j]
for check in lines[:i]:
if check.upper()[:KEY_LENGTH] == line.upper()[:KEY_LENGTH]:
print(f"Line {i + 1} is a duplicate: {line}")
del lines[i]
break
else: # Didn't break
total += 1
file.write_text("\n".join(line for line in lines if line.removeprefix("#")))
file.write_text("\n".join(lines))
print(f"Total keys: {total}")
+1 -1
View File
@@ -3,7 +3,7 @@ ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_stack_end = 0x20030000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_stack_size = 0x200; /* required amount of stack */
_stack_size = 0x400; /* required amount of stack */
MEMORY {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
+1 -1
View File
@@ -3,7 +3,7 @@ ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_stack_end = 0x20030000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_stack_size = 0x200; /* required amount of stack */
_stack_size = 0x400; /* required amount of stack */
MEMORY {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K