OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 7:48 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: [Solved]Unable to obtain disk identify info on qemu
PostPosted: Thu Dec 23, 2021 5:24 pm 
Offline

Joined: Fri Nov 12, 2021 1:09 am
Posts: 12
First, I use
Code:
qemu-img create -f qcow2 80m.img 80m
to create a 80m img file as hard disk. Then I use
Code:
-hdb 80m.img
to plug in the disk and start the qemu.

And here is my full command to start qemu:
Code:
qemu-system-x86_64 -cpu Nehalem,+x2apic -m 512 -enable-kvm -s -S -fda a.img -hdb 80m.img


I want to get the identify information of my disk, and here is my code to do that:

Code:
//send command to the primary disk of slave controller to get identify info
   io_out8(PORT_DISK1_ALT_STA_CTL,0);   
   io_out8(PORT_DISK1_ERR_FEATURE,0);
   io_out8(PORT_DISK1_SECTOR_CNT,0);
   io_out8(PORT_DISK1_SECTOR_LOW,0);
   io_out8(PORT_DISK1_SECTOR_MID,0);
   io_out8(PORT_DISK1_SECTOR_HIGH,0);
   io_out8(PORT_DISK1_DEVICE,0xe0);
   io_out8(PORT_DISK1_STATUS_CMD,0xec);

Definition of all macros used above
Code:
#define PORT_DISK1_DATA      0x170
#define PORT_DISK1_ERR_FEATURE   0x171
#define PORT_DISK1_SECTOR_CNT   0x172
#define PORT_DISK1_SECTOR_LOW   0x173
#define PORT_DISK1_SECTOR_MID   0x174
#define PORT_DISK1_SECTOR_HIGH   0x175
#define PORT_DISK1_DEVICE      0x176
#define PORT_DISK1_STATUS_CMD   0x177

#define PORT_DISK1_ALT_STA_CTL   0x376

But the data I've got from the port is nothing but 0. Here is the code I've used to get return data from port:
Code:
   struct Disk_Identify_Info a;
   unsigned short *p = NULL;
   port_insw(PORT_DISK1_DATA,&a,256);
   p = (unsigned short *)&a;
   for(int i = 0;i<256;i++){
      printk(ORANGE,WHITE,"%x ",*(p+i));
   }

Here is the definition of port_insw:
Code:
#define port_insw(port,buffer,nr)   \
__asm__ __volatile__("rep;insw;mfence;"::"d"(port),"D"(buffer),"c"(nr):"memory")

Structure "Disk_Identify_Info" is nothing but a 256 bits struct to store disk identify info. It is kind of long so I cannot post it on this quote.
(Definition of Disk_Identify_Info: https://github.com/bigjr-mkkong/OStest/blob/main/disk.h)

However, I want to know how can I fix this problem or it is normal to get a full 0 identify info in qemu.


Last edited by michael on Fri Dec 24, 2021 2:39 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Unable to obtain disk identify info on qemu
PostPosted: Thu Dec 23, 2021 9:08 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
michael wrote:
hdb

You're attaching your image as the second hard drive, but you're trying to identify the first hard drive.

You're not checking if the drive is ready before you begin accessing it. This is unlikely to be a problem in QEMU, but it can cause trouble on bare metal.

michael wrote:
Code:
   io_out8(PORT_DISK1_ALT_STA_CTL,0);

Modern drives don't care, but ancient drives might misbehave if you don't set bit 3 in the drive control register.

michael wrote:
Code:
   io_out8(PORT_DISK1_DEVICE,0xe0);

Each drive has its own command block registers. If writing to the drive/head register changes which drive is selected, you need to write it before you write the other command block registers. IDENTIFY DEVICE doesn't use any of the command block registers aside from the command register, so this isn't the reason why it's not working right now, but it will cause problems for other commands.

michael wrote:
Code:
#define port_insw(port,buffer,nr)   \
__asm__ __volatile__("rep;insw;mfence;"::"d"(port),"D"(buffer),"c"(nr):"memory")

Be aware that if REP INSW causes certain corrected exceptions (e.g. demand paging) it will silently discard data. You're clobbering RCX and RDI because you didn't specify them as output operands. You don't need the MFENCE instruction. If you provide the destination buffer as an output operand, you don't need a "memory" clobber.

If you fix all of the above issues, you should end up with something like this:

Code:
void rep_insw( uint16_t port, void * dest, size_t count )
{
    asm volatile( "rep insw" : "+D"(dest), "+c"(count), "=m"(*(char (*)[count*2])dest) : "d"(port) );
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 68 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group