[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: mkfs.jffs big/little endian bug fix



So far, I have only started with a blank flash.  I have not used
mkfs.jffs at all.

Yet, my usual development platform is an x86 based linux system, while
my target system is a big-endian MIPs based system.  (I know some MIPs
systems are either-endian, but ours is hardwired big endian).

Could you (or someone else with the knowledge) go into detail a bit
about what the endianness issues are?

Does JFFS (apart from mkfs.jffs) use native byte ordering in it's
filesystem structures, or is it portable between systems of differing
endianness?  Is there any change in this matter in JFFS2 vs. JFFS? 

Your patch below seems to always write little endian regardless of the
processor involved.  So, I'm inclined to believe that either (A) you
didn't cover the other case (developing on a little endian system for
a big endian target) or (B) the filesystem is always run little
endian.

I would be quite willing to work with you, or anyone, on changing
these patches to handle endiannes conversion in any direction.  But I
need to do a little preliminary footwork first.

--> Steve Wahl

On Mon, Apr 22, 2002 at 12:47:35PM +0200, Martin Herren wrote:
> Hej,
> 
> here is a patch to run mkfs.jffs on big endian CPUs, like
> Sparc/UltraSparc.
> 
> This patch doesn't include my previous patch for Sparc/UltraSparc, so
> you'll have to apply it too.
> 
> hth
> 
> /Martin
> --- mkfs.jffs_patch-1.c	Mon Apr 22 03:06:28 2002
> +++ mkfs.jffs.c	Mon Apr 22 12:38:20 2002
> @@ -71,6 +71,8 @@ static u_int32_t jffs_checksum(void *dat
>  void jffs_print_trace(const char *path, int depth);
>  int make_root_dir(FILE *fs, int first_ino, const char *root_dir_path,
>  		  int depth);
> +void write_u_int16_t(FILE *fs, u_int16_t data);
> +void write_u_int32_t(FILE *fs, u_int32_t data);
>  void write_file(struct jffs_file *f, FILE *fs, struct stat st);
>  void read_data(struct jffs_file *f, const char *path, int offset);
>  int mkfs(FILE *fs, const char *path, int ino, int parent, int depth);
> @@ -223,6 +225,29 @@ make_root_dir(FILE *fs, int first_ino, c
>  }
>  
>  
> +void write_u_int16_t(FILE *fs, u_int16_t data)
> +{
> +  int i = 0;
> +  for(i = 0; i < 2; i++)
> +    {
> +      u_int8_t byte = (u_int8_t)data % 0xff;
> +      fwrite(&byte, 1, 1, fs);
> +      data = data >> 8;
> +    }
> +}
> +
> +
> +void write_u_int32_t(FILE *fs, u_int32_t data)
> +{
> +  int i = 0;
> +  for(i = 0; i < 4; i++)
> +    {
> +      u_int8_t byte = (u_int8_t)data % 0xff;
> +      fwrite(&byte, 1, 1, fs);
> +      data = data >> 8;
> +    }
> +}
> +
>  /* This function writes at least one inode.  */
>  void
>  write_file(struct jffs_file *f, FILE *fs, struct stat st)
> @@ -237,7 +262,27 @@ write_file(struct jffs_file *f, FILE *fs
>    {
>      fprintf(stderr, "***write_file()\n");
>    }
> -  fwrite((void *)&f->inode, sizeof(struct jffs_raw_inode), 1, fs);
> +  write_u_int32_t(fs, f->inode.magic);
> +  write_u_int32_t(fs, f->inode.ino);
> +  write_u_int32_t(fs, f->inode.pino);
> +  write_u_int32_t(fs, f->inode.version);
> +  write_u_int32_t(fs, f->inode.mode);
> +  write_u_int16_t(fs, f->inode.uid);
> +  write_u_int16_t(fs, f->inode.gid);
> +  write_u_int32_t(fs, f->inode.atime);
> +  write_u_int32_t(fs, f->inode.mtime);
> +  write_u_int32_t(fs, f->inode.ctime);
> +  write_u_int32_t(fs, f->inode.offset);
> +  write_u_int32_t(fs, f->inode.dsize);
> +  write_u_int32_t(fs, f->inode.rsize);
> +  fwrite((void *)&f->inode.nsize, 1, 1, fs);
> +  fwrite((void *)&f->inode.nlink, 1, 1, fs);
> +  fwrite((void *)&f->inode.nlink + 1, 1, 1, fs);
> +  fwrite((void *)&f->inode.accurate, 1, 1, fs);
> +  write_u_int32_t(fs, f->inode.dchksum);
> +  write_u_int16_t(fs, f->inode.nchksum);
> +  write_u_int16_t(fs, f->inode.chksum);
> +
>    if (f->inode.nsize)
>    {
>      fwrite(f->name, 1, f->inode.nsize, fs);
> @@ -251,7 +296,15 @@ write_file(struct jffs_file *f, FILE *fs
>    {
>      if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
>      {
> -      fwrite((char *)&st.st_rdev, sizeof(st.st_rdev)/4, 1, fs);
> +      int i = 0;
> +      dev_t data = st.st_rdev;
> +
> +      for(i = 0; i < sizeof(st.st_rdev)/4; i++)
> +	{
> +	  u_int8_t byte = (u_int8_t)data % 0xff;
> +	  fwrite(&byte, 1, 1, fs);
> +	  data = data >> 8;
> +	}
>      }
>      else
>      {
> @@ -485,8 +538,25 @@ mkfs(FILE *fs, const char *path, int ino
>      }
>      else
>      {
> +      int i;
> +      dev_t rdev = st.st_rdev;
> +      char *data = (char *)alloca(sizeof(st.st_rdev) / 4);
> +
> +      if (!data)
> +	{
> +	  fprintf(stderr, "mkfs(): Allocation failed.\n");
> +	  exit(1);
> +	}
> +
> +      for(i = 0; i < sizeof(st.st_rdev)/4; i++)
> +	{
> +	  u_int8_t byte = (u_int8_t)rdev % 0xff;
> +	  data[i] = byte;
> +	  rdev = rdev >> 8;
> +	}
> +      
>        f.inode.dchksum
> -	= jffs_checksum((void *)&st.st_rdev, sizeof(st.st_rdev) / 4);
> +	= jffs_checksum((void *)data, sizeof(st.st_rdev) / 4);
>      }
>  
>      f.inode.nchksum = jffs_checksum((void *)f.name, f.inode.nsize);


To unsubscribe from this list: send the line "unsubscribe jffs-dev" in
the body of a message to majordomo@xxxxxxx.com