• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 #include "defs.h"
13 #include <errno.h>
14 #include <string.h>
15 #include <fcntl.h>
16 #include <pthread.h>
17 #include <stdio.h>
18 #include <chcore-internal/fs_defs.h>
19 #include <chcore/ipc.h>
20 #include <chcore/services.h>
21 
22 #include "device.h"
23 
24 #define UNUSED(x) (void)(x)
25 
26 /*
27  * partition informations
28  */
29 static device_partition_t dparts[5];
30 
31 /* lock to protect 'dparts' */
32 static pthread_mutex_t dparts_lock = PTHREAD_MUTEX_INITIALIZER;
33 
34 /* whether fill the 'dparts' */
35 static bool dparts_inited = false;
36 
initialize_dparts(void)37 static void initialize_dparts(void)
38 {
39     memcpy(dparts[0].device_name, "sda1", 5);
40     memcpy(dparts[1].device_name, "sda2", 5);
41     memcpy(dparts[2].device_name, "sda3", 5);
42     memcpy(dparts[3].device_name, "sda4", 5);
43     memcpy(dparts[4].device_name, "sda5", 5);
44 }
45 
chcore_parse_devices(void)46 static int chcore_parse_devices(void)
47 {
48     return -1;
49 }
50 
51 /*
52  * @arg: 'device_name' is like 'sda1'...etc
53  * @return: device_partition_t* dparts, 0 for any error
54  */
chcore_get_server(const char * device_name)55 device_partition_t *chcore_get_server(const char *device_name)
56 {
57     int i;
58 
59     for (i = 0; i < MAX_PARTS_CNT; i++)
60         if (strcmp(dparts[i].device_name, device_name) == 0)
61             return &(dparts[i]);
62 
63     printf("[debug %d] can't find server id\n", __LINE__);
64     return 0;
65 }
66 
67 /*
68  * @arg: 'fs_cap' is fatfs server_cap, 'partition' is partition_index in device
69  * @return: error code returned by fatfs server
70  */
chcore_initial_fat_partition(cap_t fs_cap,int partition)71 int chcore_initial_fat_partition(cap_t fs_cap, int partition)
72 {
73     int ret;
74     ipc_msg_t *ipc_msg;
75     struct fs_request *fr_ptr;
76     ipc_struct_t *ipc_struct = ipc_register_client(fs_cap);
77     ipc_msg = ipc_create_msg(ipc_struct, sizeof(struct fs_request));
78     fr_ptr = (struct fs_request *)ipc_get_msg_data(ipc_msg);
79 
80     fr_ptr->req = FS_REQ_MOUNT;
81     fr_ptr->mount.paritition = partition;
82 
83     ipc_set_msg_data(ipc_msg, (char *)fr_ptr, 0, sizeof(struct fs_request));
84     ret = ipc_call(ipc_struct, ipc_msg);
85     ipc_destroy_msg(ipc_msg);
86 
87     return ret;
88 }
89 
90 /*
91  * Once start a ext4fs server, transform parititon offset to server using
92  * FS_REQ_MOUNT
93  * @arg: 'fs_cap' is ext4fs server_cap, 'partition_lba' is partition offset
94  * @return: error code returned by ext4fs server
95  */
chcore_initial_ext4_partition(int fs_cap,uint64_t partition_lba)96 int chcore_initial_ext4_partition(int fs_cap, uint64_t partition_lba)
97 {
98     int ret;
99     ipc_msg_t *ipc_msg;
100     struct fs_request *fr_ptr;
101     ipc_struct_t *ipc_struct = ipc_register_client(fs_cap);
102     ipc_msg = ipc_create_msg(ipc_struct, sizeof(struct fs_request));
103     fr_ptr = (struct fs_request *)ipc_get_msg_data(ipc_msg);
104 
105     fr_ptr->req = FS_REQ_MOUNT;
106     fr_ptr->mount.offset = partition_lba; // Store partition_lba in offset
107 
108     ipc_set_msg_data(ipc_msg, (char *)fr_ptr, 0, sizeof(struct fs_request));
109     ret = ipc_call(ipc_struct, ipc_msg);
110     ipc_destroy_msg(ipc_msg);
111 
112     return ret;
113 }
114 
chcore_initial_littlefs_partition(int fs_cap,uint64_t partition_lba)115 int chcore_initial_littlefs_partition(int fs_cap, uint64_t partition_lba)
116 {
117     return chcore_initial_ext4_partition(fs_cap, partition_lba);
118 }
119 
120 /*
121  * @arg: 'device_name' is like 'sda1'.. etc
122  * @return: corresponding fs server cap
123  */
mount_storage_device(const char * device_name)124 int mount_storage_device(const char *device_name)
125 {
126     struct proc_request *proc_req;
127     cap_t fs_server_cap = 0;
128     device_partition_t *fs_server;
129     ipc_msg_t *proc_ipc_msg;
130 
131     /*
132      * Refill 'dparts' to refresh partition_information
133      * Write 'dparts' only first call 'chcore_parse_devices'
134      */
135     pthread_mutex_lock(&dparts_lock);
136     if (chcore_parse_devices() < 0) {
137         return -1;
138     }
139     print_devices();
140     pthread_mutex_unlock(&dparts_lock);
141 
142     /* get corresponding fs server id */
143     fs_server = chcore_get_server(device_name);
144     if (fs_server == NULL || !fs_server->valid) {
145         errno = EINVAL;
146         return -1;
147     }
148 
149     /* prepare structs to IPC call FSM */
150     proc_ipc_msg =
151         ipc_create_msg(procmgr_ipc_struct, sizeof(struct proc_request));
152     proc_req = (struct proc_request *)ipc_get_msg_data(proc_ipc_msg);
153     proc_req->req = PROC_REQ_GET_SERVER_CAP;
154     proc_req->get_server_cap.server_id = fs_server->server_id;
155 
156     ipc_call(procmgr_ipc_struct, proc_ipc_msg);
157     fs_server_cap = ipc_get_msg_cap(proc_ipc_msg, 0);
158     ipc_destroy_msg(proc_ipc_msg);
159 
160     /* deal with different fs type */
161     if (fs_server->server_id == SERVER_FAT32_FS) {
162         /* FAT type */
163         if (!fs_server->mounted) {
164             chcore_initial_fat_partition(fs_server_cap,
165                                          fs_server->partition_index);
166             fs_server->mounted = true;
167         }
168     } else if (fs_server->server_id == SERVER_EXT4_FS) {
169         /* EXT4 type */
170         if (!fs_server->mounted) {
171             chcore_initial_ext4_partition(fs_server_cap,
172                                           fs_server->partition_lba);
173         }
174     } else if (fs_server->server_id == SERVER_LITTLEFS) {
175         /* LITTLEFS type */
176         if (!fs_server->mounted) {
177             chcore_initial_littlefs_partition(fs_server_cap,
178                                               fs_server->partition_lba);
179         }
180     } else {
181         /* others */
182         printf("[WARNING] Not supported fs type \n");
183     }
184 
185     return fs_server_cap;
186 }
187 
print_partition(partition_struct_t * p)188 void print_partition(partition_struct_t *p)
189 {
190     printf("partition infomation:\n");
191 
192     /* parse boot */
193     if (p->boot == 0x0)
194         printf("  boot: no\n");
195     else if (p->boot == 0x80)
196         printf("  boot: yes\n");
197     else
198         printf("  boot: (unknown)\n");
199 
200     /* print fs id */
201     printf("  file system id: 0x%x\n", p->fs_id);
202 
203     /* parse fs type */
204     if (p->fs_id == EXT4_PARTITION)
205         printf("  file system: Linux File System\n");
206     else if (p->fs_id == FAT32_PARTITION)
207         printf("  file system: W95 FAT32 (LBA)\n");
208     else if (p->fs_id == 0)
209         printf("  file system: Unused\n");
210     else
211         printf("  file system: (unknown)\n");
212 
213     /* parse partition lba */
214     printf("  partition lba: 0x%x = %d\n", p->lba, p->lba);
215 
216     /* parse partition size */
217     printf("  partition size: 0x%x = %d\n", p->total_sector, p->total_sector);
218 }
219 
print_devices(void)220 void print_devices(void)
221 {
222     /* Now, only support sd device */
223     int i;
224     printf("[SDCARD]\n");
225     printf("Device\tServer\tPartition\tType\n");
226     for (i = 0; i < 5; i++)
227         if (dparts[i].valid)
228             printf("%s\t%d\t%d\t%x\n",
229                    dparts[i].device_name,
230                    dparts[i].server_id,
231                    dparts[i].partition_index,
232                    dparts[i].partition_type);
233 }
234