@@ -400,79 +400,230 @@ extern "C" void __disableWiFiAtBootTime (void)
400
400
401
401
#if FLASH_MAP_SUPPORT
402
402
#include " flash_hal.h"
403
- extern " C" void flashinit (void );
403
+ extern " C" bool flashinit (void );
404
+ #if (NONOSDK >= (0x30000))
405
+ uint32_t __flashindex __attribute__ ((section(" .noinit" )));
406
+ #else
404
407
uint32_t __flashindex;
405
408
#endif
409
+ #endif
406
410
407
411
#if (NONOSDK >= (0x30000))
412
+ #undef ETS_PRINTF
413
+ #define ETS_PRINTF (...) ets_uart_printf(__VA_ARGS__)
414
+ extern " C" uint8_t uart_rx_one_char_block ();
415
+
416
+ #if ! FLASH_MAP_SUPPORT
417
+ #include " flash_hal.h"
418
+ #endif
408
419
409
420
extern " C" void ICACHE_FLASH_ATTR user_pre_init (void )
410
421
{
411
- uint32_t rf_cal = 0 ;
422
+ const char *flash_map_str = NULL ;
423
+ const char *chip_sz_str = NULL ;
424
+ const char *table_regist_str = NULL ;
425
+ [[maybe_unused]] uint32_t ld_config_chip_size = 0 ;
426
+ uint32_t flash_size = 0 ;
412
427
uint32_t phy_data = 0 ;
428
+ uint32_t rf_cal = 0 ;
413
429
uint32_t system_parameter = 0 ;
414
-
415
- switch (system_get_flash_size_map ())
416
- {
417
- case FLASH_SIZE_2M:
418
- rf_cal = 0x3b000 ;
419
- phy_data = 0x3c000 ;
420
- system_parameter = 0x3d000 ;
421
- break ;
422
- case FLASH_SIZE_4M_MAP_256_256:
423
- rf_cal = 0x7b000 ;
424
- phy_data = 0x7c000 ;
425
- system_parameter = 0x7d000 ;
426
- break ;
427
- case FLASH_SIZE_8M_MAP_512_512:
428
- rf_cal = 0xfb000 ;
429
- phy_data = 0xfc000 ;
430
- system_parameter = 0xfd000 ;
431
- break ;
432
- case FLASH_SIZE_16M_MAP_512_512:
433
- case FLASH_SIZE_16M_MAP_1024_1024:
434
- rf_cal = 0x1fb000 ;
435
- phy_data = 0x1fc000 ;
436
- system_parameter = 0x1fd000 ;
437
- break ;
438
- case FLASH_SIZE_32M_MAP_512_512:
439
- case FLASH_SIZE_32M_MAP_1024_1024:
440
- case FLASH_SIZE_32M_MAP_2048_2048:
441
- rf_cal = 0x3fb000 ;
442
- phy_data = 0x3fc000 ;
443
- system_parameter = 0x3fd000 ;
444
- break ;
445
- case FLASH_SIZE_64M_MAP_1024_1024:
446
- rf_cal = 0x7fb000 ;
447
- phy_data = 0x7fc000 ;
448
- system_parameter = 0x7fd000 ;
449
- break ;
450
- case FLASH_SIZE_128M_MAP_1024_1024:
451
- rf_cal = 0xffb000 ;
452
- phy_data = 0xffc000 ;
453
- system_parameter = 0xffd000 ;
454
- break ;
430
+ [[maybe_unused]] const partition_item_t *_at_partition_table = NULL ;
431
+ size_t _at_partition_table_sz = 0 ;
432
+
433
+ do {
434
+ #if FLASH_MAP_SUPPORT
435
+ if (!flashinit ()) {
436
+ flash_map_str = PSTR (" flashinit: flash size missing from FLASH_MAP table\n " );
437
+ continue ;
438
+ }
439
+ #endif
440
+
441
+ // For SDKs 3.0.0 and later, place phy_data readonly overlay on top of
442
+ // the EEPROM address. For older SDKs without a system partition, RF_CAL
443
+ // and PHY_DATA shared the same flash segment.
444
+ //
445
+ // For the Arduino ESP8266 core, the sectors for "EEPROM = size -
446
+ // 0x5000", "RF_CAL = size - 0x4000", and "SYSTEM_PARAMETER = size -
447
+ // 0x3000" are positioned in the last five sectors of flash memory.
448
+ // PHY_INIT_DATA is special. It is a one time read of 128 bytes of data
449
+ // that is provided by a spoofed flash read.
450
+ #if FLASH_MAP_SUPPORT
451
+ flash_size = __flashdesc[__flashindex].flash_size_kb * 1024u ;
452
+ #else
453
+ // flashchip->chip_size is updated by the SDK. The size is based on the
454
+ // value patched into the .bin header by esptool.
455
+ // system_get_flash_size_map() returns that patched value.
456
+ flash_size = flashchip->chip_size ;
457
+ #endif
458
+
459
+ // For all configurations, place RF_CAL and system_parameter in the
460
+ // last 4 sectors of the flash chip.
461
+ rf_cal = flash_size - 0x4000u ;
462
+ system_parameter = flash_size - 0x3000u ;
463
+
464
+ // The system_partition_table_regist will not allow partitions to
465
+ // overlap. EEPROM_start is a good choice for phy_data overlay. The SDK
466
+ // does not need to know about EEPROM_start. So we can omit it from the
467
+ // table. The real EEPROM access is after user_init() begins long after
468
+ // the PHY_DATA read. So it should be safe from conflicts.
469
+ phy_data = EEPROM_start - 0x40200000u ;
470
+
471
+ // For SDKs 3.0 builds, "sdk3_begin_phy_data_spoof and
472
+ // user_rf_cal_sector_set" starts and stops the spoofing logic in
473
+ // `core_esp8266_phy.cpp`.
474
+ extern void sdk3_begin_phy_data_spoof ();
475
+ sdk3_begin_phy_data_spoof ();
476
+
477
+ ld_config_chip_size = phy_data + 4096 * 5 ;
478
+
479
+ // -DALLOW_SMALL_FLASH_SIZE=1
480
+ // Allows for small flash-size builds targeted for multiple devices,
481
+ // commonly IoT, of varying flash sizes.
482
+ #if !defined(FLASH_MAP_SUPPORT) && !defined(ALLOW_SMALL_FLASH_SIZE)
483
+ // Note, system_partition_table_regist will only catch when the build
484
+ // flash size value set by the Arduino IDE Tools menu is larger than
485
+ // the firmware image value detected and updated on the fly by esptool.
486
+ if (flashchip->chip_size != ld_config_chip_size) {
487
+ // Stop to avoid possible stored flash data corruption. This
488
+ // mismatch will not occur with flash size selection "Mapping
489
+ // defined by Hardware and Sketch".
490
+ chip_sz_str = PSTR (" Flash size mismatch, check that the build setting matches the device.\n " );
491
+ continue ;
492
+ }
493
+ #elif defined(ALLOW_SMALL_FLASH_SIZE) && !defined(FLASH_MAP_SUPPORT)
494
+ // Note, while EEPROM is confined to a smaller flash size, we are still
495
+ // placing RF_CAL and SYSTEM_PARAMETER at the end of flash. To prevent
496
+ // this, esptool or its equal needs to not update the flash size in the
497
+ // .bin image.
498
+ #endif
499
+
500
+ #if FLASH_MAP_SUPPORT && defined(DEBUG_ESP_PORT)
501
+ // I don't think this will ever fail. Everything traces back to the results of spi_flash_get_id()
502
+ if (flash_size != flashchip->chip_size ) {
503
+ chip_sz_str = PSTR (" Flash size mismatch, check that the build setting matches the device.\n " );
504
+ continue ;
505
+ }
506
+ #endif
507
+
508
+ // All the examples I find, show the partition table in the global address space.
509
+ static const partition_item_t at_partition_table[] =
510
+ {
511
+ { SYSTEM_PARTITION_PHY_DATA, phy_data, 0x1000 }, // type 5
512
+ { SYSTEM_PARTITION_RF_CAL, rf_cal, 0x1000 }, // type 4
513
+ { SYSTEM_PARTITION_SYSTEM_PARAMETER, system_parameter, 0x3000 }, // type 6
514
+ };
515
+ _at_partition_table = at_partition_table;
516
+ _at_partition_table_sz = std::size (at_partition_table);
517
+ // SDK 3.0's `system_partition_table_regist` is FOTA-centric. It will report
518
+ // on BOOT, OTA1, and OTA2 being missing. We are Non-FOTA. I don't see
519
+ // anything we can do about this. Other than maybe turning off os_print.
520
+ if (!system_partition_table_regist (at_partition_table, _at_partition_table_sz, system_get_flash_size_map ())) {
521
+ table_regist_str = PSTR (" System partition table registration failed!\n " );
522
+ continue ;
523
+ }
524
+ } while (false );
525
+
526
+ if (chip_sz_str || flash_map_str || table_regist_str) {
527
+ // user_pre_init() is called very early in the SDK startup. When called,
528
+ // the PLL CPU clock calibration hasn't not run. Since we are failing, the
529
+ // calibration will never complete. And the process will repeat over and
530
+ // over. The effective data rate will always be 74880 bps. If we had a
531
+ // successful boot, the effective data rate would be 115200 on a restart
532
+ // or HWDT. This hack relies on the CPU clock calibration never having
533
+ // completed. This assumes we are starting from a hard reset.
534
+
535
+ // A possible exception would be a soft reset after flashing. In which
536
+ // case the message will not be readable until after a hard reset or
537
+ // power cycle.
538
+
539
+ // After flashing, the Arduino Serial Monitor needs a moment to
540
+ // reconnect. This also allows time for the FIFO to clear and the host
541
+ // serial port to clear any framing errors.
542
+ ets_delay_us (200u * 1000u ); // For an uncalibrated CPU Clock, this is close enough.
543
+
544
+ #if !defined(F_CRYSTAL)
545
+ #define F_CRYSTAL 26000000
546
+ #endif
547
+ // For print messages to be readable, the UART clock rate is based on the
548
+ // precalibration rate.
549
+ if (F_CRYSTAL != 40000000 ) {
550
+ uart_div_modify (0 , F_CRYSTAL * 2 / 115200 );
551
+ ets_delay_us (150 );
552
+ }
553
+ do {
554
+ ETS_PRINTF (" \n\n " );
555
+ // Because SDK v3.0.x always has a non-32-bit wide exception handler
556
+ // installed, we can use PROGMEM strings with Boot ROM print functions.
557
+ #if defined(DEBUG_ESP_CORE) || defined(DEBUG_ESP_PORT) // DEBUG_ESP_CORE => verbose
558
+ #if FLASH_MAP_SUPPORT
559
+ if (flash_map_str) {
560
+ ETS_PRINTF (flash_map_str);
561
+ #if defined(DEBUG_ESP_CORE)
562
+ size_t num = __flashindex; // On failure __flashindex is the size of __flashdesc[]; :/
563
+ ETS_PRINTF (PSTR (" Table of __flashdesc[%u].flash_size_kb entries converted to bytes:\n " ), num);
564
+ for (size_t i = 0 ; i < num; i++) {
565
+ uint32_t size = __flashdesc[i].flash_size_kb << 10 ;
566
+ ETS_PRINTF (PSTR (" [%02u] 0x%08X %8u\n " ), i, size, size);
567
+ }
568
+ #endif
569
+ ETS_PRINTF (PSTR (" Reference info:\n " ));
570
+ uint32_t flash_chip_size = 1 << ((spi_flash_get_id () >> 16 ) & 0xff );
571
+ ETS_PRINTF (PSTR (" %-24s 0x%08X %8u\n " ), PSTR (" fn(spi_flash_get_id())" ), flash_chip_size, flash_chip_size);
572
+ ETS_PRINTF (PSTR (" %-24s 0x%08X %8u\n " ), PSTR (" bin_chip_size" ), flashchip->chip_size , flashchip->chip_size );
573
+ } else
574
+ #endif
575
+ if (chip_sz_str) {
576
+ ETS_PRINTF (chip_sz_str);
577
+ } else
578
+ if (table_regist_str) {
579
+ ETS_PRINTF (table_regist_str);
580
+ // (printing now works) repeat ...regist error messages
581
+ system_partition_table_regist (_at_partition_table, _at_partition_table_sz, system_get_flash_size_map ());
582
+ }
583
+ if (chip_sz_str || table_regist_str) {
584
+ ETS_PRINTF (PSTR (" Reference info:\n " ));
585
+ #if FLASH_MAP_SUPPORT
586
+ ETS_PRINTF (PSTR (" %-24s 0x%08X %8u\n " ), PSTR (" fn(...ex].flash_size_kb)" ), flash_size, flash_size);
587
+ uint32_t flash_chip_size = 1 << ((spi_flash_get_id () >> 16 ) & 0xff );
588
+ ETS_PRINTF (PSTR (" %-24s 0x%08X %8u\n " ), PSTR (" fn(spi_flash_get_id())" ), flash_chip_size, flash_chip_size);
589
+ ETS_PRINTF (PSTR (" %-24s 0x%08X %8u\n " ), PSTR (" bin_chip_size" ), flashchip->chip_size , flashchip->chip_size );
590
+ #else
591
+ ETS_PRINTF (PSTR (" %-24s 0x%08X %8u\n " ), PSTR (" config_flash_size" ), ld_config_chip_size, ld_config_chip_size);
592
+ ETS_PRINTF (PSTR (" %-24s 0x%08X %8u\n " ), PSTR (" bin_chip_size" ), flashchip->chip_size , flashchip->chip_size );
593
+ #endif
594
+ #if defined(DEBUG_ESP_CORE)
595
+ ETS_PRINTF (PSTR (" %-24s 0x%08X\n " ), PSTR (" PHY_DATA" ), phy_data);
596
+ ETS_PRINTF (PSTR (" %-24s 0x%08X\n " ), PSTR (" RF_CAL" ), rf_cal);
597
+ ETS_PRINTF (PSTR (" %-24s 0x%08X\n " ), PSTR (" SYSTEM_PARAMETER" ), system_parameter);
598
+ ETS_PRINTF (PSTR (" %-24s 0x%08X\n " ), PSTR (" EEPROM_start" ), EEPROM_start);
599
+ ETS_PRINTF (PSTR (" %-24s 0x%08X\n " ), PSTR (" FS_start" ), FS_start);
600
+ ETS_PRINTF (PSTR (" %-24s 0x%08X\n " ), PSTR (" FS_end" ), FS_end);
601
+ ETS_PRINTF (PSTR (" %-24s 0x%08X\n " ), PSTR (" FS_page" ), FS_page);
602
+ ETS_PRINTF (PSTR (" %-24s 0x%08X\n " ), PSTR (" FS_block" ), FS_block);
603
+ #endif
604
+ }
605
+ #else
606
+ if (flash_map_str) {
607
+ ETS_PRINTF (flash_map_str);
608
+ } else
609
+ if (chip_sz_str) {
610
+ ETS_PRINTF (chip_sz_str);
611
+ } else
612
+ if (table_regist_str) {
613
+ ETS_PRINTF (table_regist_str);
614
+ }
615
+ #endif
616
+ uart_rx_one_char_block (); // Someone said hello - repeat message
617
+ } while (true );
455
618
}
456
-
457
- extern uint32_t user_rf_cal_sector_set (void );
458
- user_rf_cal_sector_set ();
459
-
460
- const partition_item_t at_partition_table[] =
461
- {
462
- { SYSTEM_PARTITION_RF_CAL, rf_cal, 0x1000 },
463
- { SYSTEM_PARTITION_PHY_DATA, phy_data, 0x1000 },
464
- { SYSTEM_PARTITION_SYSTEM_PARAMETER, system_parameter, 0x3000 },
465
- };
466
- system_partition_table_regist (at_partition_table, sizeof (at_partition_table) / sizeof (at_partition_table[0 ]), system_get_flash_size_map ());
467
619
}
468
-
469
- #endif
620
+ #endif // #if (NONOSDK >= (0x30000))
470
621
471
622
extern " C" void user_init (void ) {
472
623
473
624
#if (NONOSDK >= (0x30000))
474
625
extern void user_rf_pre_init ();
475
- user_rf_pre_init ();
626
+ user_rf_pre_init (); // Stop spoofing logic
476
627
#endif
477
628
478
629
struct rst_info *rtc_info_ptr = system_get_rst_info ();
@@ -503,8 +654,10 @@ extern "C" void user_init(void) {
503
654
#if defined(MMU_IRAM_HEAP)
504
655
umm_init_iram ();
505
656
#endif
506
- #if FLASH_MAP_SUPPORT
507
- flashinit ();
657
+ #if FLASH_MAP_SUPPORT && (NONOSDK < 0x30000)
658
+ if (!flashinit ()) {
659
+ panic ();
660
+ }
508
661
#endif
509
662
preinit (); // Prior to C++ Dynamic Init (not related to above init() ). Meant to be user redefinable.
510
663
__disableWiFiAtBootTime (); // default weak function disables WiFi
0 commit comments