From e743d03a78609745794762004d12c7379a5ad2ab Mon Sep 17 00:00:00 2001
From: Angus Gratton <gus@projectgus.com>
Date: Sat, 30 May 2015 19:11:04 +1000
Subject: [PATCH] Preprocess all binary SDK symbols to add an sdk_ prefix

* This fixes the problem of axTLS symbols hmac_md5/hmac_sha1 having same
  name as symbols in libwpa (which have incompatible signatures)

* Also allows for easier identification and piece-by-piece removal of
  binary functions.

* Some libc symbols are not renamed, list is in lib/symbols_norename.txt
---
 FreeRTOS/Source/portable/esp8266/port.c      |  16 +++---
 FreeRTOS/Source/portable/esp8266/portmacro.h |  21 ++++---
 common.mk                                    |  57 ++++++++++++++++---
 examples/http_get/main.c                     |  10 ++--
 include/esp8266.h                            |  33 +++++++++++
 include/espressif/esp_misc.h                 |   6 +-
 include/espressif/esp_softap.h               |   6 +-
 include/espressif/esp_sta.h                  |  28 ++++-----
 include/espressif/esp_system.h               |  32 +++++------
 include/espressif/esp_timer.h                |   6 +-
 include/espressif/esp_wifi.h                 |  33 ++++++-----
 include/espressif/sdk_prototypes.h           |  23 ++++++--
 include/espressif/spi_flash.h                |  14 ++---
 ld/eagle.app.v6.ld                           |  18 +++---
 lib/libhal.a                                 | Bin 162888 -> 0 bytes
 lib/symbols_norename.txt                     |   6 ++
 lwip/esp_interface.c                         |   4 +-
 lwip/include/arch/cc.h                       |   8 +++
 lwip/include/arch/sys_arch.h                 |   2 +
 19 files changed, 220 insertions(+), 103 deletions(-)
 create mode 100644 include/esp8266.h
 delete mode 100644 lib/libhal.a
 create mode 100644 lib/symbols_norename.txt

diff --git a/FreeRTOS/Source/portable/esp8266/port.c b/FreeRTOS/Source/portable/esp8266/port.c
index 0aaed7b..42cb36a 100644
--- a/FreeRTOS/Source/portable/esp8266/port.c
+++ b/FreeRTOS/Source/portable/esp8266/port.c
@@ -99,7 +99,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
     SET_STKREG( XT_STK_A0,      0                           );  /* to terminate GDB backtrace       */
     SET_STKREG( XT_STK_A1,      (uint32_t)sp + XT_STK_FRMSZ   );  /* physical top of stack frame      */
     SET_STKREG( XT_STK_A2,      pvParameters   );           /* parameters      */
-    SET_STKREG( XT_STK_EXIT,    _xt_user_exit               );  /* user exception exit dispatcher   */
+    SET_STKREG( XT_STK_EXIT,    sdk__xt_user_exit               );  /* user exception exit dispatcher   */
 
     /* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user mode. */
     SET_STKREG( XT_STK_PS,      PS_UM | PS_EXCM     );
@@ -139,19 +139,19 @@ void PendSV(enum SVC_ReqType req)
  * after a Blob SV requests a soft interrupt by calling
  * PendSV(SVC_MACLayer).
  */
-extern portBASE_TYPE MacIsrSigPostDefHdl(void);
+extern portBASE_TYPE sdk_MacIsrSigPostDefHdl(void);
 
 void SV_ISR(void)
 {
 	portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE ;
 	if(pending_maclayer_sv)
 	{
-		xHigherPriorityTaskWoken = MacIsrSigPostDefHdl();
+		xHigherPriorityTaskWoken = sdk_MacIsrSigPostDefHdl();
 		pending_maclayer_sv = 0;
 	}
 	if( xHigherPriorityTaskWoken || pending_soft_sv)
 	{
-	    _xt_timer_int1();
+	    sdk__xt_timer_int1();
 	    pending_soft_sv = 0;
 	}
 }
