OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 3:52 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Boot from SATA Hard, cannot boot from SATA CD Rom
PostPosted: Thu Jun 12, 2014 1:16 am 
Offline
Member
Member

Joined: Sun Jun 16, 2013 4:09 am
Posts: 333
Hi all.

My bootloader is followed by my Secondary bootloaded, which is followed by the Kernel.
I have no record structure, eg files to load, I know the exact locations of the three files.

My issue is loading from SATA CR Rom.
The bootloader loads fine.
The secondary bootloader loads fine.
But..
When kernel is loading the SATA readsectors code does not work, this was copied from somewhere.
If I change to a SATA Hard Disk it works fine, I have a utility which changes the boot sector location.
So I am assuming that I have missed setting it up correctly.

The code below works like this.

* Param eax is passed to BootableDevice.SATA, which is the PCI address of the SATA device
* Checks for Implemented port
* Configures port
* Reads

Where is loops is the *********************************** Here ********************
comment.

If someone could put another pair of eyes on the code and show me what I have missed it would be appreciated.

Regards, Alistair

Code:
msgPossibleBootDeviceSATA DB "Possible Boot Device - SATA", 0

msgPossibleBootDeviceSATA.BaseAddress      DB "Base Address - BAR5", 0
msgPossibleBootDeviceSATA.KernelBootSector   DB "Kernel Boot Sector", 0
msgPossibleBootDeviceSATA.KernelSectorSize   DB "Kernel Sector Size", 0
msgPossibleBootDeviceSATA.Port            DB "Port", 0
msgPossibleBootDeviceSATA.Destination      DB "Destination", 0

ahci_port dq 0
ahci_base dq 0

ahci_cmdlist   equ 0x10000
ahci_cmdtable   equ 0x11000

; Param: eax = PCI address with enabled bit 31 set; Returns: If carry set then not bootable
ProcX BootableDevice.SATA

   push   rax
   push   rsi
   rol      rax, 32
   Mov2   rsi, msgPossibleBootDeviceSATA
   Mov2   r15, rax
   call   MessageHEX64
   pop      rsi
   pop      rax

   Mov2   rbx, 0
   Mov2   r14, 0      ; ahci_port
   Mov2   r15, 0      ; BAR5
   Mov2   ebx, eax   ; PCI Address
   
   Mov2   rcx, 0

   lea      rax, [rbx + (9 << 2)] ; BAR5
   Mov2   dx, 0x0CF8
   out      dx, eax
   Mov2   dx, 0x0CFC
   in      eax, dx

   Mov2   r15, rax
   Mov2   [ahci_base], rax

   ; Search the implemented ports for a drive
   mov      ecx, [r15 + 0x0C]      ; PI – Ports Implemented
   mov      r10, 0x128            ; Offset to Port 0 Serial ATA Status
   jmp      .FirstPort

.PortNotImplemented:
   inc      r14
   shr      ecx, 1
   add      r10, 0x80            ; Each port has a 128 byte memory space

.FirstPort:
   jecxz   .NoBootableDevice
   
   bt      ecx, 0               ; Valid port?
   jnc      .PortNotImplemented
   
   mov      eax, [r15 + r10]
   cmp      eax, 0
   je      .PortNotImplemented
   
.FoundImplementedPort:
   mov      [ahci_port], r14
   call   BootableDevice.SATA.ImplementedPort
   jc      .PortNotImplemented
   ret

.NoBootableDevice:
   stc      ; Not bootable device
   ret

EndProc

ProcX BootableDevice.SATA.ImplementedPort

   ; Configure Port
   push   rax
   push   rbx
   push   rcx
   push   r14
   push   r15
   push   rdi

   Mov2   rdi, [ahci_base]
   Add2   rdi, 0x100
   shl      r14, 7
   Add2   rdi, r14
   Mov2   rax, ahci_cmdlist
   Mov2   rbx, 0
   Mov2   rcx, ahci_cmdlist + 0x1000
   Mov2   [rdi + 0x00], eax
   Mov2   [rdi + 0x04], ebx
   Mov2   [rdi + 0x08], ecx
   Mov2   [rdi + 0x0C], ebx
   Mov2   [rdi + 0x10], ebx
   Mov2   [rdi + 0x14], ebx

   ; Load sectors

   mov      rax, [BootSector]
   Add2   rax, 1
   Add2   rax, [SecondBootLoaderSectors]

   Mov2   rcx, [KernelSectors]      ; Number of Sectors to read
   Mov2   rdx, [ahci_port]         ; Port
   Mov2   rdi, KernelStartAddress      ; Destination

   Mov2   rsi, msgPossibleBootDeviceSATA.Port
   Mov2   r15, rdx
   call   MessageHEX64

   push   rax
   push   rsi
   push   r15
   Mov2   rsi, msgPossibleBootDeviceSATA.BaseAddress
   Mov2   r15, [ahci_base]
   call   MessageHEX64

   Mov2   rsi, msgPossibleBootDeviceSATA.KernelBootSector
   Mov2   r15, rax
   call   MessageHEX64

   Mov2   rsi, msgPossibleBootDeviceSATA.KernelSectorSize
   Mov2   r15, rcx
   call   MessageHEX64

   Mov2   rsi, msgPossibleBootDeviceSATA.Destination
   Mov2   r15, rdi
   call   MessageHEX64
   pop      r15
   pop      rsi
   pop      rax

   call   BootableDevice.SATA.ReadSectors
   jnc      .BootableDevice
   
