Ext2: reading directory entries reads zeros.
Re: Ext2: reading directory entries reads zeros.
Wait, I'm gonna run Linux. 5 secs
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Ext2: reading directory entries reads zeros.
This is my structures. I don't see any mistakes.
Code: Select all
struct ext2_superblock
{
uint32_t inodes_count;
uint32_t blocks_count;
uint32_t reserved_blocks_count;
uint32_t unallocated_blocks_count;
uint32_t unallocated_inodes_count;
uint32_t superblock_block_number;
uint32_t block_size;
uint32_t fragment_size;
uint32_t blocks_count_in_blk_group;
uint32_t fragments_count_in_blk_group;
uint32_t inodes_count_in_blk_group;
uint32_t last_mount_time;
uint32_t last_written_time;
uint16_t times_mounted_after_check;
uint16_t mounts_before_check;
uint16_t signature;
uint16_t fs_state;
uint16_t action_on_error;
uint16_t ver_minor;
uint32_t last_check_time;
uint32_t check_interval;
uint32_t creator_id;
uint32_t ver_major;
uint16_t reserved_blocks_uid;
uint16_t reserved_blocks_gid;
uint32_t first_nonreserved_inode;
uint16_t inode_size;
uint16_t superblock_block_group;
uint32_t optional_features;
uint32_t required_features;
uint32_t features_to_read_write;
uint8_t fs_id[16];
char volume_label[16];
char last_mount_path[64];
uint32_t compression_algorithms_used;
uint8_t blocks_to_preallocate_for_files;
uint8_t blocks_to_preallocate_for_dirs;
uint16_t unused;
uint8_t journal_id[16];
uint32_t journal_inode;
uint32_t journal_device;
uint32_t orphan_inode_list_head;
} __attribute__((packed));
struct ext2_inode
{
uint16_t type_and_perms;
uint16_t owner_uid;
uint32_t size_low;
uint32_t access_time;
uint32_t creation_time;
uint32_t modified_time;
uint32_t deletion_time;
uint16_t owner_gid;
uint16_t link_count; //These links are "pointers" to this inode.
uint32_t sector_count;
uint32_t flags;
uint32_t os_specific;
uint32_t direct_block_pointers[12]; //For medium-size files this is enough.
uint32_t singly_indir_block_pointer;
uint32_t double_indir_block_pointer;
uint32_t triple_indir_block_pointer;
uint32_t generation_number;
uint32_t file_acl;
uint32_t dir_acl_or_file_size_high;
uint32_t fragment_address;
uint8_t os_specific_2[12];
} __attribute__((packed));
struct ext2_block_group_descriptor
{
uint32_t block_usage_address;
uint32_t inode_usage_address;
uint32_t inode_table_address;
uint16_t unallocated_blocks_count;
uint16_t unallocated_inodes_count;
uint16_t directories_in_group;
uint16_t unused[7];
} __attribute__((packed));
struct ext2_directory_entry
{
uint32_t inode;
uint16_t size;
uint8_t name_length_low;
uint8_t type_or_name_length_high;
//As you can see, structure misses name field. It's because C doesn't allow variable-length arrays in structures, because it will prevent compile-time structure size computing.
} __attribute__((packed));
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Ext2: reading directory entries reads zeros.
Anybody?
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
- crunch
- Member
- Posts: 81
- Joined: Wed Aug 31, 2016 9:53 pm
- Libera.chat IRC: crunch
- Location: San Diego, CA
Re: Ext2: reading directory entries reads zeros.
I'd suggest you try and test your code on a host machine, with disk images. That's how I got my ext2 code sorted out.
Some of my open-source projects:
Ext2/ELF32 bootloader
Lightweight x86 assembler, designed to be portable for osdev
Scheme in under 1000 lines of C
Ext2/ELF32 bootloader
Lightweight x86 assembler, designed to be portable for osdev
Scheme in under 1000 lines of C
Re: Ext2: reading directory entries reads zeros.
My driver fails to find drives, IDK why. But disk reads finely when it exists, as I previosly said many times.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Ext2: reading directory entries reads zeros.
catnikita255 wrote:Anybody?
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Ext2: reading directory entries reads zeros.
Also you may need ATA driver, this is ata.c file:
Code: Select all
#include <string.h>
#include <stdint.h>
#include <arch/i686/ata.h>
#include <stdio.h>
#include <io.h>
#include <debug.h>
#include <time.h>
#define ATA_BLOCKSIZE 512
#define ATA_IRQ0 32+14
#define ATA_IRQ1 32+15
#define ATA_IRQ2 32+11
#define ATA_IRQ3 32+9
#define ATA_BASE0 0x1F0
#define ATA_BASE1 0x170
#define ATA_BASE2 0x1E8
#define ATA_BASE3 0x168
#define ATA_TIMEOUT 3
#define ATA_DATA 0 /* data register */
#define ATA_ERROR 1 /* error register */
#define ATA_COUNT 2 /* sectors to transfer */
#define ATA_SECTOR 3 /* sector number */
#define ATA_CYL_LO 4 /* low byte of cylinder number */
#define ATA_CYL_HI 5 /* high byte of cylinder number */
#define ATA_FDH 6 /* flags, drive and head */
#define ATA_STATUS 7
#define ATA_COMMAND 7
#define ATA_CONTROL 0x206
#define ATA_FLAGS_ECC 0x80 /* enable error correction */
#define ATA_FLAGS_LBA 0x40 /* enable linear addressing */
#define ATA_FLAGS_SEC 0x20 /* enable 512-byte sectors */
#define ATA_FLAGS_SLV 0x10 /* address the slave drive */
#define ATA_STATUS_BSY 0x80 /* controller busy */
#define ATA_STATUS_RDY 0x40 /* drive ready */
#define ATA_STATUS_WF 0x20 /* write fault */
#define ATA_STATUS_SC 0x10 /* seek complete (obsolete) */
#define ATA_STATUS_DRQ 0x08 /* data transfer request */
#define ATA_STATUS_CRD 0x04 /* corrected data */
#define ATA_STATUS_IDX 0x02 /* index pulse */
#define ATA_STATUS_ERR 0x01 /* error */
#define ATA_COMMAND_IDLE 0x00
#define ATA_COMMAND_READ 0x20 /* read data */
#define ATA_COMMAND_WRITE 0x30 /* write data */
#define ATA_COMMAND_IDENTIFY 0xec
#define ATAPI_COMMAND_IDENTIFY 0xa1
#define ATAPI_COMMAND_PACKET 0xa0
#define ATAPI_FEATURE 1
#define ATAPI_IRR 2
#define ATAPI_SAMTAG 3
#define ATAPI_COUNT_LO 4
#define ATAPI_COUNT_HI 5
#define ATAPI_DRIVE 6
#define ATAPI_BLOCKSIZE 2048
#define SCSI_READ10 0x28
#define SCSI_SENSE 0x03
#define ATA_CONTROL_RESET 0x04
#define ATA_CONTROL_DISABLEINT 0x02
static const int ata_base[4] = {
ATA_BASE0,
ATA_BASE0,
ATA_BASE1,
ATA_BASE1
};
struct ata_drive_info
{
uint8_t attached;
const char *name;
int block_size;
uint64_t size;
};
static struct ata_drive_info drives[4];
void ata_reset(int id) {
outb(ata_base[id] + ATA_CONTROL, ATA_CONTROL_RESET);
sleep(10);
outb(ata_base[id] + ATA_CONTROL, 0);
sleep(10);
}
static int ata_wait(int id, int mask, int state) {
int t;
int time=0;
while(1) {
t = inb(ata_base[id] + ATA_STATUS);
if((t&mask) == state) {
return 1;
}
if(t&ATA_STATUS_ERR) {
debug_print(ERROR, "ATA error.");
ata_reset(id);
return 0;
}
if(time>=ATA_TIMEOUT*100)
{
debug_print(NOTICE, "ata_wait: timed out!");
ata_reset(id);
return 0;
}
sleep(1);
time++;
}
}
static void ata_pio_read(int id, void *buffer, int size) {
uint16_t *wbuffer = (uint16_t*)buffer;
while(size > 0) {
*wbuffer = inw(ata_base[id] + ATA_DATA);
wbuffer++;
size -= 2;
}
}
static void ata_pio_write(int id, const void *buffer, int size) {
uint16_t *wbuffer = (uint16_t*)buffer;
while(size > 0) {
outw(ata_base[id] + ATA_DATA, *wbuffer);
wbuffer++;
size-=2;
}
}
static int ata_begin(int id, int command, int nblocks, int offset) {
int base = ata_base[id];
int sector, clow, chigh, flags;
flags = ATA_FLAGS_ECC | ATA_FLAGS_LBA | ATA_FLAGS_SEC;
if(id % 2) flags |= ATA_FLAGS_SLV;
sector = (offset >> 0) & 0xff;
clow = (offset >> 8) & 0xff;
chigh = (offset >> 16) & 0xff;
flags |= (offset >> 24) & 0x0f;
if(!ata_wait(id, ATA_STATUS_BSY, 0)) return 0;
outb(base + ATA_FDH, flags);
int ready;
if(command == ATAPI_COMMAND_IDENTIFY) ready = ata_wait(id, ATA_STATUS_BSY,0);
else ready = ata_wait(id, ATA_STATUS_BSY | ATA_STATUS_RDY, ATA_STATUS_RDY);
if(!ready) return 0;
outb(base + ATA_CONTROL, 0);
outb(base + ATA_COUNT, nblocks);
outb(base + ATA_SECTOR, sector);
outb(base + ATA_CYL_LO, clow);
outb(base + ATA_CYL_HI, chigh);
outb(base + ATA_FDH, flags);
outb(base + ATA_COMMAND, command);
return 1;
}
static int ata_read_unlocked(int id, void *buffer, int nblocks, int offset) {
int i;
if(!ata_begin(id,ATA_COMMAND_READ,nblocks,offset)) return 0;
for(i = 0;i < nblocks; i++) {
if(!ata_wait(id, ATA_STATUS_DRQ, ATA_STATUS_DRQ)) return 0;
ata_pio_read(id,buffer, ATA_BLOCKSIZE);
buffer = ((char*)buffer) + ATA_BLOCKSIZE;
offset++;
}
if(!ata_wait(id, ATA_STATUS_BSY, 0)) return 0;
return nblocks;
}
int ata_read(int id, void *buffer, int nblocks, int offset) {
int result;
result = ata_read_unlocked(id, buffer, nblocks, offset);
return result;
}
int ata_read_bytes(int id, void *buffer, int nbytes, int offset)
{
int nblocks=nbytes/drives[id].block_size;
if(nbytes % drives[id].block_size)
nblocks++;
return ata_read(id, buffer, nblocks, offset/drives[id].block_size);
}
static int atapi_begin(int id, void *data, int length) {
int base = ata_base[id];
int flags;
flags = ATA_FLAGS_ECC | ATA_FLAGS_LBA | ATA_FLAGS_SEC;
if(id%2) flags |= ATA_FLAGS_SLV;
if(!ata_wait(id, ATA_STATUS_BSY,0)) return 0;
outb(base+ATA_FDH, flags);
if(!ata_wait(id, ATA_STATUS_BSY,0)) return 0;
outb(base+ ATAPI_FEATURE, 0);
outb(base+ ATAPI_IRR, 0);
outb(base+ ATAPI_SAMTAG, 0);
outb(base + ATAPI_COUNT_LO, length & 0xff);
outb(base + ATAPI_COUNT_HI, length >> 8);
outb(base + ATA_COMMAND, ATAPI_COMMAND_PACKET);
if(!ata_wait(id, ATA_STATUS_BSY | ATA_STATUS_DRQ, ATA_STATUS_DRQ)) {}
ata_pio_write(id, data, length);
return 1;
}
static int atapi_read_unlocked(int id, void *buffer, int nblocks, int offset) {
uint8_t packet[12];
int length = sizeof(packet);
int i;
packet[0] = SCSI_READ10;
packet[1] = 0;
packet[2] = offset >>24;
packet[3] = offset >>16;
packet[4] = offset >>8;
packet[5] = offset >>0;
packet[6] = 0;
packet[7] = nblocks >>8;
packet[8] = nblocks >>0;
packet[9] = 0;
packet[10] = 0;
packet[11] = 0;
if(!atapi_begin(id,packet,length)) return 0;
for(i = 0;i < nblocks; i++) {
if(!ata_wait(id, ATA_STATUS_DRQ, ATA_STATUS_DRQ)) return 0;
ata_pio_read(id, buffer, ATAPI_BLOCKSIZE);
buffer = ((char*)buffer) + ATAPI_BLOCKSIZE;
offset++;
}
return nblocks;
}
int atapi_read(int id, void *buffer, int nblocks, int offset) {
int result;
result = atapi_read_unlocked(id, buffer, nblocks, offset);
return result;
}
static int ata_write_unlocked(int id, const void *buffer, int nblocks, int offset) {
int i;
if(!ata_begin(id, ATA_COMMAND_WRITE, nblocks, offset)) return 0;
for(i = 0; i < nblocks; i++) {
if(!ata_wait(id, ATA_STATUS_DRQ, ATA_STATUS_DRQ)) return 0;
ata_pio_write(id, buffer, ATA_BLOCKSIZE);
buffer = ((char*)buffer) + ATA_BLOCKSIZE;
offset++;
}
if(!ata_wait(id, ATA_STATUS_BSY, 0)) return 0;
return nblocks;
}
int ata_write(int id, void *buffer, int nblocks, int offset) {
int result;
result = ata_write_unlocked(id, buffer, nblocks, offset);
return result;
}
int ata_write_bytes(int id, void *buffer, int nbytes, int offset)
{
return ata_write(id, buffer, nbytes*drives[id].block_size, offset);
}
static int ata_identify(int id, int command, void *buffer) {
if(!ata_begin(id, command, 0, 0)) return 0;
if(!ata_wait(id, ATA_STATUS_DRQ, ATA_STATUS_DRQ)) return 0;
ata_pio_read(id, buffer, 512);
return 1;
}
int ata_probe( int id, int *nblocks, int *blocksize, char *name ) {
uint16_t buffer[256];
char *cbuffer = (char*)buffer;
uint8_t t = inb(ata_base[id] + ATA_STATUS);
if(t == 0xff) {
debug_print(NOTICE, "ATA: Nothing attached.");
drives[id].name="Not attached!";
drives[id].block_size=0;
drives[id].size=0;
drives[id].attached=0;
return 0;
}
ata_reset(id);
memset(cbuffer,0,512);
if(ata_identify(id, ATA_COMMAND_IDENTIFY, cbuffer)) {
*nblocks = buffer[1] * buffer[3] * buffer[6];
*blocksize = 512;
} else if(ata_identify(id, ATAPI_COMMAND_IDENTIFY, cbuffer)) {
*nblocks = 337920;
*blocksize = 2048;
} else {
debug_print(NOTICE, "ATA: Identity command failed!");
drives[id].name="Identify command failed! (Maybe nothing attached?)";
drives[id].block_size=0;
drives[id].size=0;
drives[id].attached=0;
return 0;
}
uint32_t i;
for(i = 0; i < 512; i += 2) {
t = cbuffer[i];
cbuffer[i] = cbuffer[i + 1];
cbuffer[i + 1] = t;
}
cbuffer[256]=0;
strcpy(name, &cbuffer[54]);
name[40] = 0;
debug_print(SUCCESS, "ATA: Found connected disk. Printing info to the screen.");
printf("ATA device #%d: type: %s, size: %f MB, name: %s\n", id, (*blocksize)==512 ? "ATA disk" : "ATAPI CDROM", (float)(*nblocks)*(*blocksize)/1024/1024, name);
debug_print(NOTICE, "ATA: Writing info to drive list...");
drives[id].name=name;
drives[id].block_size=*blocksize;
drives[id].size=*nblocks * *blocksize;
return 1;
}
void ata_init() {
debug_print(INIT, "ATA: Starting ATA initialization. Thanks to GUGDUN!");
int i;
int nblocks;
int blocksizes[4];
char disk_names[40][4];
debug_print(INIT, "ATA: Probing devices");
/*interrupt_register(ATA_IRQ0, ata_interrupt);
interrupt_enable(ATA_IRQ0);
interrupt_register(ATA_IRQ1, ata_interrupt);
interrupt_enable(ATA_IRQ1);*/
for(i = 0; i < 4; i++) ata_probe(i, &nblocks, &blocksizes[i], disk_names[i]);
printf("ATA device block sizes:\n\t%u, %u, %u, %u.\n", drives[0].block_size, blocksizes[1], blocksizes[2], blocksizes[3]);
}
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Ext2: reading directory entries reads zeros.
catnikita255 wrote:catnikita255 wrote:Anybody?
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
-
- Member
- Posts: 45
- Joined: Wed Dec 25, 2013 11:51 am
Re: Ext2: reading directory entries reads zeros.
crunch wrote:I'd suggest you try and test your code on a host machine, with disk images. That's how I got my ext2 code sorted out.
Did you followed crunch's suggestion? This way you could isolate the ext2 code and check if it's working (and if not, find out what's wrong). Use an image created with dd + mke2fs. A hexadecimal file viewer (hexdump, bless, etc.) could be used to look the image.catnikita255 wrote:Anybody?
And if you have any questions, tell people how you created the image (block size, disk size, etc.) and the values your code read.
Machina - https://github.com/brunexgeek/machina
Re: Ext2: reading directory entries reads zeros.
Oops, didn't get what crunch meant. Starting the work.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Ext2: reading directory entries reads zeros.
On my host OS output is exactly same, so problem isn't in ATA driver but in my code. Also I want to ask: is that
filename means something? I don't know why, but this "magneted" my attention to it.
Code: Select all
Filename: '
$��'
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Ext2: reading directory entries reads zeros.
catnikita255 wrote:catnikita255 wrote:catnikita255 wrote:Anybody?
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
-
- Member
- Posts: 5587
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Ext2: reading directory entries reads zeros.
You aren't getting any replies because (as far as we can tell) you haven't tried to debug your code.
Since you're testing your ext2 driver on disk images under a fully-functional OS, you can easily do some printf() debugging. Print out intermediate values, compare them against what you should see according to the ext2 specifications, and find where your code stops matching your expectations.
Since you're testing your ext2 driver on disk images under a fully-functional OS, you can easily do some printf() debugging. Print out intermediate values, compare them against what you should see according to the ext2 specifications, and find where your code stops matching your expectations.
- crunch
- Member
- Posts: 81
- Joined: Wed Aug 31, 2016 9:53 pm
- Libera.chat IRC: crunch
- Location: San Diego, CA
Re: Ext2: reading directory entries reads zeros.
Yep. Quite frankly, I don't have the time to work on my own projects as much as I'd like, let alone read through and debug hundreds of lines of someone else's code. There are lots of great resources for ext2 out there, and I have provided links to my own code as well.Octocontrabass wrote:You aren't getting any replies because (as far as we can tell) you haven't tried to debug your code.
Since you're testing your ext2 driver on disk images under a fully-functional OS, you can easily do some printf() debugging. Print out intermediate values, compare them against what you should see according to the ext2 specifications, and find where your code stops matching your expectations.
Some of my open-source projects:
Ext2/ELF32 bootloader
Lightweight x86 assembler, designed to be portable for osdev
Scheme in under 1000 lines of C
Ext2/ELF32 bootloader
Lightweight x86 assembler, designed to be portable for osdev
Scheme in under 1000 lines of C
Re: Ext2: reading directory entries reads zeros.
I have also strange extra characters at the end of each "file_name". can"t figure out what can it be.
on the second screenshot it is better visible
It must be:
on the second screenshot it is better visible
It must be:
Code: Select all
/.
/ ..
/.Trash-1000
/bin
/.Trash-0
/usr
/src
/boot
/os.iso
/root_dir_12
/root_dir_11
/root_dir_13
/lib
/var
/etc
/dev
/tmp
/run
/root_dir_15
/root_dir_14