@@ -175,14 +175,14 @@ void xPortSysTickHandle (void)
 portBASE_TYPE xPortStartScheduler( void )
 {
     _xt_isr_attach(ETS_SOFT_INUM, SV_ISR);
-    _xt_isr_unmask(1<<ETS_SOFT_INUM);
+    sdk__xt_isr_unmask(1<<ETS_SOFT_INUM);
 
     /* Initialize system tick timer interrupt and schedule the first tick. */
-    _xt_tick_timer_init();
+    sdk__xt_tick_timer_init();
 
     vTaskSwitchContext();
 
-    _xt_int_exit();
+    sdk__xt_int_exit();
 
     /* Should not get here as the tasks are now running! */
     return pdTRUE;
@@ -254,7 +254,7 @@ uint16_t _xt_isr_handler(uint16_t i)
 	}
     }
 
-    _xt_clear_ints(1<<index);
+    sdk__xt_clear_ints(1<<index);
 
     isr[index]();
 
diff --git a/FreeRTOS/Source/portable/esp8266/portmacro.h b/FreeRTOS/Source/portable/esp8266/portmacro.h
index 6cdf8c7..a41b1f7 100644
--- a/FreeRTOS/Source/portable/esp8266/portmacro.h
+++ b/FreeRTOS/Source/portable/esp8266/portmacro.h
@@ -183,18 +183,21 @@ not necessary for to use this port.  They are defined so the common demo files
 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
 /*-----------------------------------------------------------*/
 
+/* ESPTODO: These parts of the FreeRTOS support are still in binary libraries */
+#define vApplicationStackOverflowHook sdk_vApplicationStackOverflowHook
+
 /* XTensa interrupt management functions, used in port.c.
-   Implementations in blob libs */
-void        _xt_int_exit (void);
-void        _xt_user_exit (void);
-void        _xt_tick_timer_init (void);
-void        _xt_isr_unmask (uint32_t unmask);
-void        _xt_isr_mask (uint32_t mask);
-uint32_t    _xt_read_ints (void);
-void        _xt_clear_ints(uint32_t mask);
+   Some (w/ sdk_ prefix) are implemented in blob libs */
+void        sdk__xt_int_exit (void);
+void        sdk__xt_user_exit (void);
+void        sdk__xt_tick_timer_init (void);
+void        sdk__xt_isr_unmask (uint32_t unmask);
+void        sdk__xt_isr_mask (uint32_t mask);
+uint32_t    sdk__xt_read_ints (void);
+void        sdk__xt_clear_ints(uint32_t mask);
 typedef void (* _xt_isr)(void);
 void        _xt_isr_attach (uint8_t i, _xt_isr func);
-void	    _xt_timer_int1(void);
+void	    sdk__xt_timer_int1(void);
 
 #ifdef __cplusplus
 }
diff --git a/common.mk b/common.mk
index 1d17564..70309b9 100644
--- a/common.mk
+++ b/common.mk
@@ -55,11 +55,16 @@ OBJCOPY = $(CROSS)objcopy
 # of the root, with a 'component.mk' file.
 COMPONENTS     ?= FreeRTOS lwip
 
-# libraries to link, mainly blobs provided by the esp-iot-rtos SDK
-LIBS		?= gcc main net80211 phy pp ssl wpa hal
+# binary esp-iot-rtos SDK libraries to link. These are pre-processed prior to linking.
+SDK_LIBS		?= main net80211 phy pp wpa
+
+# open source libraries linked in
+LIBS ?= gcc hal
+
+ENTRY_SYMBOL ?= sdk_call_user_start
 
 CFLAGS		= -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals -std=gnu99
-LDFLAGS		= -nostdlib -Wl,--no-check-sections -Wl,-L$(ROOT)lib -u call_user_start -Wl,-static -Wl,-Map=build/${TARGET}.map
+LDFLAGS		= -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${TARGET}.map
 
 ifeq ($(FLAVOR),debug)
     CFLAGS += -g -O0
@@ -86,7 +91,8 @@ TARGET_DIR := $(dir $(firstword $(MAKEFILE_LIST)))
 ROOT := $(dir $(lastword $(MAKEFILE_LIST)))
 
 # derive various parts of compiler/linker arguments
-LIB_ARGS         = $(addprefix -l,$(LIBS))
+SDK_LIB_ARGS         = $(addprefix -l,$(SDK_LIBS))
+LIB_ARGS             = $(addprefix -l,$(LIBS))
 TARGET_OUT   = $(BUILD_DIR)$(TARGET).out
 LDFLAGS      += $(addprefix -T$(ROOT),$(LINKER_SCRIPTS))
 FW_FILE_1    = $(addprefix $(FW_BASE)/,$(FW_1).bin)
