SylixOS environment variable initialization process

1. Each environment variable is an object, and the core members are two string pointers of variable name and variable value, which are managed by two linked lists.

typedef struct {
    LW_LIST_LINE SV_lineManage; /* Double linked list for management */
    LW_LIST_LINE SV_lineHash; /* hash separation linked list */

    PCHAR SV_pcVarName; /* variable name */
    PCHAR SV_pcVarValue; /* variable value */
    
    ULONG SV_ulRefCnt; /* reference count */
} __TSHELL_VAR;
typedef __TSHELL_VAR *__PTSHELL_VAR; /* pointer type */

2. The two doubly-linked lists are the double-linked list for management and the hash-separated linked list. The hash-separated linked list is mainly for improving the search speed. Both linked lists are empty by default, so the environment variable is empty when the kernel is just started.

static PLW_LIST_LINE _G_plineTSVarHeader = LW_NULL; /* unified list header */
static PLW_LIST_LINE _G_plineTSVarHeaderHashTbl[LW_CFG_SHELL_VAR_HASH_SIZE];
                                                                        /* hash hash table */

3. After the kernel starts, call the __tshellSysVarInit function (located in the libsylixos\SylixOS\shell\ttinyShell\ttinyShellSysVar.c file) to register the system default environment variables with the shell command item kernel. So even if there is no /etc/profile file in the file system, there will be some default environment variables.

VOID __tshellSysVarInit (VOID)
{
    /*
     *  system message
     */
    API_TShellExec("SYSTEM="" __SYLIXOS_VERINFO """);
    API_TShellExec("VERSION="" __SYLIXOS_VERSTR """);
    API_TShellExec("LICENSE="" __SYLIXOS_LICENSE """);

    API_TShellExec("TMPDIR=" LW_CFG_TMP_PATH);
    API_TShellExec("TZ=CST-8:00:00"); /* The default is Eastern District 8 */
    API_TShellExec("STARTUP_WAIT_SEC=1"); /* Execute startup.sh delay time */
                                                                        /* between 0 ~ 10 */
    /*
     *  graphic interface
     */
    API_TShellExec("KEYBOARD=/dev/input/keyboard0"); /* HID device */
    API_TShellExec("MOUSE=/dev/input/mouse0:/dev/input/touch0");
    
    API_TShellExec("TSLIB_TSDEVICE=/dev/input/touch0"); /* touch screen calibration associated device */
    API_TShellExec("TSLIB_CALIBFILE=/etc/pointercal"); /* touch screen calibration file */
    
    /*
     * SO_MEM_PAGES: The number of pages in the application's initial heap memory space.
     * SO_MEM_MBYTES: The application's initial heap memory space in megabytes (used first)
     * SO_MEM_DIRECT: The application is not allowed to allocate memory using page fault interrupts.
     * SO_MEM_CONTIN: The application is not allowed to use page fault interrupt to allocate memory, and the memory must be continuous in physical space.
     */
#if !defined(LW_CFG_CPU_ARCH_C6X)
    API_TShellExec("SO_MEM_PAGES=8192"); /* Number of dynamic memory virtual pages */
                                                                        /* Default is 32 MB */
#else
    API_TShellExec("SO_MEM_PAGES=256"); /* Number of dynamic memory virtual pages 2MB */
#endif
    API_TShellExec("SO_MEM_DIRECT=0"); /* Whether the process MEM is opened directly */
                                                                        /* Do not use page fault interrupts (not recommended) */
#if LW_KERN_FLOATING > 0
    API_TShellExec("KERN_FLOAT=1"); /* Kernel supports floating point format */
#else
    API_TShellExec("KERN_FLOAT=0"); /* kernel does not support floating point format */
#endif /* LW_KERN_FLOATING */

#if LW_CFG_POSIX_EN > 0
    API_TShellExec("SYSLOGD_HOST=0.0.0.0:514"); /* syslog server address */
#endif

    API_TShellExec("NFS_CLIENT_AUTH=AUTH_UNIX"); /* NFS uses auth_unix by default */
    API_TShellExec("NFS_CLIENT_PROTO=udp"); /* NFS uses udp protocol by default */

    API_TShellExec("PATH=" _PATH_DEFPATH); /* PATH default path at startup */
    API_TShellExec("LD_LIBRARY_PATH=" _PATH_LIBPATH); /* LD_LIBRARY_PATH default */
    
    /*
     * Multilingual and encoding
     */
    API_TShellExec("LANG=C"); /* The system default locale is "C" */
    API_TShellExec("LC_ALL="); /* It is recommended not to use this variable */
    API_TShellExec("PATH_LOCALE=" _PATH_LOCALE); /* NOTE: Requires UTF-8 from BSD system*/
                                                                        /* directory copied here */
    /*
     * debug
     */
#if LW_CFG_GDB_EN > 0
    API_TShellExec("DEBUG_CPU=-1"); /* Whether to lock the called object to a CPU*/
    API_TShellExec("DEBUG_CRASHTRAP=0"); /* Whether to crashtrap all processes */
#endif /* LW_CFG_GDB_EN > 0 */
    
#if LW_CFG_NET_LOGINBL_EN > 0
    API_TShellExec("LOGINBL_TO=120"); /* Network login blacklist refresh time */
    API_TShellExec("LOGINBL_REP=3"); /* If it appears several times in a row, it will be added to the blacklist */
#endif /* LW_CFG_GDB_EN > 0 */
    
    /*
     * Process default control
     */
#if LW_CFG_MODULELOADER_EN > 0
    API_TShellExec("VPROC_EXIT_FORCE=0"); /* 1: Main thread exits and automatically deletes child threads */
    API_TShellExec("VPROC_MODULE_SHOW=0"); /* 1: Print module information when the process starts */
#endif /* LW_CFG_MODULELOADER_EN > 0 */
    
    /*
     * LUA environment
     */
    API_TShellExec("LUA_PATH=?.lua;/usr/local/lib/lua/?.lua;/usr/lib/lua/?.lua;/lib/lua/?.lua");
    API_TShellExec("LUA_CPATH=?.so;/usr/local/lib/lua/?.so;/usr/lib/lua/?.so;/lib/lua/?.so");
    
    /*
     * terminal
     */
    API_TShellExec("TERM=vt100");
    API_TShellExec("TERMCAP=/etc/termcap"); /* BSD terminal escape */
    API_TShellExec("TERM_PS_COLOR="); /* command prompt color eg. "01;32" */
}

4. Then the system tries to load the /etc/profile configuration file through the shell command “varload”. If the file exists and is valid, it will modify or increase the system environment variables according to this file.
5. Afterwards, the system continuously modifies or increases the system environment variables through the startup.sh script or user commands or applications.