Changeset f2b3d3e in mainline for tools/mkfat.py
- Timestamp:
- 2012-05-04T10:57:48Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 35a35651
- Parents:
- 90924df (diff), d21e935c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
tools/mkfat.py
r90924df rf2b3d3e 168 168 """ 169 169 170 LFN_ENTRY = """little: 171 uint8_t pos 172 uint16_t name1[5] 173 uint8_t attr 174 uint8_t type 175 uint8_t csum 176 uint16_t name2[6] 177 uint16_t fc 178 uint16_t name3[2] 179 """ 180 181 # Global variable to hold the file names in 8.3 format. Needed to 182 # keep track of "number" when creating a short fname from a LFN. 183 name83_list = [] 184 185 def name83(fname): 186 "Create a 8.3 name for the given fname" 187 188 # FIXME: filter illegal characters 189 parts = fname.split('.') 190 191 name = '' 192 ext = '' 193 lfn = False 194 195 if len(fname) > 11 : 170 LFN_DIR_ENTRY = """little: 171 uint8_t seq /* sequence number */ 172 char name1[10] /* first part of the name */ 173 uint8_t attr /* attributes */ 174 uint8_t rec_type /* LFN record type */ 175 uint8_t checksum /* LFN checksum */ 176 char name2[12] /* second part of the name */ 177 uint16_t cluster /* cluster */ 178 char name3[4] /* third part of the name */ 179 """ 180 181 lchars = set(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 182 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 183 'U', 'V', 'W', 'X', 'Y', 'Z', 184 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 185 '!', '#', '$', '%', '&', '\'', '(', ')', '-', '@', 186 '^', '_', '`', '{', '}', '~', '.']) 187 188 def fat_lchars(name): 189 "Filter FAT legal characters" 190 191 filtered_name = '' 192 filtered = False 193 194 for char in name.encode('ascii', 'replace').upper(): 195 if char in lchars: 196 filtered_name += char 197 else: 198 filtered_name += b'_' 199 filtered = True 200 201 return (filtered_name, filtered) 202 203 def fat_name83(name, name83_list): 204 "Create a 8.3 name for the given name" 205 206 ascii_name, lfn = fat_lchars(name) 207 ascii_parts = ascii_name.split('.') 208 209 short_name = '' 210 short_ext = '' 211 212 if len(ascii_name) > 11: 196 213 lfn = True 197 198 if len( parts) > 0:199 name =parts[0]200 if len( name) > 8:214 215 if len(ascii_parts) > 0: 216 short_name = ascii_parts[0] 217 if len(short_name) > 8: 201 218 lfn = True 202 203 if len( parts) > 1:204 ext =parts[-1]205 if len( ext) > 3:219 220 if len(ascii_parts) > 1: 221 short_ext = ascii_parts[-1] 222 if len(short_ext) > 3: 206 223 lfn = True 207 208 if len( parts) > 2:224 225 if len(ascii_parts) > 2: 209 226 lfn = True 210 211 if (lfn == False) : 212 return (name.ljust(8)[0:8], ext.ljust(3)[0:3], False) 213 227 228 if lfn == False: 229 name83_list.append(short_name + '.' + short_ext) 230 return (short_name.ljust(8)[0:8], short_ext.ljust(3)[0:3], False) 231 214 232 # For filenames with multiple extensions, we treat the last one 215 233 # as the actual extension. The rest of the filename is stripped 216 234 # of dots and concatenated to form the short name 217 for _name in parts[1:-1]: 218 name = name + _name 219 220 global name83_list 221 for number in range(1, 10000) : 222 number_str = '~' + str(number) 223 224 if len(name) + len(number_str) > 8 : 225 name = name[0:8 - len(number_str)] 226 227 name = name + number_str; 228 229 if (name + ext) not in name83_list : 235 for part in ascii_parts[1:-1]: 236 short_name += part 237 238 for number in range(1, 999999): 239 number_str = ('~' + str(number)).upper() 240 241 if len(short_name) + len(number_str) > 8: 242 short_name = short_name[0:8 - len(number_str)] 243 244 short_name += number_str; 245 246 if not (short_name + '.' + short_ext) in name83_list: 230 247 break 231 232 name83_list.append(name + ext) 233 234 return (name.ljust(8)[0:8], ext.ljust(3)[0:3], True) 235 236 def get_utf16(name, l) : 237 "Create a int array out of a string which we can store in uint16_t arrays" 238 239 bs = [0xFFFF for i in range(l)] 240 241 for i in range(len(name)) : 242 bs[i] = ord(name[i]) 243 244 if (len(name) < l) : 245 bs[len(name)] = 0; 246 247 return bs 248 249 def create_lfn_entry(name_index) : 250 (name, index) = name_index 251 entry = xstruct.create(LFN_ENTRY) 252 253 entry.name1 = get_utf16(name[0:5], 5) 254 entry.name2 = get_utf16(name[5:11], 6) 255 entry.name3 = get_utf16(name[11:13], 2) 256 entry.pos = index 257 258 entry.attr = 0xF 259 entry.fc = 0 260 entry.type = 0 261 262 return entry 263 264 def create_dirent(name, directory, cluster, size): 248 249 name83_list.append(short_name + '.' + short_ext) 250 return (short_name.ljust(8)[0:8], short_ext.ljust(3)[0:3], True) 251 252 def create_lfn_dirent(name, seq, checksum): 253 "Create LFN directory entry" 254 255 entry = xstruct.create(LFN_DIR_ENTRY) 256 name_rest = name[26:] 257 258 if len(name_rest) > 0: 259 entry.seq = seq 260 else: 261 entry.seq = seq | 0x40 262 263 entry.name1 = name[0:10] 264 entry.name2 = name[10:22] 265 entry.name3 = name[22:26] 266 267 entry.attr = 0x0F 268 entry.rec_type = 0 269 entry.checksum = checksum 270 entry.cluster = 0 271 272 return (entry, name_rest) 273 274 def lfn_checksum(name): 275 "Calculate LFN checksum" 276 277 checksum = 0 278 for i in range(0, 11): 279 checksum = (((checksum & 1) << 7) + (checksum >> 1) + ord(name[i])) & 0xFF 280 281 return checksum 282 283 def create_dirent(name, name83_list, directory, cluster, size): 284 short_name, short_ext, lfn = fat_name83(name, name83_list) 265 285 266 286 dir_entry = xstruct.create(DIR_ENTRY) 267 287 268 dir_entry.name, dir_entry.ext, lfn = name83(name) 269 270 dir_entry.name = dir_entry.name.upper().encode('ascii') 271 dir_entry.ext = dir_entry.ext.upper().encode('ascii') 272 288 dir_entry.name = short_name 289 dir_entry.ext = short_ext 290 273 291 if (directory): 274 292 dir_entry.attr = 0x30 … … 290 308 dir_entry.size = size 291 309 292 293 310 if not lfn: 294 311 return [dir_entry] 295 296 n = (int) (len(name) / 13 + 1) 297 names = [(name[i * 13: (i + 1) * 13 + 1], i + 1) for i in range(n)] 298 299 entries = sorted(map (create_lfn_entry, names), reverse = True, key = lambda e : e.pos) 300 entries[0].pos |= 0x40 301 302 fname11 = str(dir_entry.name + dir_entry.ext) 303 304 csum = 0 305 for i in range(0, 11) : 306 csum = ((csum & 1) << 7) + (csum >> 1) + ord(fname11[i]) 307 csum = csum & 0xFF 308 309 for e in entries : 310 e.csum = csum; 311 312 entries.append(dir_entry) 313 312 313 long_name = name.encode('utf_16_le') 314 entries = [dir_entry] 315 316 seq = 1 317 checksum = lfn_checksum(dir_entry.name + dir_entry.ext) 318 319 while len(long_name) > 0: 320 long_entry, long_name = create_lfn_dirent(long_name, seq, checksum) 321 entries.append(long_entry) 322 seq += 1 323 324 entries.reverse() 314 325 return entries 315 326 … … 356 367 357 368 directory = [] 358 359 if (not head): 369 name83_list = [] 370 371 if not head: 360 372 # Directory cluster preallocation 361 373 empty_cluster = fat.index(0) 362 fat[empty_cluster] = 0x ffff374 fat[empty_cluster] = 0xFFFF 363 375 364 376 directory.append(create_dot_dirent(empty_cluster)) … … 367 379 empty_cluster = 0 368 380 369 for item in listdir_items(root): 381 for item in listdir_items(root): 370 382 if item.is_file: 371 383 rv = write_file(item, outf, cluster_size, data_start, fat, reserved_clusters) 372 directory.extend(create_dirent(item.name, False, rv[0], rv[1]))384 directory.extend(create_dirent(item.name, name83_list, False, rv[0], rv[1])) 373 385 elif item.is_dir: 374 386 rv = recursion(False, item.path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster) 375 directory.extend(create_dirent(item.name, True, rv[0], rv[1]))376 377 if (head):387 directory.extend(create_dirent(item.name, name83_list, True, rv[0], rv[1])) 388 389 if head: 378 390 outf.seek(root_start) 379 391 for dir_entry in directory: … … 432 444 extra_bytes = int(sys.argv[1]) 433 445 434 path = os.path.abspath(sys.argv[2] )446 path = os.path.abspath(sys.argv[2].decode()) 435 447 if (not os.path.isdir(path)): 436 448 print("<PATH> must be a directory") … … 530 542 531 543 outf.close() 532 544 533 545 if __name__ == '__main__': 534 546 main()
Note:
See TracChangeset
for help on using the changeset viewer.