@@ -158,6 +164,37 @@ COMPONENT_ARS += $$($(1)_AR)
 -include $$($(1)_OBJ_FILES:.o=.d)
 endef
 
+
+## Linking rules for SDK libraries
+## SDK libraries are preprocessed to:
+# - prefix all defined symbols with 'sdk_'
+# - weaken all global symbols so they can be overriden from the open SDK side
+
+# SDK binary libraries are preprocessed into build/lib
+SDK_PROCESSED_LIBS = $(addsuffix .a,$(addprefix $(BUILD_DIR)sdklib/lib,$(SDK_LIBS)))
+
+# Make rule for preprocessing each SDK library
+#
+$(BUILD_DIR)sdklib/%.a: $(ROOT)lib/%.a $(BUILD_DIR)sdklib/allsymbols.rename
+	$(vecho) "Pre-processing SDK library $< -> $@"
+	$(Q) $(OBJCOPY) --redefine-syms $(word 2,$^) --weaken $< $@
+
+
+# Generate a regex to match symbols we don't want to rename, by parsing
+# a list of symbol names
+$(BUILD_DIR)sdklib/norename.match: $(ROOT)lib/symbols_norename.txt | $(BUILD_DIR)sdklib
+	grep -v "^#" $< | sed ':begin;$!N;s/\n/\\|/;tbegin' > $@
+
+# Generate list of symbols to rename from a single library. Uses grep & sed.
+$(BUILD_DIR)sdklib/%.rename: $(ROOT)lib/%.a $(BUILD_DIR)sdklib/norename.match
+	$(vecho) "Building symbol list for $< -> $@"
+	$(Q) $(NM) --defined $< | grep ' T ' | sed -r 's/(.+) T (.+)/\2 sdk_\2/' | grep -v `cat $(BUILD_DIR)sdklib/norename.match` > $@
+
+# Build master list of all SDK-defined symbols to rename
+$(BUILD_DIR)sdklib/allsymbols.rename: $(patsubst %.a,%.rename,$(SDK_PROCESSED_LIBS))
+	cat $^ > $@
+
+
 ## Include components (this is where the actual compiler sections are generated)
 $(foreach component,$(COMPONENTS), $(eval include $(ROOT)/$(component)/component.mk))
 
@@ -167,16 +204,16 @@ target_ROOT=$(TARGET_DIR)
 $(eval $(call component_compile_rules,target))
 
 # final linking step to produce .elf
-$(TARGET_OUT): $(COMPONENT_ARS)
+$(TARGET_OUT): $(COMPONENT_ARS) $(SDK_PROCESSED_LIBS)
 	$(vecho) "LD $@"
-	$(Q) $(LD) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIB_ARGS) $(COMPONENT_ARS) -Wl,--end-group -o $@
+	$(Q) $(LD) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(SDK_LIB_ARGS) $(LIB_ARGS) $(COMPONENT_ARS) -Wl,--end-group -o $@
 
-$(BUILD_DIR) $(FW_BASE):
+$(BUILD_DIR) $(FW_BASE) $(BUILD_DIR)sdklib:
 	$(Q) mkdir -p $@
 
 $(FW_FILE_1) $(FW_FILE_2): $(TARGET_OUT) $(FW_BASE)
 	$(vecho) "FW $@"
-	$(ESPTOOL) elf2image $< -o $(FW_BASE)
+	$(ESPTOOL) elf2image --entry-symbol $(ENTRY_SYMBOL) $< -o $(FW_BASE)
 
 flash: $(FW_FILE_1) $(FW_FILE_2)
 	$(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) write_flash $(FW_1) $(FW_FILE_1) $(FW_2) $(FW_FILE_2)
@@ -196,3 +233,7 @@ rebuild:
 clean:
 	$(Q) rm -rf $(BUILD_DIR)
 	$(Q) rm -rf $(FW_BASE)
