3131
3232#define VFS_INDEX 0
3333
34+ #define PART1_START_BLOCK (0x1)
35+
3436void supervisor_flash_set_usb_writable (bool usb_writable ) {
3537 mp_vfs_mount_t * current_mount = MP_STATE_VM (vfs_mount_table );
3638 for (uint8_t i = 0 ; current_mount != NULL ; i ++ ) {
@@ -63,18 +65,95 @@ STATIC mp_obj_t supervisor_flash_obj_make_new(const mp_obj_type_t *type, size_t
6365 return (mp_obj_t )& supervisor_flash_obj ;
6466}
6567
68+ uint32_t flash_get_block_count (void ) {
69+ return PART1_START_BLOCK + supervisor_flash_get_block_count ();
70+ }
71+
72+ static void build_partition (uint8_t * buf , int boot , int type , uint32_t start_block , uint32_t num_blocks ) {
73+ buf [0 ] = boot ;
74+
75+ if (num_blocks == 0 ) {
76+ buf [1 ] = 0 ;
77+ buf [2 ] = 0 ;
78+ buf [3 ] = 0 ;
79+ } else {
80+ buf [1 ] = 0xff ;
81+ buf [2 ] = 0xff ;
82+ buf [3 ] = 0xff ;
83+ }
84+
85+ buf [4 ] = type ;
86+
87+ if (num_blocks == 0 ) {
88+ buf [5 ] = 0 ;
89+ buf [6 ] = 0 ;
90+ buf [7 ] = 0 ;
91+ } else {
92+ buf [5 ] = 0xff ;
93+ buf [6 ] = 0xff ;
94+ buf [7 ] = 0xff ;
95+ }
96+
97+ buf [8 ] = start_block ;
98+ buf [9 ] = start_block >> 8 ;
99+ buf [10 ] = start_block >> 16 ;
100+ buf [11 ] = start_block >> 24 ;
101+
102+ buf [12 ] = num_blocks ;
103+ buf [13 ] = num_blocks >> 8 ;
104+ buf [14 ] = num_blocks >> 16 ;
105+ buf [15 ] = num_blocks >> 24 ;
106+ }
107+
108+ mp_uint_t flash_read_blocks (uint8_t * dest , uint32_t block_num , uint32_t num_blocks ) {
109+ if (block_num == 0 ) {
110+ if (block_num > 1 ) {
111+ return 1 ; // error
112+ }
113+ // fake the MBR so we can decide on our own partition table
114+
115+ for (int i = 0 ; i < 446 ; i ++ ) {
116+ dest [i ] = 0 ;
117+ }
118+
119+ build_partition (dest + 446 , 0 , 0x01 /* FAT12 */ , PART1_START_BLOCK , supervisor_flash_get_block_count ());
120+ build_partition (dest + 462 , 0 , 0 , 0 , 0 );
121+ build_partition (dest + 478 , 0 , 0 , 0 , 0 );
122+ build_partition (dest + 494 , 0 , 0 , 0 , 0 );
123+
124+ dest [510 ] = 0x55 ;
125+ dest [511 ] = 0xaa ;
126+
127+ return 0 ; // ok
128+
129+ }
130+ return supervisor_flash_read_blocks (dest , block_num - PART1_START_BLOCK , num_blocks );
131+ }
132+
133+ mp_uint_t flash_write_blocks (const uint8_t * src , uint32_t block_num , uint32_t num_blocks ) {
134+ if (block_num == 0 ) {
135+ if (num_blocks > 1 ) {
136+ return 1 ; // error
137+ }
138+ // can't write MBR, but pretend we did
139+ return 0 ;
140+ } else {
141+ return supervisor_flash_write_blocks (src , block_num - PART1_START_BLOCK , num_blocks );
142+ }
143+ }
144+
66145STATIC mp_obj_t supervisor_flash_obj_readblocks (mp_obj_t self , mp_obj_t block_num , mp_obj_t buf ) {
67146 mp_buffer_info_t bufinfo ;
68147 mp_get_buffer_raise (buf , & bufinfo , MP_BUFFER_WRITE );
69- mp_uint_t ret = supervisor_flash_read_blocks (bufinfo .buf , mp_obj_get_int (block_num ), bufinfo .len / FILESYSTEM_BLOCK_SIZE );
148+ mp_uint_t ret = flash_read_blocks (bufinfo .buf , mp_obj_get_int (block_num ), bufinfo .len / FILESYSTEM_BLOCK_SIZE );
70149 return MP_OBJ_NEW_SMALL_INT (ret );
71150}
72151STATIC MP_DEFINE_CONST_FUN_OBJ_3 (supervisor_flash_obj_readblocks_obj , supervisor_flash_obj_readblocks );
73152
74153STATIC mp_obj_t supervisor_flash_obj_writeblocks (mp_obj_t self , mp_obj_t block_num , mp_obj_t buf ) {
75154 mp_buffer_info_t bufinfo ;
76155 mp_get_buffer_raise (buf , & bufinfo , MP_BUFFER_READ );
77- mp_uint_t ret = supervisor_flash_write_blocks (bufinfo .buf , mp_obj_get_int (block_num ), bufinfo .len / FILESYSTEM_BLOCK_SIZE );
156+ mp_uint_t ret = flash_write_blocks (bufinfo .buf , mp_obj_get_int (block_num ), bufinfo .len / FILESYSTEM_BLOCK_SIZE );
78157 return MP_OBJ_NEW_SMALL_INT (ret );
79158}
80159STATIC MP_DEFINE_CONST_FUN_OBJ_3 (supervisor_flash_obj_writeblocks_obj , supervisor_flash_obj_writeblocks );
@@ -85,7 +164,7 @@ STATIC mp_obj_t supervisor_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_ob
85164 case BP_IOCTL_INIT : supervisor_flash_init (); return MP_OBJ_NEW_SMALL_INT (0 );
86165 case BP_IOCTL_DEINIT : supervisor_flash_flush (); return MP_OBJ_NEW_SMALL_INT (0 ); // TODO properly
87166 case BP_IOCTL_SYNC : supervisor_flash_flush (); return MP_OBJ_NEW_SMALL_INT (0 );
88- case BP_IOCTL_SEC_COUNT : return MP_OBJ_NEW_SMALL_INT (supervisor_flash_get_block_count ());
167+ case BP_IOCTL_SEC_COUNT : return MP_OBJ_NEW_SMALL_INT (flash_get_block_count ());
89168 case BP_IOCTL_SEC_SIZE : return MP_OBJ_NEW_SMALL_INT (supervisor_flash_get_block_size ());
90169 default : return mp_const_none ;
91170 }
@@ -114,10 +193,10 @@ void supervisor_flash_init_vfs(fs_user_mount_t *vfs) {
114193 vfs -> fatfs .part = 1 ; // flash filesystem lives on first partition
115194 vfs -> readblocks [0 ] = (mp_obj_t )& supervisor_flash_obj_readblocks_obj ;
116195 vfs -> readblocks [1 ] = (mp_obj_t )& supervisor_flash_obj ;
117- vfs -> readblocks [2 ] = (mp_obj_t )supervisor_flash_read_blocks ; // native version
196+ vfs -> readblocks [2 ] = (mp_obj_t )flash_read_blocks ; // native version
118197 vfs -> writeblocks [0 ] = (mp_obj_t )& supervisor_flash_obj_writeblocks_obj ;
119198 vfs -> writeblocks [1 ] = (mp_obj_t )& supervisor_flash_obj ;
120- vfs -> writeblocks [2 ] = (mp_obj_t )supervisor_flash_write_blocks ; // native version
199+ vfs -> writeblocks [2 ] = (mp_obj_t )flash_write_blocks ; // native version
121200 vfs -> u .ioctl [0 ] = (mp_obj_t )& supervisor_flash_obj_ioctl_obj ;
122201 vfs -> u .ioctl [1 ] = (mp_obj_t )& supervisor_flash_obj ;
123202}
0 commit comments