.NotBootableDevice:
   stc      ; Not bootable device

.BootableDevice:
   pop      rdi
   pop      r15
   pop      r14
   pop      rcx
   pop      rbx
   pop      rax

   ret

EndProc

; -----------------------------------------------------------------------------
; readsectors -- Read data from a SATA hard drive
; IN:   RAX = starting sector # to read
;   RCX = number of sectors to read (up to 8192 = 4MiB)
;   RDX = disk #
;   RDI = memory location to store sectors
; OUT:   RAX = RAX + number of sectors that were read
;   RCX = number of sectors that were read (0 on error)
;   RDI = RDI + (number of sectors read * 512)
;   Carry set on Error
;   All other registers preserved
ProcX BootableDevice.SATA.ReadSectors
   push rbx
   push rdi
   push rsi
   push rcx
   push rax

   push rcx         ; Save the sector count
   push rdi         ; Save the destination memory address
   push rax         ; Save the block number
   push rax

   shl rdx, 7         ; Quick multiply by 0x80
   add rdx, 0x100         ; Offset to port 0

   mov rsi, [ahci_base]

   ; Command list setup
   mov rdi, ahci_cmdlist      ; command list (1K with 32 entries, 32 bytes each)
   xor eax, eax
   mov eax, 0x00010005      ; 1 PRDTL Entry, Command FIS Length = 20 bytes
   stosd            ; DW 0 - Description Information
   xor eax, eax
   stosd            ; DW 1 - Command Status
   mov eax, ahci_cmdtable
   stosd            ; DW 2 - Command Table Base Address
   xor eax, eax
   stosd            ; DW 3 - Command Table Base Address Upper
   stosd
   stosd
   stosd
   stosd
   ; DW 4 - 7 are reserved

   ; Command FIS setup
   mov rdi, ahci_cmdtable      ; Build a command table for Port 0
   mov eax, 0x00258027      ; 25 READ DMA EXT, bit 15 set, fis 27 H2D
   stosd            ; feature 7:0, command, c, fis
   pop rax            ; Restore the start sector number
   shl rax, 36
   shr rax, 36         ; Upper 36 bits cleared
   bts rax, 30         ; bit 30 set for LBA
   stosd            ; device, lba 23:16, lba 15:8, lba 7:0
   pop rax            ; Restore the start sector number
   shr rax, 24
   stosd            ; feature 15:8, lba 47:40, lba 39:32, lba 31:24
   mov rax, rcx         ; Read the number of sectors given in rcx
   stosd            ; control, ICC, count 15:8, count 7:0
   mov rax, 0x00000000
   stosd            ; reserved

   ; PRDT setup
   mov rdi, ahci_cmdtable + 0x80
   pop rax            ; Restore the destination memory address
   stosd            ; Data Base Address
   shr rax, 32
   stosd            ; Data Base Address Upper
   stosd            ; Reserved
   pop rax            ; Restore the sector count
   shl rax, 9         ; multiply by 512 for bytes
   sub rax, 1         ; subtract 1 (4.2.3.3, DBC is number of bytes - 1)
   stosd            ; Description Information

   add rsi, rdx

   mov rdi, rsi
   add rdi, 0x10         ; Port x Interrupt Status
   xor eax, eax
   stosd

   mov rdi, rsi
   add rdi, 0x18         ; Offset to port 0
   mov eax, [rdi]
   bts eax, 4         ; FRE
   bts eax, 0         ; ST
   stosd

   mov rdi, rsi
   add rdi, 0x38         ; Command Issue
   mov eax, 0x00000001      ; Execute Command Slot 0
   stosd

   mov   rdi, 0x1FFFF      ; ***********************************************************  Here **************************8

.poll:
   dec   rdi
   jz .PortLocked

   mov eax, [rsi+0x38]
   cmp eax, 0
   jne .poll

   mov rdi, rsi
   add rdi, 0x18         ; Offset to port 0
   mov eax, [rdi]
   btc eax, 4         ; FRE
   btc eax, 0         ; ST
   stosd

   pop rax            ; rax = start
   pop rcx            ; rcx = number of sectors read
   add rax, rcx         ; rax = start + number of sectors read
   pop rsi
   pop rdi
   mov rbx, rcx         ; rdi = dest addr + number of bytes read
   shl rbx, 9
   add rdi, rbx
   pop rbx
   
   clc

   ret

.PortLocked:
   pop   rax
   pop   rcx
   pop   rsi
   pop   rdi
   pop rbx
   
   stc

   ret
EndProc


Top
 Profile  
 
 Post subject: Re: Boot from SATA Hard, cannot boot from SATA CD Rom
PostPosted: Thu Jun 12, 2014 6:39 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
Are you assuming a sector size of 512 bytes?


Top
 Profile  
 
 Post subject: Re: Boot from SATA Hard, cannot boot from SATA CD Rom
PostPosted: Thu Jun 12, 2014 1:53 pm 
Offline
Member
Member

Joined: Sun Jun 16, 2013 4:09 am
Posts: 333
No, CD is 2048, I just want it to read anything.

If you are refering to the shl by 9 then I also tried shl by 11 in case this was the issue.
But it still spins.

Regards, Alistair


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: FrankRay78 and 190 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