flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > switching to PMode |
Author |
|
revolution 26 Jan 2012, 18:48
Your ORG is 0x0000 but your code is loaded at 0x00007C00. Either set your jump to PMode to point to 0x00007C00+PMode, or set your GDT table for a base of 0x00007C00.
Edit: Another option is to ORG at 0x7c00 and run everything from a 0x0000 base. |
|||
26 Jan 2012, 18:48 |
|
cod3b453 26 Jan 2012, 20:21
I'm going to guess you're booting from a hdd or floppy, where the boot sector size is 512 bytes. Your PMode code is outside this area and so needs to be loaded from the disk first (the code is not actually there at run time). Right after the PMode switch you'll want to set up ds,es,ss to be valid GDT data selectors (which looks to be 0x10).
|
|||
26 Jan 2012, 20:21 |
|
emc 26 Jan 2012, 20:59
Quote: Edit: Another option is to ORG at 0x7c00 and run everything from a 0x0000 base. Quote: Your PMode code is outside this area and so needs to be loaded from the disk first Ok, I've added the org directive correctly and I have inserted my MPode in the first 512 bytes. It's work, now. So I have to switch to PMode after be loaded outside of the first 512 bytes because I have to use the int $13 to load anything from the disk (and pmode don't allow BIOS int). aright? stage 1: jump outside stage 2: switching to pmode stage 3: loading a kernel Is it a good idea? Thanks you _________________ ;; emc |
|||
26 Jan 2012, 20:59 |
|
edfed 26 Jan 2012, 21:37
step 1: jump outside
step 2: loading a kernel step 3: switching to pmode |
|||
26 Jan 2012, 21:37 |
|
cod3b453 26 Jan 2012, 21:47
There's a number of ways you can do this.
e.g. In my project, the HDD version has a "stub" (stage 0) boot sector that uses the BIOS to load the first stage and the CD ISO version boots directly from the first stage*; both use PIO ATA drivers to load the second stage and execute it. The second stage, still in RMode, enables and checks A20, enumerates the BIOS memory map, enumerates and enables VESA (if available)** and switches to PMode. Again, this has a 32bit PIO ATA driver which is almost the same as the 16bit one, which it uses to scan for its file system and load the core and its drivers before switching to it. *This difference is because I can't fit my first stage code into a 512 byte HDD sector (is it possible, I just didn't want two versions of the code) but can for the 2048 byte CD sector. **These are all the things you might want to do in RMode that can't be done in PMode. ---- In my case "stages 2 & 3" are the same since switching to PMode is relatively basic compared to all the other initialisation. BUT there are other projects I've seen that switch immediately to PMode, load their kernels and execute it in their boot sectors. The point here is it can vary where you choose to divide the different operations AND what you want to do. There is an issue of functionality vs size during the boot process that affects these decisions. |
|||
26 Jan 2012, 21:47 |
|
edfed 27 Jan 2012, 12:20
what is sure is that 512 bytes is not enough to (be partition root) AND (load&launch kernel from file system) AND (switch pm). it can do only one of them at a time.
better would be to load and launch kernel from file system in a second stage, because the first one of only 512 bytes will just be the partition table. second stage will load kernel and launch it and then, kernel is in the mode you want, you can launch applications now! applications can be any privilege level, it depends on the kernel to determine this iopl at loading. etc... hem, maybe it is possible in fact, it depends on how is made the file system. |
|||
27 Jan 2012, 12:20 |
|
emc 27 Jan 2012, 16:49
I am trying to read a 2nd sector of the floppy to get enough memory to switch to PMode as you have suggested.
Here is my code, the carry flag which denote an error is always up after trying to read a 2nd sector: Code: ; ; yet another try ; SIZE = 1 ; number of sectors to load (512 bytes is enough) ;------------------------ STAGE 1 ------------------------; org $7c00 mov [bootdrv], dl ; save the drive number (normally 0, floppy drive A) mov si, str0 call putstr ; print out the welcome msg mov si, str1 call putstr ; print out "step 1...." xor ax, ax ; reset disk drive int $13 ; dl is already set mov ah, 2 ; read sectors from drive mov al, SIZE ; how many sectors? mov ch, 0 ; read the first track mov cl, 2 ; read the 2nd sector mov dh, 0 ; head 0 mov dl, [bootdrv] ; load on the current drive int $13 ; if error occured then CF = 1 jc @f jmp stage2 ;; fail @@: mov si, fuck call putstr jmp $ ;-- functions -- putstr: lodsb ; al = [ds:si] or al, al ; al == 0 ? jz @f mov ah, $e ; print char int $10 jmp putstr @@: ret ;-- data -- str0: db "- bootloader -", 10, 13, 0 str1: db "> step 1: jumping outside the bootsector...", 0 str2: db "> step 2", 0 done: db "done", 10, 13, 0 fuck: db 10, 13, "failed to read the sector. FUCK! :@", 0 bootdrv: db 0 times 510-($-$$) db $00 dw $aa55 ;------------------------ STAGE 2 ------------------------; stage2: mov si, done call putstr ; print "done" I think there are bad parameters to the 2nd function of the int $13 which makes this failure. I tried to modify some values (track number, sector number) but the carry flag is still up indicating an error. |
|||
27 Jan 2012, 16:49 |
|
Mac2004 27 Jan 2012, 19:53
emc: Where's your destination buffer es:bx setup?
Your are trying to load the second sector to linear address 0x7e00. es:bx needs to be setup according to your destination. http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D02h:_Read_Sectors_From_Drive Regards Mac2004 |
|||
27 Jan 2012, 19:53 |
|
emc 28 Jan 2012, 08:54
My destination buffer must be $7c00+512 (absolute address) and it's $07e00, so BX has to contain $7e00 and ES has to contain $000 and we have [$0000:$7e00].
Code: 0000 + 7e00 ($7e00 = $7c00+512) --------- = 07e00 I tried that but the problem still occurs |
|||
28 Jan 2012, 08:54 |
|
cod3b453 28 Jan 2012, 16:39
This is ripped out of some old code from my previous loader:
Code: use16 org 0x7C00 cli jmp 0x0000:@f @@: xor ax,ax mov ds,ax mov es,ax mov ss,ax mov sp,0x7C00 mov byte [disk.id],dl sti mov ax,1 ; LBA mov bx,stage2 ; Dst mov si,1 ; Size call disk.read ;jc .error jmp stage2 ; in ; ax = LBA ; si = Count ; es:bx = Dst ; ; out ; CF disk.read: push ax dx si .next: or si,si jz .done call disk.readlba jc .done mov dx,es add bx,0x0200 jnc @f add dx,0x1000 @@: mov es,dx inc ax dec si jmp .next .done: pop si dx ax ret ; in ; ax = LBA ; es:bx = Dst ; si = Count ; ; out ; CF disk.readlba: push ax cx dx di mov di,0x0005 call disk.lba_chs @@: stc dec di jz .done call disk.reset jc .done mov ax,0x0201 int 0x13 jc @b .done: pop di dx cx ax ret ;in ; ;out ; CF disk.reset: push ax di mov di,0x0005 ; Attempts @@: stc dec di jz .done xor ah,ah int 0x13 jc @b .done: pop di ax ret ; in ; ax = LBA ; ; out ; ch = C ; cl = S ; dh = H ; dl = Drive ID disk.lba_chs: xor dx,dx div word [disk.s_c] inc dx push dx xor dx,dx div word [disk.h_c] pop cx mov ch,al mov dh,dl mov dl,byte [disk.id] ret disk.s_c dw 18 disk.h_c dw 2 disk.id db 0 times (0x0200 - ($ - 0x7C00) - 2) db 0 dw 0xAA55 stage2: mov ax,0x0003 int 0x10 cli hlt times (0x0200 - ($ and 0x01FF)) db 0 |
|||
28 Jan 2012, 16:39 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.