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