+
+# prevent "intermediate" files from being deleted
+.SECONDARY:
+
diff --git a/examples/http_get/main.c b/examples/http_get/main.c
index fc12910..6af7e34 100644
--- a/examples/http_get/main.c
+++ b/examples/http_get/main.c
@@ -109,17 +109,17 @@ void http_get_task(void *pvParameters)
 
 void user_init(void)
 {
-    uart_div_modify(0, UART_CLK_FREQ / 115200);
-    printf("SDK version:%s\n", system_get_sdk_version());
+    sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
+    printf("SDK version:%s\n", sdk_system_get_sdk_version());
 
-    struct station_config config = {
+    struct sdk_station_config config = {
 	.ssid = WIFI_SSID,
 	.password = WIFI_PASS,
     };
 
     /* required to call wifi_set_opmode before station_set_config */
-    wifi_set_opmode(STATION_MODE);
-    wifi_station_set_config(&config);
+    sdk_wifi_set_opmode(STATION_MODE);
+    sdk_wifi_station_set_config(&config);
 
     xTaskCreate(&http_get_task, (signed char *)"get_task", 256, NULL, 2, NULL);
 }
diff --git a/include/esp8266.h b/include/esp8266.h
new file mode 100644
index 0000000..a58a9be
--- /dev/null
+++ b/include/esp8266.h
@@ -0,0 +1,33 @@
+/* esp8266.h
+ *
+ * ESP-specific SoC-level addresses, macros, etc.
+ * Part of esp-open-rtos
+ *
+ * Copyright (C) 2105 Superhouse Automation Pty Ltd
+ * BSD Licensed as described in the file LICENSE
+ */
+#include <stdint.h>
+
+#ifndef _ESP8266_H
+#define _ESP8266_H
+
+/* Use this macro to store constant values in IROM flash instead
+   of having them loaded into rodata (which resides in DRAM)
+
+   Unlike the ESP8266 SDK you don't need an attribute like this for
+   standard functions. They're stored in flash by default. But
+   variables need them.
+
+   Important to note: IROM flash can only be accessed via 32-bit word
+   aligned reads. It's up to the user of this attribute to ensure this.
+*/
+#define IROM __attribute__((section(".irom0"))) const
+
+
+/* Register addresses
+
+   ESPTODO: break this out to its own header file and clean it up, add other regs, etc.
+*/
+static volatile __attribute__((unused)) uint32_t *ESP_REG_WDT = (uint32_t *)0x60000900;
+
+#endif
diff --git a/include/espressif/esp_misc.h b/include/espressif/esp_misc.h
index 68d9724..d8ce65e 100644
--- a/include/espressif/esp_misc.h
+++ b/include/espressif/esp_misc.h
@@ -18,9 +18,9 @@
 
 #define IPSTR "%d.%d.%d.%d"
 
-void os_delay_us(uint16_t us);
+void sdk_os_delay_us(uint16_t us);
 
-void os_install_putc1(void (*p)(char c));
-void os_putc(char c);
+void sdk_os_install_putc1(void (*p)(char c));
+void sdk_os_putc(char c);
 
 #endif
diff --git a/include/espressif/esp_softap.h b/include/espressif/esp_softap.h
index c2bbe42..44f06cc 100644
--- a/include/espressif/esp_softap.h
+++ b/include/espressif/esp_softap.h
@@ -6,7 +6,7 @@
 #ifndef __ESP_SOFTAP_H__
 #define __ESP_SOFTAP_H__
 
-struct softap_config {
+struct sdk_softap_config {
     uint8_t ssid[32];
     uint8_t password[64];
     uint8_t ssid_len;
@@ -17,7 +17,7 @@ struct softap_config {
     uint16_t beacon_interval;
 };
 
-bool wifi_softap_get_config(struct softap_config *config);
-bool wifi_softap_set_config(struct softap_config *config);
+bool sdk_wifi_softap_get_config(struct sdk_softap_config *config);
+bool sdk_wifi_softap_set_config(struct sdk_softap_config *config);
 
 #endif
diff --git a/include/espressif/esp_sta.h b/include/espressif/esp_sta.h
index 779242f..8b9059a 100644
--- a/include/espressif/esp_sta.h
+++ b/include/espressif/esp_sta.h
@@ -1,6 +1,8 @@
 /*
  *  Copyright (C) 2013 -2014  Espressif System
  *
+ *
+ * Adapted from BSD licensed esp_iot_rtos_sdk v0.9.9
  */
 
 #ifndef __ESP_STA_H__
@@ -8,27 +10,27 @@
 
 #include "queue.h"
 
-struct station_config {
+struct sdk_station_config {
     uint8_t ssid[32];
     uint8_t password[64];
     uint8_t bssid_set;
     uint8_t bssid[6];
 };
 
-bool wifi_station_get_config(struct station_config *config);
-bool wifi_station_set_config(struct station_config *config);
+bool sdk_wifi_station_get_config(struct sdk_station_config *config);
+bool sdk_wifi_station_set_config(struct sdk_station_config *config);
 
-bool wifi_station_connect(void);
-bool wifi_station_disconnect(void);
+bool sdk_wifi_station_connect(void);
+bool sdk_wifi_station_disconnect(void);
 
-struct scan_config {
+struct sdk_scan_config {
     uint8_t *ssid;
     uint8_t *bssid;
     uint8_t channel;
     uint8_t show_hidden;
 };
 
-struct bss_info {
+struct sdk_bss_info {
     STAILQ_ENTRY(bss_info)     next;
 
     uint8_t bssid[6];
@@ -46,14 +48,14 @@ typedef enum {
     SCAN_PENDING,
     SCAN_BUSY,
     SCAN_CANCEL,
-} scan_status_t;
+} sdk_scan_status_t;
 
-typedef void (* scan_done_cb_t)(void *arg, scan_status_t status);
+typedef void (* sdk_scan_done_cb_t)(void *arg, sdk_scan_status_t status);
 
-bool wifi_station_scan(struct scan_config *config, scan_done_cb_t cb);
+bool sdk_wifi_station_scan(struct sdk_scan_config *config, sdk_scan_done_cb_t cb);
 
-uint8_t wifi_station_get_auto_connect(void);
-bool wifi_station_set_auto_connect(uint8_t set);
+uint8_t sdk_wifi_station_get_auto_connect(void);
+bool sdk_wifi_station_set_auto_connect(uint8_t set);
 
 enum {
     STATION_IDLE = 0,
@@ -64,6 +66,6 @@ enum {
     STATION_GOT_IP
 };
 
-uint8_t wifi_station_get_connect_status(void);
+uint8_t sdk_wifi_station_get_connect_status(void);
 
 #endif
diff --git a/include/espressif/esp_system.h b/include/espressif/esp_system.h
index be3e6a0..265bc8c 100644
--- a/include/espressif/esp_system.h
+++ b/include/espressif/esp_system.h
@@ -6,14 +6,14 @@
 #ifndef __ESP_SYSTEM_H__
 #define __ESP_SYSTEM_H__
 
-enum rst_reason {
+enum sdk_rst_reason {
 	DEFAULT_RST	  = 0,
 	WDT_RST	      = 1,
 	EXCEPTION_RST = 2,
 	SOFT_RST      = 3
 };
 
-struct rst_info{
+struct sdk_rst_info{
 	uint32_t reason;
 	uint32_t exccause;
 	uint32_t epc1;
@@ -24,26 +24,26 @@ struct rst_info{
 	uint32_t rtn_addr;
 };
 
-struct rst_info* system_get_rst_info(void);
+struct rst_info* sdk_system_get_rst_info(void);
 
-const char* system_get_sdk_version(void);
+const char* sdk_system_get_sdk_version(void);
 
-void system_restore(void);
-void system_restart(void);
-void system_deep_sleep(uint32_t time_in_us);
+void sdk_system_restore(void);
+void sdk_system_restart(void);
+void sdk_system_deep_sleep(uint32_t time_in_us);
 
-uint32_t system_get_time(void);
+uint32_t sdk_system_get_time(void);
 
-void system_print_meminfo(void);
-uint32_t system_get_free_heap_size(void);
-uint32_t system_get_chip_id(void);
+void sdk_system_print_meminfo(void);
+uint32_t sdk_system_get_free_heap_size(void);
+uint32_t sdk_system_get_chip_id(void);
 
-uint32_t system_rtc_clock_cali_proc(void);
-uint32_t system_get_rtc_time(void);
+uint32_t sdk_system_rtc_clock_cali_proc(void);
+uint32_t sdk_system_get_rtc_time(void);
 
-bool system_rtc_mem_read(uint8_t src, void *dst, uint16_t n);
-bool system_rtc_mem_write(uint8_t dst, const void *src, uint16_t n);
+bool sdk_system_rtc_mem_read(uint8_t src, void *dst, uint16_t n);
+bool sdk_system_rtc_mem_write(uint8_t dst, const void *src, uint16_t n);
 
-void system_uart_swap(void);
+void sdk_system_uart_swap(void);
 
 #endif
diff --git a/include/espressif/esp_timer.h b/include/espressif/esp_timer.h
index 8ba6295..6f05547 100644
--- a/include/espressif/esp_timer.h
+++ b/include/espressif/esp_timer.h
@@ -7,16 +7,16 @@
 #define __ESP_TIMER_H__
 
 /* timer related */
-typedef void os_timer_func_t(void *timer_arg);
+typedef void sdk_os_timer_func_t(void *timer_arg);
 
 typedef struct _os_timer_t {
 	struct _os_timer_t *timer_next;
     void               *freerots_handle;
     uint32_t             timer_expire;
     uint32_t             timer_period;
-    os_timer_func_t    *timer_func;
+    sdk_os_timer_func_t    *timer_func;
     bool               timer_repeat_flag;
     void               *timer_arg;
-} os_timer_t;
+} sdk_os_timer_t;
 
 #endif
diff --git a/include/espressif/esp_wifi.h b/include/espressif/esp_wifi.h
index 08824d6..e2274f1 100644
--- a/include/espressif/esp_wifi.h
+++ b/include/espressif/esp_wifi.h
@@ -1,6 +1,9 @@
 /*
  *  Copyright (C) 2013 -2014  Espressif System
  *
+ * Adapted from BSD licensed esp_iot_rtos_sdk v0.9.9
+ *
+ * Functions declared in this header are defined in libmain.a
  */
 
 #ifndef __ESP_WIFI_H__
@@ -23,8 +26,8 @@ typedef enum _auth_mode {
     AUTH_MAX
 } AUTH_MODE;
 
-uint8_t wifi_get_opmode(void);
-bool wifi_set_opmode(uint8_t opmode);
+uint8_t sdk_wifi_get_opmode(void);
+bool sdk_wifi_set_opmode(uint8_t opmode);
 
 enum {
 	STATION_IF = 0,
@@ -38,29 +41,29 @@ struct ip_info {
     struct ip_addr gw;
 };
 
-bool wifi_get_ip_info(uint8_t if_index, struct ip_info *info);
-bool wifi_set_ip_info(uint8_t if_index, struct ip_info *info);
-bool wifi_get_macaddr(uint8_t if_index, uint8_t *macaddr);
-bool wifi_set_macaddr(uint8_t if_index, uint8_t *macaddr);
+bool sdk_wifi_get_ip_info(uint8_t if_index, struct ip_info *info);
+bool sdk_wifi_set_ip_info(uint8_t if_index, struct ip_info *info);
+bool sdk_wifi_get_macaddr(uint8_t if_index, uint8_t *macaddr);
+bool sdk_wifi_set_macaddr(uint8_t if_index, uint8_t *macaddr);
 
-uint8_t wifi_get_channel(void);
-bool wifi_set_channel(uint8_t channel);
+uint8_t sdk_wifi_get_channel(void);
+bool sdk_wifi_set_channel(uint8_t channel);
 
-void wifi_status_led_install(uint8_t gpio_id, uint32_t gpio_name, uint8_t gpio_func);
+void sdk_wifi_status_led_install(uint8_t gpio_id, uint32_t gpio_name, uint8_t gpio_func);
 
-void wifi_promiscuous_enable(uint8_t promiscuous);
+void sdk_wifi_promiscuous_enable(uint8_t promiscuous);
 
-typedef void (* wifi_promiscuous_cb_t)(uint8_t *buf, uint16_t len);
+typedef void (* sdk_wifi_promiscuous_cb_t)(uint8_t *buf, uint16_t len);
 
-void wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb);
+void sdk_wifi_set_promiscuous_rx_cb(sdk_wifi_promiscuous_cb_t cb);
 
-enum phy_mode {
+enum sdk_phy_mode {
 	PHY_MODE_11B	= 1,
 	PHY_MODE_11G	= 2,
 	PHY_MODE_11N    = 3
 };
 
-enum phy_mode wifi_get_phy_mode(void);
-bool wifi_set_phy_mode(enum phy_mode mode);
+enum phy_mode sdk_wifi_get_phy_mode(void);
+bool sdk_wifi_set_phy_mode(enum sdk_phy_mode mode);
 
 #endif
diff --git a/include/espressif/sdk_prototypes.h b/include/espressif/sdk_prototypes.h
index 2817a72..4b5e3df 100644
--- a/include/espressif/sdk_prototypes.h
+++ b/include/espressif/sdk_prototypes.h
@@ -1,6 +1,11 @@
-/* This source file contains function prototypes for functions defined
+/* sdk_prototypes.h
+
+   This source file contains function prototypes for functions defined
    in the remaining "binary blob" ESP IoT RTOS SDK libraries. Sorted
    by which library they appear in.
+
+   Function names here have the 'sdk_' prefix that is put on all binary library functions
+   by the Open RTOS SDK.
 */
 #ifndef SDK_PROTOTYPES_H
 #define SDK_PROTOTYPES_H
@@ -18,18 +23,28 @@ struct ip_addr;
    uart_no = 0 or 1 for which UART
    new_divisor = Calculated in the form UART_CLK_FREQ / BAUD
  */
-void uart_div_modify(uint32_t uart_no, uint32_t new_divisor);
+void sdk_uart_div_modify(uint32_t uart_no, uint32_t new_divisor);
+
+/* Read a single character from the UART.
+ */
+char sdk_uart_rx_one_char(void);
+
+/* Write a single character to the UART.
+ */
+void sdk_os_putc(char c);
 
 /* Called when an IP gets set on the "station" (client) interface.
  */
-void system_station_got_ip_set(struct ip_addr *ip_addr, struct ip_addr *sn_mask, struct ip_addr *gw_addr);
+void sdk_system_station_got_ip_set(struct ip_addr *ip_addr, struct ip_addr *sn_mask, struct ip_addr *gw_addr);
 
 /* This is a no-op wrapper around ppRecycleRxPkt, which is defined in libpp.a
 
    It's called when a pbuf is freed, and allows pp to reuse the 'eb' pointer to ESP-specific
    pbuf data. (See esp-lwip pbuf.h)
  */
-void system_pp_recycle_rx_pkt(void *eb);
+void sdk_system_pp_recycle_rx_pkt(void *eb);
+
+const char* sdk_system_get_sdk_version(void);
 
 
 #endif
diff --git a/include/espressif/spi_flash.h b/include/espressif/spi_flash.h
index b4761f4..719c045 100644
--- a/include/espressif/spi_flash.h
+++ b/include/espressif/spi_flash.h
@@ -10,15 +10,15 @@ typedef enum {
     SPI_FLASH_RESULT_OK,
     SPI_FLASH_RESULT_ERR,
     SPI_FLASH_RESULT_TIMEOUT
-} SpiFlashOpResult;
+} sdk_SpiFlashOpResult;
 
 #define SPI_FLASH_SEC_SIZE      4096
 
-uint32_t spi_flash_get_id(void);
-SpiFlashOpResult spi_flash_read_status(uint32_t *status);
-SpiFlashOpResult spi_flash_write_status(uint32_t status_value);
-SpiFlashOpResult spi_flash_erase_sector(uint16_t sec);
-SpiFlashOpResult spi_flash_write(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
-SpiFlashOpResult spi_flash_read(uint32_t src_addr, uint32_t *des_addr, uint32_t size);
+uint32_t sdk_spi_flash_get_id(void);
+sdk_SpiFlashOpResult sdk_spi_flash_read_status(uint32_t *status);
+sdk_SpiFlashOpResult sdk_spi_flash_write_status(uint32_t status_value);
+sdk_SpiFlashOpResult sdk_spi_flash_erase_sector(uint16_t sec);
+sdk_SpiFlashOpResult sdk_spi_flash_write(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
+sdk_SpiFlashOpResult sdk_spi_flash_read(uint32_t src_addr, uint32_t *des_addr, uint32_t size);
 
 #endif
diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld
index daeff21..538a6c5 100644
--- a/ld/eagle.app.v6.ld
+++ b/ld/eagle.app.v6.ld
@@ -1,4 +1,8 @@
-/* This linker script generated from xt-genldscripts.tpp for LSP . */
+/* This linker script generated from xt-genldscripts.tpp for LSP .
+
+   Modified for esp open RTOS, this linker script is no longer the same as the esp_iot_rtos_sdk one.
+*/
+
 /* Linker Script for ld -N */
 MEMORY
 {
@@ -19,12 +23,12 @@ PHDRS
 
 
 /*  Default entry point:  */
-ENTRY(call_user_start)
-EXTERN(_DebugExceptionVector)
-EXTERN(_DoubleExceptionVector)
-EXTERN(_KernelExceptionVector)
-EXTERN(_NMIExceptionVector)
-EXTERN(_UserExceptionVector)
+ENTRY(sdk_call_user_start)
+EXTERN(sdk__DebugExceptionVector)
+EXTERN(sdk__DoubleExceptionVector)
+EXTERN(sdk__KernelExceptionVector)
+EXTERN(sdk__NMIExceptionVector)
+EXTERN(sdk__UserExceptionVector)
 PROVIDE(_memmap_vecbase_reset = 0x40000000);
 /* Various memory-map dependent cache attribute settings: */
 _memmap_cacheattr_wb_base = 0x00000110;
diff --git a/lib/libhal.a b/lib/libhal.a
deleted file mode 100644
index 728a0184b3ed8a0a8a65b929ae8262a74140675d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 162888
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
KXFxQ;@;Lw?n+)Xu

diff --git a/lib/symbols_norename.txt b/lib/symbols_norename.txt
new file mode 100644
index 0000000..8d762b4
--- /dev/null
+++ b/lib/symbols_norename.txt
@@ -0,0 +1,6 @@
+# this is a stop-gap to avoid renaming some useful libc
+# symbols to sdk_xxx
+puts
+printf
+putchar
+atoi
diff --git a/lwip/esp_interface.c b/lwip/esp_interface.c
index 034c1b6..6f37b5a 100644
--- a/lwip/esp_interface.c
+++ b/lwip/esp_interface.c
@@ -47,7 +47,7 @@
 #include "netif/etharp.h"
 
 /* declared in libnet80211.a */
-int8_t ieee80211_output_pbuf(struct netif *ifp, struct pbuf* pb);
+int8_t sdk_ieee80211_output_pbuf(struct netif *ifp, struct pbuf* pb);
 
 static err_t
 low_level_output(struct netif *netif, struct pbuf *p)
@@ -55,7 +55,7 @@ low_level_output(struct netif *netif, struct pbuf *p)
   struct pbuf *q;
 
   for(q = p; q != NULL; q = q->next) {
-      ieee80211_output_pbuf(netif, q);
+      sdk_ieee80211_output_pbuf(netif, q);
   }
 
   LINK_STATS_INC(link.xmit);
diff --git a/lwip/include/arch/cc.h b/lwip/include/arch/cc.h
index 507409c..fe10d25 100644
--- a/lwip/include/arch/cc.h
+++ b/lwip/include/arch/cc.h
@@ -35,6 +35,14 @@
 /* include ESP SDK prototypes as they're used in some LWIP routines */
 #include "espressif/sdk_prototypes.h"
 
+/* ESP8266 SDK Interface
+
+   The lwip-esp stack is designed to be also compatible with other ESP8266 SDKs,
+   so we can't use our 'sdk_' prefixes there
+*/
+#define system_station_got_ip_set sdk_system_station_got_ip_set
+#define system_pp_recycle_rx_pkt sdk_system_pp_recycle_rx_pkt
+
 /* Include some files for defining library routines */
 #include <stdio.h> /* printf, fflush, FILE */
 #include <stdlib.h> /* abort */
diff --git a/lwip/include/arch/sys_arch.h b/lwip/include/arch/sys_arch.h
index 3daf87b..ac616c9 100644
--- a/lwip/include/arch/sys_arch.h
+++ b/lwip/include/arch/sys_arch.h
@@ -37,6 +37,8 @@
 #include "queue.h"
 #include "semphr.h"
 
+/* MBOX primitives */
+
 #define SYS_MBOX_NULL					( ( xQueueHandle ) NULL )
 #define SYS_SEM_NULL					( ( xSemaphoreHandle ) NULL )
 #define SYS_DEFAULT_THREAD_STACK_DEPTH	configMINIMAL_STACK_SIZE