分类: LINUX
2013-10-16 03:36:58
[bits 16] [org 0x7c00] ;Skysmiler 2008-5-13 UESTC ;为了提供灵活的加载方式,采用间接读取FAT32参数,大小一个扇区 ;文件由BIOS加载至0x7C00处执行, ;从C盘的FAT32中读取BSLDR将其加载到0x7e00处,跳转执行... ; this will find the BSLDR in only one cluster dir struct ; then load it to 0x7e00 untill the end of the file , so thie file shoule not be too large ; only support FAT32 jmp start times 0x03-($-$) db 0 ;bpb & FAT32 or FAT16 struct data :first offset-> 0x03H times 0x60-($-$) db 0 ;end here m_bsldrmiss db 'BSLDR missing.' db 13,10,0 bsldr db 'BSLDR ' BOOTSEG EQU 0X0000 BOOTOFF EQU 0X7C00 TMPSEG EQU 0X1000 ;AVALID FROM 0X00500->0X07BFF SUB THE [BP-4]*0X200 :ABOUT 29K ;THE BSLDR WILL LOAD TO FROM 0X7E00 UNTILL 0X9FFFF :ABOUT 608K ;SO THE BSLDR SHOULD NEVER EXCEED THE 608K ! TMPOFF EQU 0X0000 BOOTDRIVER EQU 0X80 ; FIRST HARD DISK NO.1 LBA; ;硬盘LBA结构 SIZE DB 16 RESERVED DB 0 COUNT DW 0X0001 BUFFER DD TMPSEG SECTORNUML DD 0 SECTORNUMH DD 0 ;显示字符串__________________ PRINT: ;THIS DEAL ax SPECIALLY ! P_START: LODSB OR AL,AL JZ RETURN CALL DIS_CHAR JMP P_START RETURN: RET ;显示一个字符 DIS_CHAR: MOV AH,0EH INT 10H RET LOAD: LOAD_START: MOV [SECTORNUML],eax MOV [BUFFER],Ecx MOV AH,42H MOV DL,80H MOV SI,LBA INT 13H JC LOAD_START RET ;++++++++++++++++++++++++++++++ start: mov ax,BOOTSEG mov ds,ax mov es,ax mov ss,ax mov bp,0x7c00;bootseg ;bp and sp both 0x0 that is interesting this will roll back mov sp,0x7c00 ;----------------------------------------load bootsector of c: mov dword [SECTORNUML],63 ;自己的位置 mov ah,42h ; mov dl,80h mov si,LBA int 13h xor eax,eax ;should be here! mov ax,[TMPSEG+510] cmp ax,0xaa55 jz find_bts ;mov si,m_not_find_bootsector ;call print jmp $ ;can't get the boot sector,system will now die ! find_bts: ;if fat32 ;not fat32 file-system system now halt ! find_fat32: ;get the fdt mov ax,[TMPSEG+0x0b] ;bp-2 每扇区字节数 2字节 push ax mov al,byte [TMPSEG+0x0d] ;bp-2-2 每簇扇区数 1 xor ah,ah push ax mov ax,[TMPSEG+0x0e] ; add ax,63 push eax ;bp-2-2-4 FAT表开始扇区 4 mov ecx,eax mov eax,[TMPSEG+0x24]; shl eax,1 add eax,ecx push eax ;bp-2-2-4-4 FAT数据开始扇区 4 mov eax,[TMPSEG+0x2c] ;根目录簇号 search_rootdir: push eax call GET_SECT_FROM_CLUST ;search for bsldr in fat32 mov dword[SECTORNUML],eax;读一个簇 xor eax,eax mov al,[bp-4] mov [COUNT],ax mov dword[BUFFER],TMPSEG+512 mov ah,42h ; mov dl,80h mov si,LBA int 13h mov ax,TMPSEG+512 mov dl,[bp-4] shl dx,9 ;*512 add dx,ax ;*512+0x9000+512 upper limit find_bsldr: ;在本簇中搜索 mov si,bsldr mov di,ax;0x9000+512+0x80; mov cx,11 repe cmpsb jz get_bsldr add ax,0x20 cmp ax,dx jbe find_bsldr ;准备在下一簇中搜索 pop eax call GET_NEXT_CLUST cmp eax ,0xffffffff; jnz search_rootdir;历遍完所有的根目录! mov si,m_bsldrmiss call PRINT jmp $ ;can't find the bsldr get_bsldr: ;ax contain the address of dir struct in memory mov bx,ax ;加载目录的数据 mov ax,[bx+0x14] push ax ; mov ax,[bx+0x1a] push ax ; pop eax ; xor ebx,ebx mov bx,[bp-4] mov [COUNT],bx mov ecx,0x7e00 load_bsldr: push ecx push eax call GET_SECT_FROM_CLUST call LOAD pop eax ; call GET_NEXT_CLUST; pop ecx ;get_next_clust破坏了ecx cmp eax,0x0fffffff jz load_ok xor edx,edx mov dx,[bp-4] shl edx,9 add ecx,edx jmp load_bsldr load_ok: ;here we go hoho jmp 0:0x7e00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;子例程 GET_NEXT_CLUST: ;计算下一个簇号 push ecx shl eax,2 xor edx,edx xor ebx,ebx mov bx,[bp-2];512;;;;! fix number div ebx push edx add eax,[bp-8] ;eax=eax*4/512+[bp-8] ; edx(ebx)=eax*4%512 mov ecx,TMPSEG call LOAD pop ebx ;ebx=edx=簇号偏移 mov eax,[TMPSEG+bx] pop ecx ret ; ;give me the clustnum in eax ,i'll offer the datasec_begin back in eax GET_SECT_FROM_CLUST: ;计算簇号对应的数据扇区 sub eax,2 xor ebx,ebx mov bl,[bp-4] mul ebx add eax,[bp-12] ;first cluster in data: eax=(eax-2)*[bp-4]+[bp-12] ret times 510-($-$) db 0 dw 0xaa55