lin
2025-01-10 9ec4e21f2f615ef95b70a249569906799e36bace
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// SPDX-License-Identifier: GPL-2.0+
 
#include <common.h>
#include <environment.h>
 
static int __check_systemAB(void)
{
   char *systemA = env_get("systemA");
   char *systemB = env_get("systemB");
   char *rootfsA = env_get("rootfsA");
   char *rootfsB = env_get("rootfsB");
 
   if (!systemA || !rootfsA) {
       printf("CHECK SYSTEM ERROR : env can't find systemA or rootfsA!!\n");
       return -1;
   }
   if (!systemB || !rootfsB) {
       printf("CHECK SYSTEM ERROR : env can't find systemB or rootfsB!!\n");
       return -1;
   }
 
   return 0;
}
 
//note:systemAB_now can only be modified by this function
static int __switch_systemAB(char *system)
{
   char tmp_system[5] = {0};
   char *systemA = NULL;
   char *systemB = NULL;
   char *rootfsA = NULL;
   char *rootfsB = NULL;
   char *systemAB_damage = env_get("systemAB_damage");
   char *systemAB_now = env_get("systemAB_now");
   memcpy(tmp_system, system, sizeof(tmp_system));
 
   if (!strcmp(tmp_system, "A")) {
       if (strcmp(systemAB_damage, "A"))
           printf("SWITCH WARNING : systemA is damaged\n");
 
       if ((!strcmp(systemAB_now, "B")) || (!systemAB_now)) {
           systemA = env_get("systemA");
           rootfsA = env_get("rootfsA");
           env_set("boot_partition", systemA);
           env_set("root_partition", rootfsA);
           env_set("systemAB_now", "A");
           env_save();
           printf("boot system %s\n", tmp_system);
           return 0;
       }
   } else if (!strcmp(tmp_system, "B")) {
       if (strcmp(systemAB_damage, "B"))
           printf("SWITCH WARNING : systemB is damaged\n");
 
       if ((!strcmp(systemAB_now, "A")) || (!systemAB_now)) {
           systemB = env_get("systemB");
           rootfsB = env_get("rootfsB");
           env_set("boot_partition", systemB);
           env_set("root_partition", rootfsB);
           env_set("systemAB_now", "B");
           env_save();
           printf("boot system %s\n", tmp_system);
           return 0;
       }
   } else {
       printf("SWITCH ERROR : input system is %s\n", tmp_system);
       printf("               Please input A or B system\n");
       return -1;
   }
   return 0;
}
 
//The system will switch according to systemab_next
int sunxi_auto_switch_system(void)
{
   char *systemAB_next = env_get("systemAB_next");
 
   if (!systemAB_next) {
       printf("AUTO SWITCH WARNING : Can't get systemAB_next\n");
       printf("                      Started system by default\n");
       return 0;
   }
   if (strcmp(systemAB_next, "A") && strcmp(systemAB_next, "B")) {
       printf("AUTO SWITCH WARNING : systemAB_next(%s) is neither A nor B\n", systemAB_next);
       printf("                      Started system by default\n");
       return 0;
   }
 
   if (__check_systemAB()) {
       printf("AUTO SWITCH ERROR : Check systemAB fail\n");
       return -1;
   }
 
   if (!strcmp(systemAB_next, "A")) {
       if (__switch_systemAB("A")) {
               printf("AUTO SWITCH ERROR : Switch to systemA fail\n");
               return -1;
           }
       }
   else {
       if (__switch_systemAB("B")) {
               printf("AUTO SWITCH ERROR : Switch to systemB fail\n");
               return -1;
           }
       }
 
   return 0;
}
 
//note:systemAB_damage can only be modified by this function
int sunxi_damage_switch_system(void)
{
   printf("==========DAMAGE SWITCH NOW==========\n");
   char *systemAB_next = env_get("systemAB_next");
 
   if (!systemAB_next) {
       printf("DAMAGE SWITCH ERROR : Can't get systemAB_next\n");
       printf("                      Please check the systemAB_next\n");
       return -1;
   }
 
   if (__check_systemAB()) {
       printf("DAMAGE SWITCH ERROR : Check systemAB fail\n");
       return -1;
   }
 
   if (!strcmp(systemAB_next, "A")) {
       printf("DAMAGE SWITCH : systemA is damaged;now switch to systemB\n");
       if (!__switch_systemAB("B")) {
           env_set("systemAB_next", "B");
           env_set("systemAB_damage", "A");
           bootcount_store(0);
#ifndef CONFIG_BOOTCOUNT_ENV
           /*
            * If CONFIG_BOOTCOUNT_ENV is defined,
            * there is no need to call env_save function to save the data to env,
            * because the bootcount_store function contains the env_save function
            *
            * If CONFIG_BOOTCOUNT_ENV is not defined,
            * need to call env_save function to save the data to env,
            * because the bootcount_store function does not include
            * the env_save function at this time.
            */
           env_save();
#endif
       } else {
           printf("DAMAGE SWITCH ERROR:Switch to systemB fail\n");
           return -1;
       }
   } else {
       printf("DAMAGE SWITCH : systemB is damaged ;now switch to systemA\n");
       if (!__switch_systemAB("A")) {
           env_set("systemAB_next", "A");
           env_set("systemAB_damage", "B");
           bootcount_store(0);
#ifndef CONFIG_BOOTCOUNT_ENV
           /* The situation is the same as the comment above */
           env_save();
#endif
       } else {
           printf("DAMAGE SWITCH ERROR : Switch to systemA fail\n");
           return -1;
       }
   }
 
   return 0;
}